在UIȝE?处理Bitmap
BitmapFactory.decode*
pd的方法,讨?的是怎么样去高效的加载大囄Q但?图片数?来源Q这些方法都不应该在UIȝE上使用。因些方法?费的旉???估的Q图片加载?费的旉依赖于很多的因素Q网l或?的?写?度,囄的大,手机CPU的?理能力等{)。在E序???其中?囄加蝲dd?了UIȝE,那么你的应用会无响应(ANRQ不能再与用戯行交互了Q,Androidpȝ会显C?知用P用户会选择关闭你的应用Q这?w怸好的用户体验?/div> Z这?原因Q你?使用
AsyncTask
来在UIȝE?的线E中处理囄加蝲Q但还有???Q?妥善处理好并发的??Q下面将介绍这两U问题的处理Ҏ使用AsyncTask
AsyncTask
cMؓ我们提供了一U很好的方式来在UIȝE之外的U程?行一些任务,q且把任务的l果返回到UIȝE上。你??l承AsyncTask cd重蝲?提供的方法来使用这?异?d方式Q下面是?CZE序 class BitmapWorkerTask extends AsyncTask { private final WeakReference imageViewReference; private int data = 0; public BitmapWorkerTask(ImageView imageView) { // Use a WeakReference to ensure the ImageView can be garbage collected imageViewReference = new WeakReference(imageView); } // Decode image in background. @Override protected Bitmap doInBackground(Integer... params) { data = params[0]; return decodeSampledBitmapFromResource(getResources(), data, 100, 100)); } // Once complete, see if ImageView is still around and set bitmap. // 此方法运行在UIȝE上 @Override protected void onPostExecute(Bitmap bitmap) { if (imageViewReference != null && bitmap != null) { final ImageView imageView = imageViewReference.get(); if (imageView != null) { imageView.setImageBitmap(bitmap); } } }}
使用弱引用去保存 ImageView 对象?ؓ了确?/span>
AsyncTask
不会d\?/span>ImageView 的用和垃圾回收器能够回?/span>ImageView 引用的?象?不能保证当任务完成的时?ImageView 引用的?象没有?回收Q所以呢你必donPostExecute() Ҏ?行?查是否ؓnull?/span>ImageView 对象?会不存在了,例?Q在?dl束前,用户?已经d了当前的用户界面QActivity被destroyQ或者一?|?Q例如横f屏切换Q发生改? Q所以在使用的时候必d?ImageView 对象做必要的?? 你可以直接创Z?/span>
AsyncTask
对象q调用execute()Ҏ来异步加载图?/span>public void loadBitmap(int resId, ImageView imageView) { BitmapWorkerTask task = new BitmapWorkerTask(imageView); task.execute(resId);}
处理q发??
?a href="http://www.android-doc.com/reference/android/widget/ListView.html" style="font-family:'courier new',courier,monospace; font-weight:bold; line-height:21px; color:rgb(37,138,175); text-decoration:initial">ListView?a href="http://www.android-doc.com/reference/android/widget/GridView.html" style="font-family:'courier new',courier,monospace; font-size:14px; font-weight:bold; line-height:21px; color:rgb(37,138,175); text-decoration:initial">GridView 这?常?的?囄Ӟl合AsyncTask ?v使用的时候会产生另????。ؓ了尽?的提高内存的使用效率Q当用户滚动lgӞ这类视图lg会@?用它的子视图Q?果每?视图都姦发一?span style="background-color:rgb(249,249,249); color:rgb(34,34,34); font-family:Roboto,sans-serif; font-size:14px; line-height:19px">
AsyncTask
Q那么将不会有保证相兌的?图是否已l回收供另??子?囑@?用了。?且,异?d的执行顺序并不意味着d的执行结束时的顺序也?L。结合这两?原因Q引发的这个q发??有可能会D囄讄雭视图上时会发生错位? 针?这?q发、错位问题,我们??a href="http://www.android-doc.com/reference/android/widget/ImageView.html" style="font-family:'courier new',courier,monospace; font-size:14px; font-weight:bold; line-height:21px; background-color:rgb(249,249,249); color:rgb(37,138,175); text-decoration:initial">ImageView 对象存储??使用?a href="http://www.android-doc.com/reference/android/os/AsyncTask.html" style="font-family:'courier new',courier,monospace; font-size:14px; font-weight:bold; line-height:21px; color:rgb(37,138,175); text-decoration:initial">AsyncTask 的引?这样我们?L?任务是否完?/div>
创徏?专用?a href="http://www.android-doc.com/reference/android/graphics/drawable/Drawable.html" style="font-family:'courier new',courier,monospace; font-size:14px; font-weight:bold; line-height:21px; color:rgb(37,138,175); text-decoration:initial">Drawable 子类来存储一?之?应的AsyncTask (这个AsyncTask 实际上是用来加蝲Drawable 的任?Q当囄加蝲d还在执?Ӟ可以用这?a href="http://www.android-doc.com/reference/android/graphics/drawable/Drawable.html" style="font-family:'courier new',courier,monospace; font-size:14px; font-weight:bold; line-height:21px; color:rgb(37,138,175); text-decoration:initial">Drawable 来显CZ张默认的囄了,当任务完成时这个Drawable随之??/div>
//存储??之?应的taskQ?在任务还在执行时充当?占位W,当任务完成时Q随之?替换static class AsyncDrawable extends BitmapDrawable { private final WeakReference bitmapWorkerTaskReference; public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { super(res, bitmap); bitmapWorkerTaskReference = new WeakReference(bitmapWorkerTask); } public BitmapWorkerTask getBitmapWorkerTask() { return bitmapWorkerTaskReference.get(); }}
在执行任务之前,先?|?位?Q?/span>ImageView 显C默认图?/span>
public void loadBitmap(int resId, ImageView imageView) { if (cancelPotentialWork(resId, imageView)) { final BitmapWorkerTask task = new BitmapWorkerTask(imageView); // mPlaceHolderBitmap 引用的就?认?昄的图片?? final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), mPlaceHolderBitmap, task); imageView.setImageDrawable(asyncDrawable); task.execute(resId); }}
cancelPotentialWork
Ҏ?来?与ImageView 相关联的另??d?正在执?Q?果是的话Q将会?过调?/span>cancel()Ҏ?/span>关闭这个 d。只有极部分的情况下两?务的囄数据会相{,如果相等的话Q那也不会出C么并发问题了Q我?不需要做M的??/span>public static boolean cancelPotentialWork(int data, ImageView imageView) { // 取得当前与ImageView相关联的d final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); // 如果存在的话Q则取消 if (bitmapWorkerTask != null) { final int bitmapData = bitmapWorkerTask.data; if (bitmapData != data) { // Cancel previous task bitmapWorkerTask.cancel(true); } else { // The same work is already in progress return false; } } // No task associated with the ImageView, or an existing task was cancelled return true;}
下面?/span>getBitmapWorkerTask() Ҏ的定?/span>
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { // imageView有可能?回收 if (imageView != null) { final Drawable drawable = imageView.getDrawable(); if (drawable instanceof AsyncDrawable) { final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; return asyncDrawable.getBitmapWorkerTask(); } } return null;}
雜?/span>
onPostExecute()
Ҏ?????d??消了Q还有需要?下当前的任务是否是与imageView相关联的d class BitmapWorkerTask extends AsyncTask { ... @Override protected void onPostExecute(Bitmap bitmap) { // if task cancelled , this method is never invoked // why check here ? if (isCancelled()) { bitmap = null; } if (imageViewReference != null && bitmap != null) { final ImageView imageView = imageViewReference.get(); final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); // 判断当前task??兌的task if (this == bitmapWorkerTask && imageView != null) { imageView.setImageBitmap(bitmap); } } }}
前面的ImageView加蝲的实现方式?用于?/span>
ListView
and GridView
这类的UI视图lgQ我?以在Adapter?getView()
Ҏ??/span>loadBitmap Ҏ ؽ
- android ȡbyte[]еԪؽ
- android ַʽ
- android ActivityBroadcastReceiver,ô
- Android 4.0 ΪʲôģʾСҹȸƴ뷨ֹͣ
- androidgetSharedPreferences() ĸķ˼·
- android ôжһǷ
- android ݰܷ,ν
- android RadioButtonĬѡ
- ksoap2-android-webServiceôóʱ
- android ôê
- android UIƽ
- android ͼƬȡй
- android ôԱ֧ӿ
- Android ϮInputMethodServiceԶ뷨
- android ڷӵ
- android activityͨ
- android ôʵֶviewķŴС
- android ̳̽
- android ID,δ
- ϰ2-3£java+androidоߣôЧá
- android UI߳AsyncTaskй
- android(java)еjava.netܲܺc#system.net.socketstcpͨ,ν
- android ListView еonItemClick Intent ûת
- android(java) й
- c#c++,android,ios(iphone),php,javaγ ɢ
- android PostļASP.NETй⣬յղļ
- RIM Android ṩѵ PlayBook213ǰ
- android ̬ؼ߶
- Android test project 뷽
- android -ʹý̳̣1