In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
How to deal with bitmaps from UI threads, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can gain something.
BitmapFactory's decode () method, discussed in Load Large Bitmaps Efficiently key points, should not be executed in the main UI thread if you want to read source data from disk or network location (or any other real source relative to memory). The loading time of the data is unpredictable and depends on many factors (read speed from disk or network, image size, power of CPU, etc.). If these tasks block the UI thread and the system marks your application as unresponsive, the user can choose to turn it off to respond (see Designing for Responsiveness for more information).
It will guide you to work with bitmaps by using AsyncTask in background threads and tell you how to deal with concurrency problems.
Use an asynchronous task
The AsyncTask class provides a simple way to perform many tasks in a background thread and feed the results back to the UI thread. The method used is to create a subclass that inherits from it and implement the provided method. Here is an example of loading a large image into ImageView using AsyncTask and decodeSampledBitmapFromResource ():
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. @ Override protected void onPostExecute (Bitmap bitmap) {if (imageViewReference null) {final ImageView imageView = imageViewReference.get (); if (imageView! = null) {imageView.setImageBitmap (bitmap);}}
For ImageView, WeakReference ensures that AsyncTask does not prevent ImageView and any of its references from being reclaimed during garbage collection. There is no guarantee that ImageView will still exist after the task is completed, so you must check its reference in the onPostExecute () method. ImageView may no longer exist if, for example, if the user exits the activity or the configuration changes before the task is completed.
To load the bitmap asynchronously, simply create a new task and execute it:
Public void loadBitmap (int resId, ImageView imageView) {BitmapWorkerTask task = new BitmapWorkerTask (imageView); task.execute (resId);}
Deal with concurrency
Common view components such as ListView and GridView, when used in conjunction with AsyncTask in the previous section, raise another problem. To optimize memory, these components recycle child views when the user scrolls. If each child view triggers an AsyncTask, there is no guarantee when it is completed, and the related view has been used in other child views before it has been reclaimed. In addition, the order in which asynchronous tasks start cannot guarantee the order in which they are completed.
This article discusses dealing with concurrency through the Multithreading for Performance function and provides a solution for ImageView to store a reference to an AsyncTask that can be checked later when the task is completed. Using a similar approach, the AsyncTask in the previous section can be extended to follow a similar pattern.
Create a dedicated subclass of Drawable to store a reference backup to the work task. In this case, a BitmapDrawable is used so that a placeholder image can be displayed in the ImageView after the task is completed:
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 ();}}
Before executing BitmapWorkerTask, you create an AsyncDrawable and bind it to the target ImageView:
Public void loadBitmap (int resId, ImageView imageView) {if (cancelPotentialWork (resId, imageView)) {final BitmapWorkerTask task = new BitmapWorkerTask (imageView); final AsyncDrawable asyncDrawable = new AsyncDrawable (getResources (), mPlaceHolderBitmap, task); imageView.setImageDrawable (asyncDrawable); task.execute (resId);}}
If another running task is already associated with this ImageView, the cancelPotentialWork reference is in the code sample check above. If so, it attempts to cancel the previous task by calling cancel (). In a few cases, the new task data matches the existing task and does not need to be done. Here is the implementation of cancelPotentialWork:
Public static boolean cancelPotentialWork (int data, ImageView imageView) {final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask (imageView); 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;}
A helper method, getBitmapWorkerTask (), uses the above to retrieve a task related to a particular ImageView:
Private static BitmapWorkerTask getBitmapWorkerTask (ImageView imageView) {if (imageView! = null) {final Drawable drawable = imageView.getDrawable (); if (drawable instanceof AsyncDrawable) {final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; return asyncDrawable.getBitmapWorkerTask ();}} return null;}
The * step is to update the onPostExecute () method in BitmapWorkerTask so that it is checked when the task is cancelled and when the current task is associated with this ImageView:
Class BitmapWorkerTask extends AsyncTask {... @ Override protected void onPostExecute (Bitmap bitmap) {if (isCancelled ()) {bitmap = null;} if (imageViewReference! = null & & bitmap! = null) {final ImageView imageView = imageViewReference.get (); final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask (imageView) If (this = = bitmapWorkerTask & & imageView! = null) {imageView.setImageBitmap (bitmap);}}
This implementation is now suitable for using ListView and GridView control components and any other components that recycle their child views. Simply call loadBitmap when you normally set a picture for your ImageView control. For example, the way to do this in a GridView is in the [android.view.View, android.view.ViewGroup) getView ()] (http://docs.eoeandroid.com/reference/android/widget / Adapter.html#getView (int,) method in a supported adaptation.
Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.