Android Development Notes: Asynctask's application detailed _android

Source: Internet
Author: User
Tags http request
Introduction of Asynctask and its basic use method
The introduction and basic usage of asynctask can refer to the official documentation and the Android development Note: An in-depth understanding of multithreaded asynctask is not repeated here.
A problem caused by asynctask
Last week encountered a very strange problem, a small function from the network to download a picture, and then put into the ImageView, is implemented with Asynctask, its logic is also very simple, only in the Doinbackground with HTTP request the image of the input stream out, Then use Bitmapfactory to parse, and then put the bitmap into ImageView. This application is developed with a 4.0 SDK and is run on 4.0. But sometimes it takes a long time to download this picture, and even a few minutes to wait. An unacceptable fact was found through debugging: Doinbackground () was not executed in time, that is, it did not execute immediately after the #execute () call, but waited a long time before it was executed.
God horse situation, is not asynctask is not a thread, is not asynchronous, is asynctask another insider?
the inside of Asynctask
Asynctask has two main parts: one is the interaction with the main line, the other is the management scheduling of the thread. Although it is possible to have multiple instances of Asynctask subclasses, the internal handler and threadpoolexecutor of Asynctask are shared within the process, and they are static, and they belong to the class, and the properties of the class are scoped to the Classpath , because a process is a VM, Asynctask controls all instances of subclasses within the process scope.
interacting with the main thread
Interaction with the main thread is done through handler, because this article mainly discusses asynctask in the task scheduling, so for this part does not do a detailed introduction, interested friends can go to see Asynctask source code
Scheduling of thread Tasks
Internally creates a process-scoped thread pool to manage the task to run, which means that when you call Asynctask#execute (), Asynctask will hand the task to the thread pool, where the thread pool manages to create the thread and run Therad. For the internal thread pool different versions of the Android is not implemented the same way:
Android2.3 Previous version, also known as SDK/API 10 and previous versions
The internal thread pool limit is 5, which means that only 5 threads can run at the same time, more than one thread can wait, waiting for a previous thread to execute before being dispatched and running. In other words, if there are more than 5 instances of asynctask in a process, then the 6th can only wait for an opportunity if the first 5 have been running for a long time. This is a limitation of the asynctask and cannot be resolved for versions prior to 2.3. If your application requires a large number of background threads to perform tasks, then you can only discard using asynctask, create a thread pool to manage thread, or simply use thread without thread pooling directly. Have to say, although asynctask more convenient than thread, but it can only run at the same time 5 threads, which also greatly limits its strength, you have to carefully design your application, stagger the use of asynctask time, try to do time-sharing, or ensure that the number will not be greater than 5 , or you may experience the problem mentioned above. Otherwise, you can only use the APIs in Javase.



Android 3.0 Later, also known as Sdk/api 11 and later versions
Google may be aware of the limitations of Asynctask, starting with Android 3.0 to make some adjustments to the Asynctask API:
1. #execute () The tasks submitted, in order to run only one at a time
That is, it is in the order of submission to start one thread at a time to perform a task, and then perform a second task, which is equivalent to having only one background thread executing the Committed task (Executors.newsinglethreadpool ()).



2. New Interface #executeonexecutor ()
This interface allows developers to provide custom thread pool running and scheduling threads, and if you want all tasks to run concurrently, create an unlimited thread pool (Executors.newcachedthreadpool ()), and provided to Asynctask. This asynctask instance has its own thread pool instead of using the Asynctask default.
3. Added two predefined thread pools Serial_executor and Thread_pool_executor
In fact, Thread_pool_executor is not new, before there is, but before (Android 2.3) It is asynctask private, not public just. Thread_pool_executor is a corepoolsize 5 thread pool, which means that up to 5 threads run at the same time, more than 5 will wait. So if you use Executeonexecutor (Asynctask.thread_pool_executor) with the 2.3 version of Asynctask.execute () effect is the same.



The Serial_executor is new, and its role is to guarantee the order in which the tasks are executed, that is, it can ensure that the tasks submitted are actually executed in a sequential order. It has a queue internally to hold the submitted tasks, ensuring that only one is currently running, so that the task is executed in exactly the order that the default execute () uses, that is, Executeonexecutor (Asynctask.serial_ EXECUTOR) is the same as execute ().
the solution to the preceding problem
Knowing the asynctask is the reason for the previous problem: because it is a 4.0 platform, all asynctask do not run on separate threads, but are executed by Serial_executor-ordered threads of use. Because asynctask may be used elsewhere in the application, the asynctask that takes pictures from the network may wait until the other task is completed before executing instead of calling executor () immediately after.
The solution is actually simple, either using thread directly or creating a separate thread pool(Executors.newcachedthreadpool ()). Or the simplest solution is to use Executeonexecutor (Asynctask.thread_pool_executor), so at least not until the front end of the execution.
Precautions for use of Asynctask
The previous article suggested using Asynctask instead of thread, but Asynctask seems to have its limitations, which means choosing the right tool based on specific requirements, No Silver Bullet. Here are some suggestions:
• Improve your design with less asynchronous processing
Thread overhead is very large, while asynchronous processing is also prone to errors, difficult to debug, difficult to maintain, so improve your design, as little as possible with asynchronous. For general database queries, a small number of I/O operations are not necessary to start the thread.
• Use Asynctask when interacting with the main thread, otherwise use thread
Asynctask is designed to meet the specific needs of Android: non-main thread cannot operate (UI) components, so asynctask extended thread enhances the ability to interact with the main thread. If your application does not interact with the main thread, then use thread directly.
• Be sure to create a thread pool when you need a large number of threads to perform a task
The overhead of a thread is very large, especially if you create a new thread, otherwise you do not have to design tools such as thread pools. When a large number of threads are required to perform a task, it is important to create a thread pool, whether using asynctask or thread, because there is a limit to the number of thread pools within it, which may not meet the requirements, and thread pooling is used to manage the thread, avoiding the creation of a large number of threads by the For example, downloading pictures from the Internet in bulk, you don't want to download it one at a time, or 5 or 5 downloads, then create a thread pool with a corepoolsize of 10 or 20, each 10 or 20 of these downloads, which satisfies the speed without consuming the useless performance overhead to create the thread indefinitely.
• For asynchronous tasks that you want to start immediately, either use thread directly or create a separate thread pool for Asynctask
The default asynctask does not necessarily immediately execute your task unless you provide him with a separate thread pool. If you do not interact with the main thread, you can create a thread directly, although creating threads is expensive, but if this is not a bulk operation there is no problem.
the development of Android is not as simple as it should be, and it takes more effort and time to code and test to make sure that the program is of high quality
Attach Related resources:
Use a custom corepoolsize of 7 executor (Executors.newfixedthreadpool (7)):


Use Unrestricted executor (Executors.newcachedthreadpool ()):



The code used for these examples:
Copy Code code as follows:

public class Asynctaskdemoactivity extends activity {
private static int ID = 0;
private static final int task_count = 9;
private static Executorservice Single_task_executor;
private static Executorservice Limited_task_executor;
private static Executorservice Full_task_executor;

static {
Single_task_executor = (executorservice) executors.newsinglethreadexecutor ();
Limited_task_executor = (executorservice) executors.newfixedthreadpool (7);
Full_task_executor = (executorservice) executors.newcachedthreadpool ();
};

@Override
public void OnCreate (Bundle icicle) {
Super.oncreate (Icicle);
Setcontentview (r.layout.asynctask_demo_activity);
String title = "Asynctask of API" + VERSION. Sdk_int;
Settitle (title);
Final ListView taskList = (ListView) Findviewbyid (r.id.task_list);
Tasklist.setadapter (New Asynctaskadapter (Getapplication (), task_count));
}

Private class Asynctaskadapter extends Baseadapter {
Private context Mcontext;
Private Layoutinflater mfactory;
private int mtaskcount;
List<simpleasynctask> mtasklist;

Public Asynctaskadapter (context context, int taskcount) {
Mcontext = context;
MFactory = Layoutinflater.from (Mcontext);
Mtaskcount = Taskcount;
Mtasklist = new arraylist<simpleasynctask> (taskcount);
}

@Override
public int GetCount () {
return mtaskcount;
}
@Override
Public Object getitem (int position) {
return Mtasklist.get (position);
}
@Override
public long getitemid (int position) {
return position;
}
@Override
Public View GetView (int position, View Convertview, ViewGroup parent) {
if (Convertview = = null) {
Convertview = mfactory.inflate (R.layout.asynctask_demo_item, NULL);
Simpleasynctask task = new Simpleasynctask ((TaskItem) convertview);
/*
* It only supports five tasks at most. More tasks would be scheduled only
* Five finish. In all, the pool size of Asynctask are 5, at any time it's only
* has 5 threads running.
*/
Task.execute ();
Use Asynctask#serial_executor are the same to #execute ();
Task.executeonexecutor (Asynctask.serial_executor);
Use Asynctask#thread_pool_executor is the same to older version #execute () (less than API 11)
But different from newer version of #execute ()
Task.executeonexecutor (Asynctask.thread_pool_executor);
One by one, same to newer version of #execute ()
Task.executeonexecutor (Single_task_executor);
Execute tasks at some limit which can is customized
Task.executeonexecutor (Limited_task_executor);
No limit to thread pool size, all tasks run simultaneously
Task.executeonexecutor (Full_task_executor);

Mtasklist.add (Task);
}
return convertview;
}
}

Private class Simpleasynctask extends Asynctask<void, Integer, void> {
Private TaskItem Mtaskitem;
Private String Mname;

Public Simpleasynctask (TaskItem item) {
Mtaskitem = Item;
Mname = "Task #" + string.valueof (++id);
}

@Override
protected void Doinbackground (void ... params) {
int prog = 1;
while (Prog < 101) {
Systemclock.sleep (100);
Publishprogress (Prog);
prog++;
}
return null;
}

@Override
protected void OnPostExecute (void result) {
}

@Override
protected void OnPreExecute () {
Mtaskitem.settitle (Mname);
}

@Override
protected void Onprogressupdate (Integer ... values) {
Mtaskitem.setprogress (Values[0]);
}
}
}
Class TaskItem extends LinearLayout {
Private TextView Mtitle;
Private ProgressBar mprogress;

Public TaskItem (context context, AttributeSet Attrs) {
Super (context, attrs);
}
Public TaskItem {
Super (context);
}

public void Settitle (String title) {
if (Mtitle = = null) {
Mtitle = (TextView) Findviewbyid (r.id.task_name);
}
Mtitle.settext (title);
}

public void setprogress (int prog) {
if (mprogress = = null) {
Mprogress = (ProgressBar) Findviewbyid (r.id.task_progress);
}
Mprogress.setprogress (Prog);
}
}

Copy Code code as follows:

<?xml version= "1.0" encoding= "Utf-8"?>
<linearlayout xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Match_parent"
android:layout_height= "Match_parent"
android:paddingleft= "10dip"
android:paddingright= "10dip"
android:orientation= "Vertical" >
<listview android:id= "@+id/task_list"
Android:layout_width= "Fill_parent"
android:layout_height= "Wrap_content"
Android:divider= "#cccccc"
android:dividerheight= "0.6dip"
Android:footerdividersenabled= "true"
Android:headerdividersenabled= "true"/>
</LinearLayout>

Copy Code code as follows:

<?xml version= "1.0" encoding= "Utf-8"?>
<com.hilton.effectiveandroid.os.taskitem xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "Match_parent"
android:layout_height= "50dip"
Android:gravity= "Center_vertical"
Android:layout_gravity= "Center_vertical"
android:orientation= "Horizontal" >
<textview android:id= "@+id/task_name"
Android:layout_width= "Wrap_content"
android:layout_height= "Wrap_content"
Android:textcolor= "#ffff00"
Android:textsize= "26sp"/>
<progressbar android:id= "@+id/task_progress"
Android:layout_width= "Fill_parent"
android:layout_height= "15dip"
android:max= "100"
Style= "@android: Style/widget.progressbar.horizontal"/>
</com.hilton.effectiveandroid.os.taskitem >

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.