Android Asynchronous Task Design ideas (asynctask) _android

Source: Internet
Author: User
Tags sleep

The idea here is that I'm using the code to view the Android source code, so it doesn't match the original design idea of Google engineer 100% (or maybe 0%), but this article will certainly help you understand asynctask, or something you haven't found before.

As we all know, Android's main thread (also known as UI thread, thread ID 1) has some restrictions, so that the main thread can not do some things, such as access to the network is not allowed, otherwise it is reported, However, after the 2.3 version, you can change its restriction policy by adding the following code, forcing the main thread to access the network:

Copy Code code as follows:

if (Android.os.Build.VERSION.SDK_INT > 9) {
Strictmode.threadpolicy policy = new StrictMode.ThreadPolicy.Builder (). Permitall (). build ();
Strictmode.setthreadpolicy (Policy);
}

However, Strictmode is a development tool primarily used to detect disk and network access in the main thread, rather than letting you do the "bad" thing, in fact, the limitations of Android are good, forcing developers to focus on the user experience, a negative example is Windows, the main thread can do anything, Some lazy developers put all the tasks in the main thread, make threads often good cards, such as editor UE or notepad++ open a network (such as Samba server) files, if suddenly the network is interrupted, then your entire editor is stuck, it will take a long time to have a response, But I'm not sure if that's because the mainline Chengri has access to the network, but Windows often does that for this reason. There is also a positive example of iOS, extremely attention to response speed, so when there is a user input event, the kernel has a corresponding scheduling, so that the priority response to user action.

Or back to the point, this is because the main thread of these restrictions so that developers have to write a number of threads, of course, you can not asynctask, but you do not have to avoid multithreading, if you do not, it is possible to use handler and thread, I think a lot of people when beginners is that dry, including me, because it is very likely that there is no such a class, so often write handler and thread, written to find that there are some code is the same, you write handler and thread anonymous class must be repeated code, as follows:

Copy Code code as follows:

[Final Handler Handler = new Handler () {
public void Handlemessage (msg) {
System.out.println ("The Hard have done!");
... front end code
}
};
New Thread () {
public void Run () {
Dohardwork ();
Handler.sendemptymessage (0);
}

private void Dohardwork () {
... back end code
}
}.start ();

You might want to reuse the code, and of course, you can use this code in a copy way, just write your code in the ellipsis, but better reuse is to encapsulate it with a class, well, then we'll simply encapsulate it, and then it becomes this:

Copy Code code as follows:

public class Handlerandthread {
Private Handler Handler = new Handler () {
public void Handlemessage (msg) {
System.out.println ("The Hard have done!");
//...
}
};

public void Doinbackground () {
New Thread () {
public void Run () {
Dohardwork ();
Handler.sendemptymessage (0);
}


private void Dohardwork () {
// ...
}
};
}
}

It's not going to work. Because you can't tell the background thread what to do, do not know the notice, to reuse or get the copy code, we can add two methods, one in the foreground call a call in the background, as long as the definition of a new class can be implemented reuse, so the code becomes this:

Copy Code code as follows:

public class Handlerandthread {
Private Handler Handler = new Handler () {
public void Handlemessage (msg) {
System.out.println ("The Hard have done!");
Runinfrontend (); Added
}
};

public void Doinbackground () {
New Thread () {
public void Run () {
Dohardwork ();
Handler.sendemptymessage (0);
}

private void Dohardwork () {
Runinbackend (); Added
}
};
}

Added
protected void Runinbackend () {
}

Added
protected void Runinfrontend () {
}
}

A reusable class comes out, we write a subclass and call it with an activity:

Copy Code code as follows:

public class Mainactivity extends activity {
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);

New Subhandlerandthread (). Doinbackground ();
}

Class Subhandlerandthread extends Handlerandthread {
protected void Runinbackend () {
try {
Thread.Sleep (10 * 1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

protected void Runinfrontend () {
System.out.println ("Task has been done");
}
}
}

Is this a lot simpler than writing thread and handler directly? Here I use sleep to mold like a long time transaction, if in the real environment, we may be to download, if it is a download, we may want to pass the parameters of the download address to the background thread, to let him download according to our needs, We add a parameter to the Doinbackground method, so the code for the Handlerandthread class becomes this:

Copy Code code as follows:

public class Handlerandthread {
...

public void Doinbackground (final String URL) {//Added URL
New Thread () {
public void Run () {
Dohardwork ();
Handler.sendemptymessage (0);
}

private void Dohardwork () {
Runinbackend (URL); Added URL
}
};
}

protected void runinbackend (String URL) {//Added URL
}

...
}

And the code that invokes the class becomes this:

Copy Code code as follows:

public class Mainactivity extends activity {
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);

String url = "Http://path/to/file";
New Subhandlerandthread (). Doinbackground (URL); Added URL
}

Class Subhandlerandthread extends Handlerandthread {
@Override
protected void runinbackend (String URL) {//Added URL
System.out.println ("Start download from URL:" + URL);
try {
Thread.Sleep (10 * 1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
}

@Override
protected void Runinfrontend () {
System.out.println ("Finish Download");
}
}
}

If it was the next file, would we add a progress update, and then it would be this way:

Copy Code code as follows:

public class Handlerandthread {
Private Handler Handler = new Handler () {
public void Handlemessage (msg) {
Switch (msg.what) {//Added
Case 0:
Runinfrontend ();
Break

Case 1:
Runinfrontendprogress (MSG.ARG1);
Break
}
}
};

...

Final protected void publishprogress (int progress) {//Added
Handler.obtainmessage (1, progress, 0);
}

protected void runinfrontendprogress (int progress) {//Added
}
}

public class Mainactivity extends activity {
...

Class Subhandlerandthread extends Handlerandthread {
@Override
protected void runinbackend (String URL) {
System.out.println ("Start download from URL:" + URL);
for (int i = 0; i < ++i) {
try {
Thread.Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrack ();
}
Publishprogress (I*10); Added
}
}

...

@Override
protected void runinfrontendprogress (int progress) {//Added
System.out.println ("Progress:" + Progress);
}
}
}

You may not have the patience of a version of the evolution, then I jump it, a few more needs: one, we downloaded may want to get the file path, so we give the Runinfrontend method plus an input parameter filepath representation path; The methods that must be implemented are changed into abstract methods, and classes are also changed to abstract methods. I change some of the method names in the code to make them better understood, change the doinbackground to execute, change the runinfrontend to OnPostExecute, Change the runinfrontendprogress to Onprogressupdate. The final version is as follows:

Copy Code code as follows:

Public abstract class Handlerandthread {
Private Handler Handler = new Handler () {
public void Handlemessage (msg) {
Switch (msg.what) {
Case 0:
OnPostExecute ((String) msg.obj);
Break


Case 1:
Onprogressupdate (MSG.ARG1);
Break
}
}
};

public void Doinbackground (final String URL) {
New Thread () {
public void Run () {
String result = runinbackend (URL);
Handler.obtainmessage (0, result);
}


};
}

Final protected void publishprogress (int progress) {
Handler.obtainmessage (1, progress, 0);
}


Abstract protected string runinbackend (string url);
protected void OnPostExecute (String filePath) {}
protected void Onprogressupdate (int progress) {}
}
public class Mainactivity extends activity {
@Override
protected void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);


String url = "Http://path/to/file";
New Subhandlerandthread (). Doinbackground (URL);
}

Class Subhandlerandthread extends Handlerandthread {
@Override
Protected string runinbackend (string url) {
System.out.println ("Start download from URL:" + URL);
for (int i = 0; i < ++i) {
try {
Thread.Sleep (1000);
catch (Interruptedexception e) {
E.printstacktrace ();
}
Publishprogress (I*10);
}

return "/path/to/file";
}

@Override
protected void OnPostExecute (String filePath) {
System.out.println ("Download finished");
}

@Override
protected void Onprogressupdate (int progress) {
System.out.println ("Progress:" + Progress);
}
}
}

This is not like Android Asynctask, I think Google is due to this type of demand, the Android official website describes the Asynctask:

This class allows to perform background operations and publish results on the UI thread without has to manipulate threa DS and/or handlers.

This class makes it possible to perform operations in the background and then publish the results to the UI thread without using thread and handler. In fact, his internal implementation is encapsulated thread and handler, so you do not have to use these two low-level classes directly, but his purpose is also code reuse, his implementation and we write the class is similar. There are several main differences: one, Asynctask uses the thread pool instead of a single thread to perform background tasks, the thread pool is shared by the entire process because his thread pool object is a static member variable, and many people mistakenly think that the more threads the asynctask are creating, It's not absolutely true, because the thread pool is dynamically adjusted according to the load, and has the maximum and idle timeout, the Asynctask configuration is the smallest 5, the maximum 128, idle timeout 1 seconds, of course, you can also configure the number of threads according to the number of tasks thread increment, about the thread pool, you can refer to here, Later I will write articles on the blog to discuss the Java thread pool, two, asynctask input and output parameters using generics, three, Asynctask support interrupt the current task.

Now I know Asynctask's design idea, is not very simple, so suggested that children's shoes to see its source code, anyway, I have to write when the source check the custom, because I will wonder how it is realized, look at the source has a lot of benefits, such as good API design ideas, software architecture.

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.