In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces how to use AsyncTask, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let the editor take you to understand it.
Introduction
AsyncTask, I believe you are already familiar with it. It encapsulates Thread and Handler internally, which allows us to put some time-consuming operations on AsyncTask and update the results to UI in a timely manner. AsyncTask is mainly used for short-time and time-consuming operations. AsyncTask is not recommended for long-time-consuming operations.
An example private class DownloadFilesTask extends AsyncTask {protected void onPreExecute () {showProgress ();} protected Long doInBackground (URL...) Urls) {int count = urls.length; long totalSize = 0; for (int I = 0; I < count; iTunes +) {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");}} copy the code
AsyncTask is an abstract class, and we must customize a class that inherits from it when we want to use it. The prototype of AsyncTask is:
Public abstract class AsyncTask {} copy the code
It receives three generic parameters, representing the parameter type, the progress type, and the result type.
In the above example, DownloadFilesTask receives the parameter type as URL, uses the Integer type to indicate the progress of the task, and the final result of the task is a Long type.
Note: the above three generic types do not necessarily have to use an explicit type, for types that are not in use, you can use the Void type instead.
Inheriting AsyncTask requires at least overriding the doInBackground method, and AsyncTask also provides three other methods for us to rewrite, namely onPreExecute, onProgressUpdate, and onPostExecute.
OnPreExecute method. Executes before the task starts execution, which runs in the UI thread. Usually we can show a waiting progress bar here.
DoInBackground method. Throughout the entire time-consuming task, it runs in child threads. Perform a time-consuming operation here.
OnProgressUpdate method. The entire time-consuming task is executed after the publishProgress method is called, which runs in the UI thread. It is usually used to show the progress of the entire task.
OnProgressUpdate method. Called after the task is received, the return result of doInBackground is passed through to the parameter value of onPostExecute, which runs in the main thread. Usually we get the result data after the completion of the task execution from here.
Rules of AsyncTask
The AsyncTask class must be loaded on the UI thread. (it will be done automatically above 4.1 system version)
The AsyncTask object must be created in the UI thread, which means that the constructor of the AsyncTask must be called in the UI thread. The tested AsyncTask object can be created in the child thread, as long as the execute method executes on the UI thread to OK. But no one will do it, because it's unnecessary! )
The execute method must be called in the UI thread. This ensures that the onPreExecute method runs on the UI thread.
Do not actively call the onPreExecute, doInBackground, onProgressUpdate, onProgressUpdate methods.
Under single thread, the task of the AsyncTask object can only be executed once, otherwise a run-time error will be reported.
Rules for AsyncTask to perform tasks
In the early days of AsyncTask, tasks were executed sequentially in a background thread. Since Android 1.6, it has become possible to execute tasks in parallel in background threads. Then, when it comes to Android version 3.0, it is changed to single-threaded sequential execution, so as to avoid the wrong behavior of concurrent tasks.
To verify the above conclusion, let's look at an example of Demo.
Public class MainActivity extends Activity {public static final String TAG = "MyApplication"; @ Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); new MyTask ("task1"). Execute (); new MyTask ("task2"). Execute (); new MyTask ("task3"). Execute (); new MyTask ("task4"). Execute () New MyTask ("task5") .execute (); new MyTask ("task6") .execute ();} private class MyTask extends AsyncTask {private String taskName; MyTask (String taskName) {this.taskName = taskName;} @ Override protected Void doInBackground (Void...) Integers) {try {Thread.sleep (6000);} catch (InterruptedException e) {e.printStackTrace ();} return null;} @ Override protected void onPostExecute (Void aVoid) {SimpleDateFormat df = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss") Log.e (TAG, taskName + "finish at:" + df.format (new Date ();} copy code
This example is relatively simple, that is, when MainActivity starts, MyTask is executed six times and the time node after the execution of the task is printed out.
Image.png
The system version of the phone is Android 8.0. from the above Log information, we can see that AsyncTask is indeed executed serially. Since the minimum system version of the existing test machine is Android 4.1, it is difficult to find antique machines below Android 3.0.Therefore, we can only use the source code to verify whether AsyncTask is executed in parallel from Android 1.6to Android 3.0.Therefore, we can only use the source code to verify whether AsyncTask is executed in parallel.
Source code analysis Android version 2.3
Whether AsyncTask executes serially or in parallel depends on its execute method.
Public final AsyncTask execute (Params... Params) {... Omit mWorker.mParams = params; sExecutor.execute (mFuture); return this;} copy code
The execute method, through sExecutor, is actually a ThreadPoolExecutor object, and its initialization is as follows.
Private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor (CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); copy code
ThreadPoolExecutor is a multithreaded container in which multiple threads can be created to perform multiple tasks. This verifies that Android 1.6 version to Android 3.0 version is direct, and the mechanism of AsyncTask task execution is indeed different now, which allows tasks to be executed in parallel.
Android version 8.0
Let's compare the execute method of Android version 8.0.
Public final AsyncTask execute (Params... Params) {return executeOnExecutor (sDefaultExecutor, params);} public final AsyncTask executeOnExecutor (Executor exec, Params...) Params) {... Omit mWorker.mParams = params; exec.execute (mFuture); return this;} copy code
The executeOnExecutor method is called in the execute method and sDefaultExecutor is passed in as an Executor object. The initialization of sDefaultExecutor is shown below.
Private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;public static final Executor SERIAL_EXECUTOR = new SerialExecutor (); private static class SerialExecutor implements Executor {final ArrayDeque mTasks = new ArrayDeque (); Runnable mActive; public synchronized void execute (final Runnable r) {mTasks.offer (new Runnable () {public void run () {try {r.run ()) } finally {scheduleNext (); / / continue to execute the scheduleNext method after the task is finished); if (mActive = = null) {/ / the first task will execute the method scheduleNext () }} protected synchronized void scheduleNext () {if ((mActive = mTasks.poll ())! = null) {/ / determine whether there is a next task in the mTask queue, and then take it out and execute THREAD_POOL_EXECUTOR.execute (mActive);} copy the code
As you can see, in Android version 8.0, an ArrayDeque queue is created, and only one task is obtained from the queue for execution at a time. After execution, it will continue to determine whether there are any tasks in the queue, and if so, take them out and execute them until all tasks have been executed. Thus it can be seen that Android version 8.0 execution tasks are performed serially.
If we want to change the default behavior of AsyncTask, can we change it? The answer is yes.
We can directly call the executeOnExecutor method of AsyncTask, pass an Executor object, and become a parallel execution method.
For the above example, you can change it like this.
Public class MainActivity extends Activity {public static final String TAG = "MyApplication"; @ Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); new MyTask ("task1") .executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR); new MyTask ("task2") .executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR); new MyTask ("task3") .executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR) New MyTask ("task4") .executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR); new MyTask ("task5") .executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR); new MyTask ("task6") .executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR);} private class MyTask extends AsyncTask {private String taskName; MyTask (String taskName) {this.taskName = taskName } @ Override protected Void doInBackground (Void... Integers) {try {Thread.sleep (6000);} catch (InterruptedException e) {e.printStackTrace ();} return null;} @ Override protected void onPostExecute (Void aVoid) {SimpleDateFormat df = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss") Log.e (TAG, taskName + "finish at:" + df.format (new Date ();} copy code
After execution, the printed Log information is shown in the following figure.
Image.png
Note: the first five Task are executed at the same time, because AsyncTask.THREAD_POOL_EXECUTOR creates five core threads, and the sixth task needs to wait for the idle thread to continue. Therefore, it is explained that the execution time of the sixth task is inconsistent with that of the first five tasks.
Thank you for reading this article carefully. I hope the article "how to use AsyncTask" shared by the editor will be helpful to everyone. At the same time, I also hope that you will support and pay attention to the industry information channel. More related knowledge is waiting for you to learn!
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.