- 浏览: 564430 次
- 来自: -
博客专栏
-
libgdx 游戏开发
浏览量:12295
文章分类
- 全部博客 (171)
- OS (1)
- JavaScript (13)
- Struts (2)
- Regular Expression (1)
- Java (14)
- HTML (4)
- XML (1)
- Non-Relational Database (2)
- Miscellaneous (7)
- Lotus Notes (8)
- Algorithm (3)
- Web Analytics (6)
- Web (8)
- Perl (3)
- PHP (3)
- C & C++ (1)
- Shell (7)
- Google (1)
- Android (31)
- iPhone (1)
- SQL (1)
- HTML5 (3)
- jQuery (6)
- CSS (6)
- PostgreSQL (1)
- Design Patterns (1)
- Excel (1)
- Magento (4)
- jMeter (3)
- SEO (1)
- libgdx (5)
- Software (4)
- App (1)
- Game (1)
- Gradle (1)
- Linux (16)
- Ubuntu (4)
- Docker (2)
- Spring (2)
- Other (3)
- Directory Server (1)
- CentOS (1)
- Python (1)
- VCS (3)
- Database (1)
- Open Source (1)
最新评论
-
ls0609:
赞一个,支持下博主。
[原创] Android ListView 在右上角添加三角形图标和文字 -
love297:
不让别人商用,自己先商用起来了。
手机游戏开发展示 -
a851206:
你的有些类是哪里来的?我想研究一下你的程序,可是有些类没有代码 ...
[原创] Google Custom Search & Yahoo Boss Search | Web Search API 使用 -
ypppk:
BitmapFactory.Options options = ...
[原创] 连载 1 - 深入讨论 Android 关于高效显示图片的问题 - 如何高效的加载大位图 -
笑遍世界:
我也遇到了,弄清了其中原因,可参考我的博客:http://sm ...
[原创] 使用 jMeter 登录 Wordpress
[原创] 连载 3 - 深入讨论 Android 关于高效显示图片的问题 - 如何对位图进行缓存
- 博客分类:
- Android
更加详细的说明,可以参阅如下官网地址:http://developer.android.com/training/building-graphics.html
快速导航
1. 如何高效的加载大位图。(如何解码大位图,避免超过每个应用允许使用的最大内存)http://yhz61010.iteye.com/blog/1848337
2. 如何在非 UI 线程处理位图。(如何使用 AsyncTask 在后台线程处理位图及处理并发问题)http://yhz61010.iteye.com/blog/1848811
3. 如何对位图进行缓存。(如何通过创建内存缓存和磁盘缓存来流畅的显示多张位图)http://yhz61010.iteye.com/blog/1849645
4. 如何管理位图内存。(如何针对不同的 Android 版本管理位图内存)http://yhz61010.iteye.com/blog/1850232
5. 如何在 UI 中显示位图。(如何通过 ViewPager 和 GridView 显示多张图片)http://yhz61010.iteye.com/blog/1852927
如何对位图进行缓存?
若只加载一张位图到 UI 中是很简单的事情,不过,如果要一次性加载多张大图片的话,事情就会变得很复杂。例如,使用 ListView, GridView 或 ViewPager 等显示多张图片,由于使用这些组件时,可以滚动屏幕,从而理论上可以加载无数张图片。
当使用上述组件显示图片时,若显示的内容随机用户滚动屏幕而不在屏幕上显示的时候,组件本身会重复利用子视图,这里内存的使用量便会降低。若没有长时间存在的引用时,垃圾回收器就会释放已经加载过的图片所占的内存。这当然是非常理想的情况。但是,程序为了让用户能快速而流畅的查看图片,并不希望当已经加载过的图片再次显示在屏幕上时,依然对这些图片再次进行处理。所以,对于再次显示已经加载过的图片,进行内存缓存或磁盘缓存就显得很有必要。
本文将引导你如何通过创建内存缓存和磁盘缓存来流畅的显示多张位图。
使用内存缓存
内存缓存提供了一种快速访问位图的方法,不过其代价是需要占用一些宝贵的应用内存。LruCache 类特别适合用于对位图进行缓存,将最近使用过的对象保存在强引用 LinkedHashMap 中,并且在缓存超过指定的大小时,清除掉最近不使用的位图。
注意:以前比较流行的内存缓存实现方法是使用 SoftReference 或 WeakReference 对位图进行缓存,但是现在已经不建议这么做了。从 Android 2.3(API Level 9)开始,垃圾回收器会更加主动的回收无效的 soft/weak references。此外,在 Android 3.0 (API Level 11)之前,返回的位图数据虽然保存在内存中,但是所占用的内存并不会按照可预知的方式将其释放掉,从而导致的潜在问题就是应用程序很容易就超过内存限制并导致程序崩溃。
为了给 LruCache 选取一个合适的大小,我们需要考虑如下一些因素:
・余下的页面或应用需要占用多少内存?
・屏幕上一次最多可以显示几张图片?需要几屏才能显示余下的图片?
・手机的屏幕大小及分辨率是多少?与 Nexus S (hdpi)相比,像 Galaxy Nexus 这样的超清屏(xhdpi)需要更大的缓存才能显示下相同数量的图片。
・位图的尺寸和配置是什么?并且需要占用多少内存?
・是否经常需要访问图片?某些图片的访问频率是否会比其它图片的访问频率高?若是的话,可能需要专门针对这些图片进行内存缓存。或者使用多个 LruCache 对象来缓存不同的位图。
・如何在质量和数量上保持平衡?例如,有时需要缓存大量低品质的图片,有时却需要在后台缓存一张高品质的图片。
并没有特定缓存的大小或公式适用于所有的应用,这完全取决于你对程序内存使用情况的分析。若缓存太小反而会导致额外的内存开销,起不到缓存的作用。若缓存太大可能会导致发生 java.lang.OutOfMemory 异常,让程序可用的内存变得很小。
下面的例子为你演示如何为位图建立缓存:
注意:在上面这个例子中,我们设置的缓存大小是应用所占内存的 1/8。对于普通分辨率或高分辨率的屏幕来说,这个缓存值大约是 4 MB (32/8)。对于 800x480 分辨率的屏幕来说,一屏幕的图片大约需要占用 1.5 MB (800*480*4 bytes) 内存。也就是说,整个缓存大约能缓存 2.5 屏的图片。
当将一张位图加载至 ImageView 时,我们首先要检查该位图是否已经被 LruCache 缓存,若已经被缓存,则可以直接更新该 ImageView,若没有被缓存,则需要在后台进行图片处理:
我们同样需要升级 BitmapWorkerTask 类,增加缓存处理的操作:
使用磁盘缓存
虽然使用内存缓存可以快速的访问最近使用过的位图,但是我们不能完全依赖于它,因为像 GridView 这样的组件,很容易就将内存缓存占满。又如,应用程序可以被其它任务中断,例如,来了一个电话,此时后台任务会被中止,内存缓存自然也就无效了。若之后用户再次回到应用中,程序还得重新处理图片。
然而磁盘缓存却可以解决这个问题,它可以持久的缓存图片。当内存缓存无效的时候,磁盘缓存可以有效的帮忙你降低图片加载时间。当然,从磁盘获取图片要比从内存获取图片要慢,所以应用在后台线程加载图片,因为磁盘读写时间是不可预知的。
注意:若频繁的访问图片,那么 ContentProvider 可能是更加合适的地方用于缓存图片。例如,在制作图像画廊这样的应用程序中。
在下面的例子中,我们使用了 DiskLruCache 实现了从磁盘缓存读取图片。下面这个例子是前面内存缓存例子的升级版,除了可以从内存缓存读取图片外,还添加了从磁盘缓存读取图片的功能:
注意:即使初始化磁盘缓存需要磁盘操作权限,但是这也不应该在主线程中进行。这就意味着程序有可能在初始化操作之前就对缓存进行访问。为了解决这个问题,我们在上面的实现中,使用了一个同步锁对象来保证直到缓存被初始化之后,才可以访问磁盘缓存。
虽然检查内存缓存是在 UI 线程中进行的,但是对磁盘缓存的检查却应该放到后台线程去做。要记住,对磁盘的操作永远不要发生在主 UI 线程中。当图片处理完成后,最终的位图应该同时被添加到内存缓存和磁盘缓存中以备后用。
处理配置变化
在程序运行的过程中,配置是会发生变化的,例如,屏幕方向的变化会导致系统销毁当前的页面并重新应用新的配置后重启原页面(关于类似行为的详细说明,请参阅如下文章:Handling Runtime Changes http://developer.android.com/guide/topics/resources/runtime-changes.html)。为了让用户有一个更快更平滑的使用体验,我们并不希望当配置发生变化时,就得重新处理所有的图片。
幸运的是,我们前面已经讲了如何使用内存缓存,使用它就可以完美的解决这个问题。当使用 Fragment 时,我们可以调用 setRetainInstance(true) 方法,将内存缓存传入新的 activity 实例中。当新的 activity 被重新创建时,被保持的 Fragment 会被重新添加到页面中,然后我们就可以重新访问缓存对象了,从而可以快速的在页面上显示图片。
下面这个例子是关于使用 Fragment,当配置发生变化时,如何保持一个 LruCache 对象:
为了验证上面这个例子,你可以改变手机的方向来查看是否使用了被保持的 Fragment。你可能注意到了,当手机方向发生变化时,图片几乎是瞬间就从内存缓存中被重新加载了。任何没有被内存缓存的图片,都可能被磁盘进行缓存,若也没有被磁盘缓存,那么图片就会从非缓存对象中被加载。
快速导航
1. 如何高效的加载大位图。(如何解码大位图,避免超过每个应用允许使用的最大内存)http://yhz61010.iteye.com/blog/1848337
2. 如何在非 UI 线程处理位图。(如何使用 AsyncTask 在后台线程处理位图及处理并发问题)http://yhz61010.iteye.com/blog/1848811
3. 如何对位图进行缓存。(如何通过创建内存缓存和磁盘缓存来流畅的显示多张位图)http://yhz61010.iteye.com/blog/1849645
4. 如何管理位图内存。(如何针对不同的 Android 版本管理位图内存)http://yhz61010.iteye.com/blog/1850232
5. 如何在 UI 中显示位图。(如何通过 ViewPager 和 GridView 显示多张图片)http://yhz61010.iteye.com/blog/1852927
如何对位图进行缓存?
若只加载一张位图到 UI 中是很简单的事情,不过,如果要一次性加载多张大图片的话,事情就会变得很复杂。例如,使用 ListView, GridView 或 ViewPager 等显示多张图片,由于使用这些组件时,可以滚动屏幕,从而理论上可以加载无数张图片。
当使用上述组件显示图片时,若显示的内容随机用户滚动屏幕而不在屏幕上显示的时候,组件本身会重复利用子视图,这里内存的使用量便会降低。若没有长时间存在的引用时,垃圾回收器就会释放已经加载过的图片所占的内存。这当然是非常理想的情况。但是,程序为了让用户能快速而流畅的查看图片,并不希望当已经加载过的图片再次显示在屏幕上时,依然对这些图片再次进行处理。所以,对于再次显示已经加载过的图片,进行内存缓存或磁盘缓存就显得很有必要。
本文将引导你如何通过创建内存缓存和磁盘缓存来流畅的显示多张位图。
使用内存缓存
内存缓存提供了一种快速访问位图的方法,不过其代价是需要占用一些宝贵的应用内存。LruCache 类特别适合用于对位图进行缓存,将最近使用过的对象保存在强引用 LinkedHashMap 中,并且在缓存超过指定的大小时,清除掉最近不使用的位图。
注意:以前比较流行的内存缓存实现方法是使用 SoftReference 或 WeakReference 对位图进行缓存,但是现在已经不建议这么做了。从 Android 2.3(API Level 9)开始,垃圾回收器会更加主动的回收无效的 soft/weak references。此外,在 Android 3.0 (API Level 11)之前,返回的位图数据虽然保存在内存中,但是所占用的内存并不会按照可预知的方式将其释放掉,从而导致的潜在问题就是应用程序很容易就超过内存限制并导致程序崩溃。
为了给 LruCache 选取一个合适的大小,我们需要考虑如下一些因素:
・余下的页面或应用需要占用多少内存?
・屏幕上一次最多可以显示几张图片?需要几屏才能显示余下的图片?
・手机的屏幕大小及分辨率是多少?与 Nexus S (hdpi)相比,像 Galaxy Nexus 这样的超清屏(xhdpi)需要更大的缓存才能显示下相同数量的图片。
・位图的尺寸和配置是什么?并且需要占用多少内存?
・是否经常需要访问图片?某些图片的访问频率是否会比其它图片的访问频率高?若是的话,可能需要专门针对这些图片进行内存缓存。或者使用多个 LruCache 对象来缓存不同的位图。
・如何在质量和数量上保持平衡?例如,有时需要缓存大量低品质的图片,有时却需要在后台缓存一张高品质的图片。
并没有特定缓存的大小或公式适用于所有的应用,这完全取决于你对程序内存使用情况的分析。若缓存太小反而会导致额外的内存开销,起不到缓存的作用。若缓存太大可能会导致发生 java.lang.OutOfMemory 异常,让程序可用的内存变得很小。
下面的例子为你演示如何为位图建立缓存:
private LruCache<String, Bitmap> mMemoryCache; @Override protected void onCreate(Bundle savedInstanceState) { ... // Get max available VM memory, exceeding this amount will throw an // OutOfMemory exception. Stored in kilobytes as LruCache takes an // int in its constructor. final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // Use 1/8th of the available memory for this memory cache. final int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { // The cache size will be measured in kilobytes rather than // number of items. return bitmap.getByteCount() / 1024; } }; ... } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemCache(key) == null) { mMemoryCache.put(key, bitmap); } } public Bitmap getBitmapFromMemCache(String key) { return mMemoryCache.get(key); }
注意:在上面这个例子中,我们设置的缓存大小是应用所占内存的 1/8。对于普通分辨率或高分辨率的屏幕来说,这个缓存值大约是 4 MB (32/8)。对于 800x480 分辨率的屏幕来说,一屏幕的图片大约需要占用 1.5 MB (800*480*4 bytes) 内存。也就是说,整个缓存大约能缓存 2.5 屏的图片。
当将一张位图加载至 ImageView 时,我们首先要检查该位图是否已经被 LruCache 缓存,若已经被缓存,则可以直接更新该 ImageView,若没有被缓存,则需要在后台进行图片处理:
public void loadBitmap(int resId, ImageView imageView) { final String imageKey = String.valueOf(resId); final Bitmap bitmap = getBitmapFromMemCache(imageKey); if (bitmap != null) { mImageView.setImageBitmap(bitmap); } else { mImageView.setImageResource(R.drawable.image_placeholder); BitmapWorkerTask task = new BitmapWorkerTask(mImageView); task.execute(resId); } }
我们同样需要升级 BitmapWorkerTask 类,增加缓存处理的操作:
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { ... // Decode image in background. @Override protected Bitmap doInBackground(Integer... params) { final Bitmap bitmap = decodeSampledBitmapFromResource( getResources(), params[0], 100, 100)); addBitmapToMemoryCache(String.valueOf(params[0]), bitmap); return bitmap; } ... }
使用磁盘缓存
虽然使用内存缓存可以快速的访问最近使用过的位图,但是我们不能完全依赖于它,因为像 GridView 这样的组件,很容易就将内存缓存占满。又如,应用程序可以被其它任务中断,例如,来了一个电话,此时后台任务会被中止,内存缓存自然也就无效了。若之后用户再次回到应用中,程序还得重新处理图片。
然而磁盘缓存却可以解决这个问题,它可以持久的缓存图片。当内存缓存无效的时候,磁盘缓存可以有效的帮忙你降低图片加载时间。当然,从磁盘获取图片要比从内存获取图片要慢,所以应用在后台线程加载图片,因为磁盘读写时间是不可预知的。
注意:若频繁的访问图片,那么 ContentProvider 可能是更加合适的地方用于缓存图片。例如,在制作图像画廊这样的应用程序中。
在下面的例子中,我们使用了 DiskLruCache 实现了从磁盘缓存读取图片。下面这个例子是前面内存缓存例子的升级版,除了可以从内存缓存读取图片外,还添加了从磁盘缓存读取图片的功能:
private DiskLruCache mDiskLruCache; private final Object mDiskCacheLock = new Object(); private boolean mDiskCacheStarting = true; private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB private static final String DISK_CACHE_SUBDIR = "thumbnails"; @Override protected void onCreate(Bundle savedInstanceState) { ... // Initialize memory cache ... // Initialize disk cache on background thread File cacheDir = getDiskCacheDir(this, DISK_CACHE_SUBDIR); new InitDiskCacheTask().execute(cacheDir); ... } class InitDiskCacheTask extends AsyncTask<File, Void, Void> { @Override protected Void doInBackground(File... params) { synchronized (mDiskCacheLock) { File cacheDir = params[0]; mDiskLruCache = DiskLruCache.open(cacheDir, DISK_CACHE_SIZE); mDiskCacheStarting = false; // Finished initialization mDiskCacheLock.notifyAll(); // Wake any waiting threads } return null; } } class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { ... // Decode image in background. @Override protected Bitmap doInBackground(Integer... params) { final String imageKey = String.valueOf(params[0]); // Check disk cache in background thread Bitmap bitmap = getBitmapFromDiskCache(imageKey); if (bitmap == null) { // Not found in disk cache // Process as normal final Bitmap bitmap = decodeSampledBitmapFromResource( getResources(), params[0], 100, 100)); } // Add final bitmap to caches addBitmapToCache(imageKey, bitmap); return bitmap; } ... } public void addBitmapToCache(String key, Bitmap bitmap) { // Add to memory cache as before if (getBitmapFromMemCache(key) == null) { mMemoryCache.put(key, bitmap); } // Also add to disk cache synchronized (mDiskCacheLock) { if (mDiskLruCache != null && mDiskLruCache.get(key) == null) { mDiskLruCache.put(key, bitmap); } } } public Bitmap getBitmapFromDiskCache(String key) { synchronized (mDiskCacheLock) { // Wait while disk cache is started from background thread while (mDiskCacheStarting) { try { mDiskCacheLock.wait(); } catch (InterruptedException e) {} } if (mDiskLruCache != null) { return mDiskLruCache.get(key); } } return null; } // Creates a unique subdirectory of the designated app cache directory. Tries to use external // but if not mounted, falls back on internal storage. public static File getDiskCacheDir(Context context, String uniqueName) { // Check if media is mounted or storage is built-in, if so, try and use external cache dir // otherwise use internal cache dir final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() : context.getCacheDir().getPath(); return new File(cachePath + File.separator + uniqueName); }
注意:即使初始化磁盘缓存需要磁盘操作权限,但是这也不应该在主线程中进行。这就意味着程序有可能在初始化操作之前就对缓存进行访问。为了解决这个问题,我们在上面的实现中,使用了一个同步锁对象来保证直到缓存被初始化之后,才可以访问磁盘缓存。
虽然检查内存缓存是在 UI 线程中进行的,但是对磁盘缓存的检查却应该放到后台线程去做。要记住,对磁盘的操作永远不要发生在主 UI 线程中。当图片处理完成后,最终的位图应该同时被添加到内存缓存和磁盘缓存中以备后用。
处理配置变化
在程序运行的过程中,配置是会发生变化的,例如,屏幕方向的变化会导致系统销毁当前的页面并重新应用新的配置后重启原页面(关于类似行为的详细说明,请参阅如下文章:Handling Runtime Changes http://developer.android.com/guide/topics/resources/runtime-changes.html)。为了让用户有一个更快更平滑的使用体验,我们并不希望当配置发生变化时,就得重新处理所有的图片。
幸运的是,我们前面已经讲了如何使用内存缓存,使用它就可以完美的解决这个问题。当使用 Fragment 时,我们可以调用 setRetainInstance(true) 方法,将内存缓存传入新的 activity 实例中。当新的 activity 被重新创建时,被保持的 Fragment 会被重新添加到页面中,然后我们就可以重新访问缓存对象了,从而可以快速的在页面上显示图片。
下面这个例子是关于使用 Fragment,当配置发生变化时,如何保持一个 LruCache 对象:
private LruCache<String, Bitmap> mMemoryCache; @Override protected void onCreate(Bundle savedInstanceState) { ... RetainFragment mRetainFragment = RetainFragment.findOrCreateRetainFragment(getFragmentManager()); mMemoryCache = RetainFragment.mRetainedCache; if (mMemoryCache == null) { mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { ... // Initialize cache here as usual } mRetainFragment.mRetainedCache = mMemoryCache; } ... } class RetainFragment extends Fragment { private static final String TAG = "RetainFragment"; public LruCache<String, Bitmap> mRetainedCache; public RetainFragment() {} public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) { RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG); if (fragment == null) { fragment = new RetainFragment(); } return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); } }
为了验证上面这个例子,你可以改变手机的方向来查看是否使用了被保持的 Fragment。你可能注意到了,当手机方向发生变化时,图片几乎是瞬间就从内存缓存中被重新加载了。任何没有被内存缓存的图片,都可能被磁盘进行缓存,若也没有被磁盘缓存,那么图片就会从非缓存对象中被加载。
发表评论
-
[转] DialogFragment Fragment already added
2017-10-25 11:16 2798原文地址:http://blog.csdn.net/u0129 ... -
Android Studio .gitignore
2017-10-16 15:44 933参考文献: https://github.com/github ... -
[转] How to detect incoming calls in an Android
2017-10-13 14:14 1257原文地址:https://stackoverflow.com/ ... -
[转] Android 检测电源按钮是否被按下
2017-10-11 12:55 1085原文地址:https://stackoverflow.com/ ... -
[原创] Android Activity onNewIntent() 详解
2017-08-16 13:46 4828阅读难度:中 阅读前提: 1. 需要了解 Android 的生 ... -
[转] Android Webview: “Uncaught TypeError: Cannot read property 'getItem' of null
2017-08-14 15:09 2391原文地址:https://stackoverflow.com/ ... -
[原创] 使用 Vitamio 播放视频作为 Splash 时出现失真情况的解决方案
2017-08-02 09:10 1239目前在做关于视频及流媒体播放项目时,有这样一个需求,应用启动时 ... -
[转] Android: Expand/collapse animation
2017-07-31 14:57 1602原文地址:https://stackoverflow.com/ ... -
[原创] Android ListView 在右上角添加三角形图标和文字
2017-07-26 17:24 2816最终显示效果如下图,在右上角添加三角形图标并在图标内显示文字: ... -
[转] Detect home button press in android
2017-07-20 17:49 1197原文地址:https://stackoverflow.com/ ... -
[原创] 开启 Android TextView Marquee
2017-07-18 15:47 1838亲测可能。直接上代码。 测试机器:XiaoMi 2S Andr ... -
[原创] 小米手机无法真机调试
2017-07-06 09:10 6518系统环境: 小米 2S MIUI 版本:8.0.1.0(LXA ... -
了解数据绑定 - Data Binding Library
2017-06-22 15:31 1004原文地址: -
How to play gif with Fresco
2017-06-22 14:00 695原文地址:https://stackoverflow.com/ ... -
设置 Toolbar(ActionBar) 上的按钮颜色
2017-06-22 08:11 2099原文地址: https://stackoverflow.com ... -
Display back button on action bar and back event
2017-06-22 08:00 774原文地址: https://stackoverflow.com ... -
Gradle 修改 Maven 仓库地址
2017-06-02 15:51 1707修改 Gradle Maven 仓库地址为阿里云镜像 修改根 ... -
[转] How to clear cookies and cache of webview on Android when not in webview?
2017-04-26 09:28 2219原文地址:http://stackoverflow.com/a ... -
[转] Android 在程序中如何动态的修改程序图标
2017-03-02 17:05 973http://stackoverflow.com/a/4150 ... -
[转] Android Libraries
2017-01-16 10:28 582原文地址: https://dzone.com/article ...
相关推荐
3. **位图渲染**:Fresco引入了**Software Layer**和**Drawee**的概念,将复杂的图片处理工作放在后台进行,使用**SurfaceView**或者**TextureView**显示,从而降低了主线程的压力。 ### 二、Fresco的配置 Fresco...
这个过程需要对Android图形系统有深入的理解,并可能需要用到原生代码来实现1位深度的支持。通过这样的转换,开发者可以实现诸如二值化、节省内存等特定需求,尤其是在低功耗设备或性能有限的环境中。
在Android开发中,照相、压缩图片以及图片缓存是三个关键的技术环节,它们对于提升应用性能和用户体验至关重要。下面将分别对这三个方面进行详细阐述。 1. Android 照相: - 活动(Activity)启动:使用Intent启动...
本教程将详细讲解如何在Android应用中实现批量下载图片并进行高效缓存,以实现非常流畅的用户体验。我们将主要关注LruCache技术,这是一种内存管理策略,有助于优化内存使用。 首先,我们需要理解Android中的图片...
本资源"Android应用源码之Android 图片缓存、加载器.zip"提供了一个实际的安卓实例,旨在帮助开发者理解和实现高效的图片处理机制。以下将详细阐述相关知识点。 1. **图片加载库的选择与原理** - Android开发中...
在Android开发中,大位图(Bitmap)的处理是一个重要的技术点,特别是在处理高分辨率图像或者需要显示大量图片的应用中。由于Android系统对内存管理的限制,直接加载大位图可能导致应用崩溃,这就是著名的"Out of ...
1. 创建一个ImageView或自定义View,将其ScaleType设置为Matrix,这样我们可以直接对Matrix进行操作来改变图片的位置。 2. 使用Matrix的setTranslate方法来移动图片。该方法接受两个参数,分别代表X轴和Y轴上的偏移...
1:队列优先级 (如果想要listview中移动的区域优先被显示,而不是从上到下显示图片,可以把新建的任务提到任务队列前端) 2:实现了:中断任务的功能(比如进入一个Activity会开启大量任务,如果退出这个Activity ...
然后,我们需要对图片进行解码和缩放。Android提供了Bitmap类来处理位图,通过 BitmapFactory 类可以将字节流解码为Bitmap对象。为了避免内存溢出,我们可以使用inJustDecodeBounds参数预览图片大小,再通过...
"Android Google官网的图片缓存源码"是一个深入理解Android图片加载与缓存机制的重要参考资料,有助于开发者提升应用的性能和用户体验。本文将详细解析这个主题中的关键知识点。 首先,我们要了解Android中图片缓存...
"Android Google官网的图片缓存源码"压缩包包含了Google官方关于图片缓存的实现代码,对于理解Android应用中的图片加载和缓存机制具有极高的参考价值。 1. **内存缓存(Memory Cache)** 内存缓存是图片缓存的第一...
在Android开发中,位图(Bitmap)是一种非常重要的图像处理对象,用于在屏幕上显示和操作图像。本示例“android中的位图操作demo”主要涵盖了Android应用开发中关于位图的基本操作,包括位图的加载、绘制以及一些...
你可以通过分析"Android Google官网的图片缓存源码"来深入了解Glide或其他图片库的实现细节,包括如何读写磁盘缓存,如何实现内存管理,以及如何处理各种网络和设备条件下的图片加载问题。这对于提升Android应用的...
在Android开发中,ImageView是用于显示图像资源的重要组件。它能够加载本地图片或者网络图片,是用户界面设计中不可或缺的一部分。本篇文章将深入探讨ImageView的工作原理、如何使用以及相关的优化技巧。 1. **...
4. **图片库和框架**:在Android中,有许多优秀的第三方库可以帮助开发者处理图片异步加载和缓存问题,如Picasso、Glide、Fresco等。这些库提供了完善的图片处理功能,包括尺寸调整、格式转换、占位符、错误图、内存...
在Android平台上,显示SD卡上的图片是一项常见的任务,尤其对于那些需要处理图像的应用来说更是必不可少。这个场景通常涉及到几个关键的技术点,包括读取SD卡上的文件、解析图片数据以及在屏幕上显示。以下是对这些...
本资源“Android高级应用源码-listview获取网络图片缓存优化.rar”提供了一种解决方案,帮助开发者提高ListView加载网络图片的效率。 1. **内存缓存**: - 内存缓存是一种提高应用性能的有效手段。通过使用HashMap...
通过研究和学习"sketch-smooth-corner-android"项目,开发者不仅可以掌握如何在Android画布上绘制平滑角,还能对Android图形系统有更深入的理解,这对于提升应用的用户体验和设计质量有着重要的意义。同时,开源的...
总结,"android-image-filter-ndk"项目为我们提供了一个实战范例,展示了如何结合Android NDK和C语言实现高效的图像处理。通过学习该项目,开发者不仅可以掌握Android NDK的使用,还能深入理解图像处理的原理和技巧...
在Android开发中,图片浏览、缓存管理和ViewPager的使用是相当关键的部分,尤其对于构建高效、流畅的用户体验至关重要。这份"Android高级应用源码-图片浏览器+缓存+viewpager.zip"显然提供了一个完整的实现,涵盖了...