当前位置: 首页 > news >正文

Android Glide预处理preload原始图片到成品resource 预加载RecyclerViewPreloader,Kotlin

Android Glide预处理preload原始图片到成品resource & 预加载RecyclerViewPreloader,Kotlin

 

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

 

 

    implementation 'com.github.bumptech.glide:glide:4.15.1'kapt 'com.github.bumptech.glide:compiler:4.15.1'implementation ("com.github.bumptech.glide:recyclerview-integration:4.15.1") {// Excludes the support library because it's already included by Glide.transitive = false}

 

 

import android.content.Context
import android.util.Log
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.load.engine.bitmap_recycle.LruBitmapPool
import com.bumptech.glide.load.engine.cache.LruResourceCache
import com.bumptech.glide.module.AppGlideModule@GlideModule
class MyModule : AppGlideModule() {companion object {val mLruResourceCache = LruResourceCache(1024 * 1024 * 9999)val mLruBitmapPool = LruBitmapPool(1024 * 1024 * 9999)fun debug(msg: String) {Log.d(TAG,"$msg")}}override fun applyOptions(context: Context, builder: GlideBuilder) {builder.setMemoryCache(mLruResourceCache)builder.setBitmapPool(mLruBitmapPool)builder.setLogLevel(Log.DEBUG)Log.d(TAG, "自定义配置")super.applyOptions(context, builder)}override fun isManifestParsingEnabled(): Boolean {return false}
}

 

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" /></RelativeLayout>
import android.content.Context
import android.graphics.Bitmap
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.ListPreloader
import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.util.FixedPreloadSizeProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContextconst val PHOTO_SIZE = 80
const val TAG = "MyGlide"
const val preloadSize = 100class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)rvPreload()}private fun rvPreload() {val spanCount = 13var recyclerView: RecyclerView = findViewById(R.id.recycler_view)recyclerView?.layoutManager = GridLayoutManager(this, spanCount).apply {orientation = GridLayoutManager.VERTICAL}val adapter = MyAdapter(this)recyclerView?.adapter = adapterval heightCount = resources.displayMetrics.heightPixels / PHOTO_SIZEval max = 10 * heightCount * spanCount//如果没有句已加载且展示的格子再滑回去会出现残缺白块行。recyclerView.recycledViewPool.setMaxRecycledViews(0, max)CoroutineScope(Dispatchers.IO).launch {val items = readAllImage(applicationContext)//以len为长度值,将原始的列表切分为 [0-(len-1)],[len-列表结尾]两条。//第一条较短,快速完成原始图片预处理,紧急为用户快速展示图片(此时Glide将从resource直接装入内存)//第二条很长,适合在app冷启动后,后台静默加载。val len = 600val segment1 = items.subList(0, len)val segment2 = items.subList(len, items.size - 1)Log.d(TAG, "预处理 $len ...")segment1.forEachIndexed { index, myData ->glidePreload(myData)}Log.d(TAG, "预处理 $len")// 这段时间是拍脑瓜拍出来的。// Glide需要一定时间才能完成len个资源的预处理,把原始数据转换为resource成品。// 如果不等待不延迟,直接通知adapter更新数据,绝大多数情况下,Glide此时还没来得及完成预处理,没有预处理快速显示的效果。delay(10_000L)withContext(Dispatchers.Main) {Log.d(TAG, "预处理 $len done")adapter.onChange(items)}Log.d(TAG, "预处理 第二批 ...")segment2.forEachIndexed { index, myData ->glidePreload(myData)}}val preloadSizeProvider = FixedPreloadSizeProvider<MyData>(PHOTO_SIZE,PHOTO_SIZE)val preloadModelProvider = MyPreloadModelProvider(this, adapter)val preloader: RecyclerViewPreloader<MyData> = RecyclerViewPreloader(GlideApp.with(this),preloadModelProvider,preloadSizeProvider,preloadSize)recyclerView?.addOnScrollListener(preloader)}private fun glidePreload(myData: MyData) {//本身是线程化的,很快返回,不阻塞主线程。Glide将在后台线程中decode原始图片,加工成resource成品。GlideApp.with(this).asBitmap().load(myData.path).centerCrop().override(PHOTO_SIZE).diskCacheStrategy(DiskCacheStrategy.AUTOMATIC).preload(PHOTO_SIZE, PHOTO_SIZE)}class MyPreloadModelProvider(private val ctx: Context,private val adapter: MyAdapter,) : ListPreloader.PreloadModelProvider<MyData> {override fun getPreloadItems(position: Int): MutableList<MyData> {return mutableListOf(adapter.getItems()[position])}override fun getPreloadRequestBuilder(item: MyData): GlideRequest<Bitmap>? {return GlideApp.with(ctx).asBitmap().load(item.path).centerCrop().override(PHOTO_SIZE)}}class MyAdapter(private val ctx: Context) :RecyclerView.Adapter<MyViewHolder>() {private var items: MutableList<MyData>? = nullfun onChange(items: MutableList<MyData>) {this.items = itemsnotifyDataSetChanged()}fun getItems(): MutableList<MyData> {return items!!}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {val view = LayoutInflater.from(ctx).inflate(R.layout.item, parent, false)val params = view.layoutParamsparams.width = PHOTO_SIZEparams.height = PHOTO_SIZEreturn MyViewHolder(view)}override fun onBindViewHolder(holder: MyViewHolder, position: Int) {GlideApp.with(ctx).asBitmap().centerCrop().override(PHOTO_SIZE, PHOTO_SIZE).load(items?.get(position)?.path).into(holder.image)holder.text.text = "$position"}override fun getItemCount(): Int {return items?.size ?: 0}//        override fun getItemId(position: Int): Long {
//            return RecyclerView.NO_ID
//        }override fun getItemViewType(position: Int): Int {return 0}}class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {val image: AppCompatImageView = itemView.findViewById(R.id.image)val text: TextView = itemView.findViewById(R.id.text)}private fun readAllImage(context: Context): ArrayList<MyData> {val photos = ArrayList<MyData>()//读取手机图片val cursor = context.contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null,null,null,null)var index = 0while (cursor!!.moveToNext()) {//图片路径 urival path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))//图片名称//val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))//图片大小//val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))photos.add(MyData(path, index++))}cursor.close()return photos}class MyData(var path: String, val index: Int)
}

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="1px"><androidx.appcompat.widget.AppCompatImageViewandroid:id="@+id/image"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="centerCrop"android:src="@drawable/ic_launcher_background" /><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="-.-"android:textColor="@android:color/holo_red_dark"android:textSize="8dp" />
</RelativeLayout>

 

 

 

 

 

Android GlideApp FixedPreloadSizeProvider RecyclerViewPreloader,mix Java&Kotlin_zhangphil的博客-CSDN博客【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。《Android图片加载与缓存开源框架:Android Glide》Android Glide是一个开源的图片加载和缓存处理的第三方框架。https://blog.csdn.net/zhangphil/article/details/131905329Android GlideApp GlideRequest FixedPreloadSizeProvider RecyclerViewPreloader,kotlin_zhangphil的博客-CSDN博客【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。《Android图片加载与缓存开源框架:Android Glide》Android Glide是一个开源的图片加载和缓存处理的第三方框架。https://blog.csdn.net/zhangphil/article/details/131813200

 

相关文章:

Android Glide预处理preload原始图片到成品resource 预加载RecyclerViewPreloader,Kotlin

Android Glide预处理preload原始图片到成品resource & 预加载RecyclerViewPreloader&#xff0c;Kotlin <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_MED…...

亚马逊云科技全新Amazon Bedrock,助力客户构建生成式AI应用

亚马逊云科技近日在纽约峰会上宣布全面扩展其全托管基础模型服务Amazon Bedrock&#xff0c;包括新增Cohere作为基础模型供应商&#xff0c;加入Anthropic和Stability AI的最新基础模型&#xff0c;并发布变革性的新功能Amazon Bedrock Agents功能。客户无需管理任何基础设施&a…...

题解:ABC275 C-Counting Squares

题解&#xff1a;ABC275 C-Counting Squares 题目 链接&#xff1a;Atcoder。 链接&#xff1a;洛谷。 难度 算法难度&#xff1a;入门。 思维难度&#xff1a;普及。 调码难度&#xff1a;普及。 综合评价&#xff1a;简单。 算法 dfs数论。 思路 由数学方法可严谨…...

加载已训练好的目标检测YOLOv8,v5,v3,v6模型,对数据集中某张图片中的object打上方框、标出类别,并将图片保存到本地

参考的教程&#xff1a;Python - Ultralytics YOLOv8 Docs 在与ultralytics代码同一层级下新建 predict.py 里面写下面的内容。运行即可 from ultralytics import YOLO from PIL import Image import cv2# 加载计划使用的模型 model YOLO("yolov8n.pt") # load a…...

《零基础入门学习Python》第073讲:GUI的终极选择:Tkinter10

我们不难发现&#xff0c;几乎每一个应用程序都有一些相同的地方&#xff0c;比如说&#xff1a;标题栏、状态栏、边框、滚动条、工作区。还有的就是 菜单。 传统的菜单有大家熟悉的 File&#xff0c;Edit&#xff0c;Help等&#xff0c;点开之后&#xff0c;是下拉菜单&#…...

Shell脚本实现分库分表操作

目录 一&#xff0c;分库备份 二&#xff0c;分库操作 三&#xff0c;分库分表备份 四&#xff0c;备份还原 一&#xff0c;分库备份 #!/bin/bash mysql_cmd-uroot -pzly666666 bak_path/backup/db [ -d ${bak_path} ] || mkdir -p ${bak_path}mysql ${mysql_cmd} -e show…...

区块链实验室(12) - 网络拓扑对PBFT共识流量的影响

区块链实验室(10) - 实例说明PBFT的共识过程说明了1个简单又极端的网络&#xff0c;在这个网络中完成1个交易的共识&#xff0c;需要26次通信&#xff0c;见下图所示。 换1个网络&#xff0c;这个网络是强连通图&#xff0c;见下图。 在这个网络中完成1次交易&#xff0c;流量见…...

聊聊这几年的科技风口

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 数数这几年的科技风口&#xff1a;AR&#xff08;包括什么MR、VR&#xff09;、区块链(包括后来的什么web3)、元宇宙到现在的AI&#xff0c;下面逐一谈谈…...

【力扣每日一题】2023.7.30 环形链表2

题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 这道题属于是那种知道解法就很简单&#xff0c;不知道解法就很难独立想出来的那种&#xff0c;我们只需要稍微记住这类题的固定解法就可以。 所以接下来我先说解法&#xff0c;再解释为什么解法可以解出来。 那么我们都…...

Flink状态的理解

Flink是一个带状态的数据处理系统&#xff1b;系统在处理数据的过程中&#xff0c;各算子所记录的状态会随着数据的处理而不断变化&#xff1b; 1. 状态 所谓状态State&#xff0c;一般指一个具体的 Task 的状态&#xff0c;即线程处理过程中需要保存的历史数据或历史累计数据…...

6.3.tensorRT高级(1)-yolov5模型导出、编译到推理(无封装)

目录 前言1. YOLOv5导出2. YOLOv5推理3. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 高级-yolov5模…...

如何利用设备数字化平台推动精益制造?

人工智能驱动技术的不断发展&#xff0c;尤其是基于机器学习的预测分析工具的使用&#xff0c;为制造业带来了全新的效率和价值水平。一直以来&#xff0c;精益生产&#xff08;也叫精益制造&#xff09;在制造业中扮演着重要角色&#xff0c;而现在通过与工业 4.0的融合&#…...

使用Wps减小PDF文件的大小

第一步、打开左上角的文件 第二步、点击打印选项 第三步、点击打印按钮...

【深度学习】GPT-3

2020年5月&#xff0c;OpenAI在长达72页的论文《https://arxiv.org/pdf/2005.14165Language Models are Few-Shot Learners》中发布了GPT-3&#xff0c;共有1750亿参数量&#xff0c;需要700G的硬盘存储&#xff0c;(GPT-2有15亿个参数)&#xff0c;它比GPT-2有了极大的改进。根…...

在登录界面中设置登录框、多选项和按钮(HTML和CSS)

登录框&#xff08;Input框&#xff09;的样式&#xff1a; /* 设置输入框的宽度和高度 */ input[type"text"], input[type"password"] {width: 200px;height: 30px; }/* 设置输入框的边框样式、颜色和圆角 */ input[type"text"], input[type&q…...

【语音识别】- 声学,词汇和语言模型

一、说明 语音识别是指计算机通过处理人类语言的音频信号&#xff0c;将其转换为可理解的文本形式的技术。也就是说&#xff0c;它可以将人类的口语语音转换为文本&#xff0c;以便计算机能够进一步处理和理解。它是自然语言处理技术的一部分&#xff0c;被广泛应用于语音识别助…...

【考研英语语法及长难句】小结

【 考场攻略汇总 】 考点汇总 考场攻略 #1 断开长难句只看谓语动词&#xff0c;不考虑非谓语动词先找从句&#xff0c;先看主句 考场攻略 #2 抓住谓语动词&#xff0c;抓住句子最核心的表述动作或内容通过定位谓语动词&#xff0c;找到复杂多变的主语通过谓语动词的数量&…...

C# 反射

反射的概念&#xff1a;C#通过类型&#xff08;Type&#xff09;来创建对象&#xff0c;调用对象中的方法&#xff0c;属性等信息&#xff1b;B超就是利用了反射原理将超声波打在人的肚子上&#xff0c;然后通过反射波进行体内器官的成员&#xff1b; 反射提供的类&#xff1a;…...

Pytorch(二)

一、分类任务 构建分类网络模型 必须继承nn.Module且在其构造函数中需调用nn.Module的构造函数无需写反向传播函数&#xff0c;nn.Module能够利用autograd自动实现反向传播Module中的可学习参数可以通过named_parameters()返回迭代器 from torch import nn import torch.nn.f…...

Python 使用http时间同步设置系统时间源码

Python方式实现使用http时间同步设置系统时间源码&#xff0c;系统环境是ubuntu 12.04、Python2.7版本。需要使用到time、os及httplib方法。 Python使用http时间同步设置系统时间&#xff0c;源码如下&#xff1a; #-*-coding:utf8 -*- import httplib as client import time…...

2026年实用降AIGC工具:亲测AI率从90%降至4%的靠谱方案

一、前言&#xff1a;2026年毕业必过AIGC检测门槛 2026年国内高校对学术论文的AIGC疑似度审核全面收紧&#xff0c;绝大多数院校都发布了明确的AIGC检测数值要求&#xff1a;985、211院校规定本科论文AI率需低于20%&#xff0c;硕士论文AI率不得高于15%&#xff0c;普通高校也普…...

Taotoken官方折扣活动如何帮助开发者降低大模型使用门槛

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken官方折扣活动如何帮助开发者降低大模型使用门槛 对于个人开发者和学生群体而言&#xff0c;探索和应用大模型技术时&#…...

Wifite2实战指南:从零开始掌握无线网络安全审计的3大核心能力

Wifite2实战指南&#xff1a;从零开始掌握无线网络安全审计的3大核心能力 【免费下载链接】wifite2 Rewrite of the popular wireless network auditor, "wifite" 项目地址: https://gitcode.com/gh_mirrors/wi/wifite2 想象一下&#xff0c;你只需一条命令就…...

3大核心突破:用PDFPatcher重塑你的PDF工作流效率

3大核心突破&#xff1a;用PDFPatcher重塑你的PDF工作流效率 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱&#xff0c;可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档&#xff0c;探查文档结构&#xff0c;提取图片、转成图片等等 项目地址: https://gitcode…...

前端实战:CSS 实现经典对联式悬浮广告

一、效果介绍对联广告是网页中非常经典的广告布局&#xff0c;特点&#xff1a;左右两侧各一个广告栏&#xff0c;像对联一样悬挂页面上下滚动&#xff0c;广告固定不动、悬浮跟随屏幕中间是网站主体内容&#xff0c;互不遮挡、互不影响核心技术&#xff1a;CSS fixed 固定定位…...

Taotoken的模型广场如何辅助开发者进行技术选型

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken的模型广场如何辅助开发者进行技术选型 对于需要集成大模型能力的开发者而言&#xff0c;面对市场上众多的模型提供商、复…...

OfflineInsiderEnroll终极指南:5分钟快速退出Windows预览版的完整教程

OfflineInsiderEnroll终极指南&#xff1a;5分钟快速退出Windows预览版的完整教程 【免费下载链接】offlineinsiderenroll OfflineInsiderEnroll - A script to enable access to the Windows Insider Program on machines not signed in with Microsoft Account 项目地址: h…...

C++图文并茂轻松进阶面向对象

一、进阶面向对象&#xff08;上&#xff09;面向对象的意义在于将日常生活中习惯的思维方式引入程序设计中将需求中的概念直观的映射到解决方案中以模块为中心构建可复用的软件系统提高软件产品的可维护性和可扩展性类和对象是面向对象中的两个基本概念类∶指的是一类事物&…...

欢迎新Buddy:DataBuddy

大数据人自己的原生Agent来了&#xff01;腾讯云大数据智能体工作台DataBuddy正式发布。用户通过自然语言对话&#xff0c;即可完成数据接入、开发、治理、分析全链路任务&#xff0c;不用再在多个页面之间切换操作&#xff0c;一句话说清目标&#xff0c;Agent自己跑完全流程。…...

Richard Socher创业公司获6.5亿美元融资,欲让AI自动化研发引领底层范式转移

Richard Socher创业公司获巨额融资一家创业公司获得了GV&#xff08;Alphabet旗下VC&#xff09;和Greycroft共同领投的6.5亿美元早期融资&#xff0c;NVIDIA和AMD也参与本轮融资&#xff0c;它的估值达到了46.5亿美元。这家公司的创始人是Richard Socher&#xff0c;他是AI领域…...