Android asynchronous AsyncTask, androidasynctask

Source: Internet
Author: User
Tags addall

Android asynchronous AsyncTask, androidasynctask

I once saw someone say it makes sense to share it with me:

There are two types of technologies:

(1) the specific method of doing things is skill;

(2) The principle and principle of doing things are Dao;


A major problem was found in the recent project. It was caused by AsyncTask. If you do not have a thorough understanding of AsyncTask, writing the code is bury. It may not be at which time. First of all, we need to understand why Google invented AsyncTask and what problems does AsyncTask solve? Android has a single-thread model principle: UI operations are not thread-safe and must be executed in the UI thread. Therefore, Google created AsyncTask and AsyncTask extended Thread to enhance interaction with the main Thread. If your application does not interact with the main Thread, you can simply use the Thread.

In a single-threaded model, you must always remember the following two rules:
1. Do not block the UI thread
2. Make sure to only access the Android UI toolkit in the UI thread


First, let's talk about the four methods rewritten by AsyncTask:

(1) doInBackground () // runs in the background thread

(2) onPreExecute () // run in the UI thread

(3) onProgressUpdate () // run in the UI thread

(4) onPostExecute () // run in the UI thread

How to use these methods in detail. If you are not clear about them, You can Google them. Many colleagues have explained them in detail;


To correctly use the AsyncTask class, the following guidelines must be followed:
1) The Task instance must be created in the UI thread.
2) The execute method must be called in the UI thread.
3) do not manually call onPreExecute (), onPostExecute (Result), doInBackground (Params ...), OnProgressUpdate (Progress ...) These methods
4) The task can only be executed once. Otherwise, exceptions may occur during multiple calls.
The doInBackground method and the onPostExecute parameter must correspond to each other. These two parameters are specified in the generic parameter list declared by AsyncTask. The first parameter is the parameter accepted by doInBackground, and the second parameter is the parameter indicating the progress, the third parameter is the doInBackground return and the parameter passed in onPostExecute.


The above four points are taken from the internet. I think they make sense. For the 4th point, I have an objection: Even if multiple calls are made, exceptions should not occur, because the AsyncTask class has open interfaces, cancel (true) and isCancelled (). These two methods can be used together to control AsyncTask and exit manually. For details, refer to the example in the source code class AsyncTask. java.

AsyncTask must be subclassed to be used. The subclass will override at least * one method ({@link #doInBackground}), and most often will override a * second one ({@link #onPostExecute}.)</p> * * <p>Here is an example of subclassing:</p> * <pre class="prettyprint"> * private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { *     protected Long doInBackground(URL... urls) { *         int count = urls.length; *         long totalSize = 0; *         for (int i = 0; i < count; i++) { *             totalSize += Downloader.downloadFile(urls[i]); *             publishProgress((int) ((i / (float) count) * 100)); *             // Escape early if cancel() is called *             if (isCancelled()) break; *         } *         return totalSize; *     } * *     protected void onProgressUpdate(Integer... progress) { *         setProgressPercent(progress[0]); *     } * *     protected void onPostExecute(Long result) { *         showDialog("Downloaded " + result + " bytes"); *     } * }
This is the demo in AsyncTask.
 if (isCancelled()) break;

This is used to determine whether to exit the background thread. If cancel (true) is set, the break jumps out of the loop. Here we will talk about two points:

(1) it is best not to interrupt the thread to terminate the thread. This method is too crude and cannot guarantee the integrity of the Code. The best way to handle this is in the for loop, adding its own judgment flag in the while loop is the best way to handle it like AsyncTask. This is also a way for Google to guide us in how to deal with thread termination.

(2) Some people are also confused that there is no loop in my code and how to add a flag. In fact, most of the background processing logic processes the loop, it is seldom said that a line of code or a dozen lines of code is very time-consuming (of course, network-related, and download-related, there are other methods to solve this problem ). Even if a jni or so library is called, the returned result is slow. Then the mark bit is added after several time-consuming methods;

With the above method, we can make a complete solution design and design. When we execute AsyncTask again, we first determine whether we are running. If we are running, we will not execute or cancel the task and re-execute it, this depends on the specific requirements;

Example:

private void stopAyncTaskRunning() {if (mContactsListLoader != null&& mContactsListLoader.getStatus() == AsyncTask.Status.RUNNING) {mContactsListLoader.cancel(true); //if task is still running, stop it;}}

private void getContactsList() {stopAyncTaskRunning();mContactsListLoader = new ContactsListLoader();mContactsListLoader.executeOnExecutor(AsyncTask.THEAD_POOL_EXECUTOR);}
Of course, I need to cancel the previous Task and refresh the data the next time I come in. Also, do not forget to add it to the loop statement in doInBackground ().
@Overrideprotected Integer doInBackground(Object... arg0) {List<Contact> contacts = new ArrayList<Contact>();ContentResolver cr = mContext.getContentResolver();Cursor c = cr.query(ContactsContract.Contacts.CONTENT_URI,PROJECTION_CONTACT, null, null, null);if (c != null) {c.moveToPosition(-1);while (c.moveToNext()) {if (isCancelled()) {break;}。。。 。。。}
In this way, the logic is written according to the requirements, and what the requirements look like, the logic will be handled accordingly;


Let's talk about the location where AsyncTask is located. In Versions later than Android, AsyncTask has two execution methods:

(1) execute ()
(2) executeOnExecutor ()

If AsyncTask is used to call (1), it indicates a serial execution thread. If there are four fragment in this Activity and each fragment has an AsyncTask, in this case (1, it must be executed sequentially. The second is executed only after one execution is complete. If method (2) is used, serial execution can be performed, and the UI effect is good. The thread pool can be system or custom;

In addition, the number of execution threads in the default thread pool is described as follows:

The following 5 represents corePoolSize, 10 represents the length of the blocked queue, and 128 represents maximumPoolSize.
1: if the number of thread pools is less than 5, a new thread is created and executed.
2: If the number of threads is greater than 5 and smaller than 5 + 10 (the size of the blocked Queue), it will be 6th ~ 15 threads are added to the blocking queue. After five running threads in the thread pool end, the thread that blocks the queue is taken for execution.
3: if the number of threads is 16 ~ 128, the number of running threads is num-10
4: if the number of threads is greater than 128, discard it.

For details, refer to blog: Android practice skills: in-depth analysis of AsyncTask. This article provides a detailed explanation;

The last note is to refresh the UI when loading part of the data to give the user a good user experience. For example,

private static final int DISPLAY_NUM = 10;private List<Contact> mContacts = new ArrayList<Contact>();private class ContactsListLoader extendsAsyncTask<Object, Integer, Integer> {int count = 0;List<Contact> mTempContacts = new ArrayList<Contact>(DISPLAY_NUM);@Overrideprotected void onPreExecute() {super.onPreExecute();mTempContacts.clear();mContacts.clear();}@Overrideprotected Integer doInBackground(Object... arg0) {List<Contact> contacts = new ArrayList<Contact>();if (c != null) {c.moveToPosition(-1);while (c.moveToNext()) {if (isCancelled()) {break;}... ...contacts.add(contact);mTempContacts.add(contact);if (++count >= DISPLAY_NUM) {publishProgress();count = 0;}}}return contacts.size();}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);mContacts.addAll(mTempContacts);mTempContacts.clear();mAdapter.notifyDataSetChanged();}@Overrideprotected void onPostExecute(Integer size) {if (isCancelled())return;if (size > 0) {if (mTempContacts.size() > 0&& mTempContacts.size() != DISPLAY_NUM) {mContacts.addAll(mTempContacts);}} else {if (mTempContacts.size() > 0) {mContacts.addAll(mTempContacts);}}mAdapter.notifyDataSetChanged();}}
This is my model. After you understand it, you can set it to your own code. This is the logic I used to dynamically load and refresh the UI, and refresh 10 pieces of data once. This will avoid the impact of the next refresh on efficiency, it also ensures that you do not have to wait until the data is fully loaded to view the data. Two birds in one fell swoop.

For more information about AsyncTask, refer to the source code. If you know more about it, please leave a comment on shoes;


Asynchronous upload of gridview and AsyncTask in android

Like listview, The gridview will repeatedly execute the code in the getView function in your baseAdapter when you slide, if you put AsyncTask in getview, it will be asynchronously loaded multiple times.

AsyncTask for android Development

It is a little troublesome to load the gridView asynchronously. If you load the data at one time, it is okay, but if you want to load the data at getView () (such as loading each image ), at this time, you will start multiple asynchronous threads (call getView to start one Asynchronous Method at a time), which will report an error (the number of opened threads is too large ).
The official solution is to make AsyncTask a weak reference so that it can be recycled in time. You can refer to the document for specific operations, which is a bit complicated and cannot be explained here.
I am using another method: thread pool + runnable + handler. This ensures that images are loaded one by one during getView (). You can search for the specific process, there are many demos.

Several adapters in one interface are actually just a few pieces of data. What do you want to enable Asynchronization for? The background thread starts to download the data and can load the data in an Asynchronization.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.