Several multi-threaded implementations in Android

Source: Internet
Author: User
Tags message queue

There are several ways to do this:

1) activity.runonuithread (Runnable)

2) View.post (Runnable); View.postdelay (Runnable, long)

3) Handler

4) Asynctask

Android is a single-threaded model, which means that Android UI operations are not thread-safe and that these operations must be performed in the UI thread, so your simple new thread and start () will not work because it violates the Android single-threaded model. So how to use good multithreading? To summarize:

The principle of event handling: all possible time-consuming operations are placed on other threads to handle.

The event handling of the main thread in Android is not too time consuming, or the subsequent events cannot be responded to within 5 seconds, and the Anr dialog box pops up. So which methods will execute on the main thread?

1) Activity life cycle methods, such as: OnCreate (), OnStart (), Onresume (), etc.

2) Event handling methods, such as OnClick (), Onitemclick (), etc.

Usually the method that starts with on in the Android base class is invoked on the main thread.

To improve the responsiveness of the application, we can start with these two aspects.

In general, the execution time of the activity's OnCreate (), OnStart (), Onresume () method determines the time that your app's home page is opened, where it is necessary to put unnecessary actions on other threads, if it is still time-consuming, You can use SplashScreen. Using SplashScreen is best with dynamic, so users know that your app is not dead.

When the user interacts with your application, the execution speed of the event processing method determines whether the application is responsive, generally divided into synchronous and asynchronous situations:

1) synchronization, need to wait for the return result. For example, the user clicks the registration button and needs to wait for the server to return results, then a progress bar is required to prompt the user that your program is running and not dead. Generally with the server to interact with the progress bar, such as the system comes with the browser, URL jumps will have a progress bar.

2) asynchronous, no waiting for the result to be returned. For example, the collection function in the microblog, after the completion of the collection button after the successful execution of the finished to tell me, I do not want to wait for it, it is best to implement asynchronous.

Regardless of synchronous asynchronous, event handling can be time-consuming, so it needs to be processed in other threads, and then notifies the interface to refresh after processing is complete.

One thing to note here is that not all interface refresh behaviors need to be put into main threading, for example TextView's SetText () method needs to be in the main thread, otherwise it will throw calledfromwrongthreadexception, The ProgressBar setprogress () method does not need to be handled in the main thread.

Of course, you can also put all the UI component related behavior into the main thread to handle, no problem. Can lighten your burden of thinking, but you'd better understand the difference between them and master the nuances of things that are experts. The event handling code is processed in other threads, and if the result of the processing requires a refresh of the interface, then the method of inter-thread communication is required to implement a message to the main thread in the other thread.

How to implement inter-thread communication

There are several ways to enable other threads to communicate with the main thread in Android, and here are two common ways to do it.

1) Use Asynctask

Asynctask is an auxiliary class of asynchronous processing provided by the Android framework that enables time-consuming operations to be performed on other threads, while processing results are performed on the main thread, which, for developers, masks the concept of multithreading and the handler behind it. You do not know how to deal with the communication between the thread is not related, asynctask thoughtful help you do. Using him you will find that your code is easy to understand because they have some way of having specific responsibilities, especially asynctask, a preprocessing method OnPreExecute, a method doinbackground to perform tasks in the background, There are methods to update the progress publishprogress, there are methods to return the results OnPostExecute and so on, this is not like post these methods, all the operations are written in a runnable. But the better the package, the more advanced the API, the worse for the novice programmer, is that you don't know how it works. When you need to face more complex situations and the advanced API doesn't work well, you have a cup. Therefore, we should also grasp the more powerful, more free way to communicate with the main thread: the use of handler.

2) Use Handler

Here you need to know the classes that the Android SDK provides for the communication between several threads.

2.1 Handler

Handler is responsible for sending and processing messages in Android, which enables the communication of messages between other threads and the main thread.

2.2 Looper

Looper is responsible for managing thread Message Queuing and message loops

2.3 Message

Message is a messaging carrier for inter-thread communication. Transport cargo between two terminals, and the message serves as a container for any messages you want to deliver.

2.4 MessageQueue

MessageQueue is a message queue, FIFO, and its role is to save messages waiting to be processed by the thread.

The relationship between them is to call the Handler.sendmsg () method in another thread (the parameter is a Message object) and add the event that requires the main thread to be added to the MessageQueue of the main thread. The handler Handlermessage () method is called back when the main thread handler the message from the message queue through Mainlooper.

In addition to the above two common methods, there are several relatively simple methods

3) Activity.runonuithread (Runnable)

4) View.post (Runnable)

View.postdelayed (Runnable, long)

5) Handler.post

Handler.postdelayed (Runnable, long)

Improve performance with thread pooling

Here we recommend that you use a thread pool to manage temporary thread objects to achieve the purpose of improving application performance.

A thread pool is an instance of a resource pool thread application. Before we get to the thread pool, let's first look at the concept of a resource pool. In Java, creating and destroying objects is more resource-intensive. If we need to create an instance of an object of a certain type frequently in the application, it will result in many temporary objects, and when the temporary objects are lost, the virtual opportunity is garbage collected (GC), and the CPU will cause the application not to run properly when the GC is in progress, resulting in a decrease in the responsiveness of the application.

Resource pooling is used to solve this problem, when you need to use objects, from the resource pool to obtain, the resource pool is responsible for maintaining the object's life cycle.

Understanding the resource pool is a good way to understand the thread pool, which is the resource pool where the object type is the thread.

I've added an example of how to create handler in other threads as a choice, the students who have mastered the front can see if you need to implement a message processing mechanism that is similar to the main thread, which requires other threads to communicate with your thread, which can be done in this way.

1. Questions raised

1) Why do I need multi-threading?

2) How is multithreading implemented?

3) What is the core of the multithreading mechanism?

4) How many kinds of implementation are there?

2, problem analysis

1) Why the need for multi-threading is the nature of asynchronous processing, the intuitive point is not to let users feel "very card."

Eg: you click the button to download a song, and then the button has been in the pressed state, then the user experience is poor.

2) Multithreading implementation mode implements Runnable or extends Thread

3) Multithreading core mechanism is handler

4) Provide the following ways of implementation

Handler

———————————— Instructions 1

When creating a handler, be sure to associate an Looper instance, the default constructor handler (), which is the Looper that associates the current thread.

eg

When we create a handler in the UI thread, we associate the looper! of the UI thread at this point

This point can be seen from the source code!

The refinement code is as follows:

Public Handler () {

Mlooper = Looper.mylooper ();

The looper of the current thread, and the UI thread has created the Looper object when activity is created

In the handler mechanism Looper is the most core, it has been in the cyclic reading MessageQueue, has

The message to be processed sends a message to the current handler instance to handle

1 2 3 4
if (Mlooper = = null) {throw new RuntimeException ("Can ' t create handler inside thread that have not called looper.prepare ( )"); }

As can be seen from the above, an handler instance must be associated with a Looper object, otherwise an error

1
Mqueue = Mlooper.mqueue;

Handler's MessageQueue, is it FIFO? No! I think it should be chronological.

Of What is the relationship between message and MessageQueue? Interested can study the source code!

0 S
Mcallback = null; }

You can also specify Looper when creating a handler, at which point the Looper object can be either the current thread or another thread!

Handler just handles the message in the MessageQueue in the Looper it is associated with, as to which thread of Looper,handler is not very concerned!

eg

We created the handler instance in the UI thread, which is then passed into the worker thread's looper, which still allows business operations!

eg

--------------------Creating worker threads

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 All-in-a-. 
private static final class worker implements runnable { private  Static final object mlock = newobject ()  ; private looper mlooper  ; public worker (String name)  { final Thread thread =  Newthread (Null,this,name)  ; thread.setpriority (thread.min_priority)  ; thread.start ()   ; synchronized (MLock)  { while (mlooper == null)  { try { mlock.wait ()  ; } catch (interruptedexception e)  { e.printstacktrace ();  } } }  }  @Override  public void run ()  {synchronized (MLock)  { //The method can only be executed once, A thread can only associate one Looper looper.prepare ()  ;mlooper = looper.mylooper ()  ;  Mlock.notifyall ()  ; } looper.loop ()  ; } public looper getlooper () {  return mlooper ; }&nbsP;public void quit ()  { mlooper.quit ()  ; } } 

We can create a handler looper

Eg:

----------------Define your own handler

in the UI thread

 1 2 3 4 5 6 7 8 9-one-ten-all-in-one-off 
 Private final class myhandler extends handler { private long  id ; public myhandler (Looper looper)  {super (Looper)  ; } @ Override public void handlemessage (message msg)  { switch (msg.what)  {  Case 100 :mtv.settext (" + id")  ; break ; } } } -------- -Create Handler this.mworker = newworker ("Workerthread") in activity  ; this.mMyHandler  = new myhandler (This.mWorker.getLooper ())  ; ---------Create Message final message  msg = this.mmyhandler.obtainmessage (+);  msg.put ("Test"  ,  "test")  ;
  Msg.sendtotarget ()  ; 

It is important to note that each message must have its own target, the handler instance!

The source code is as follows:

1 2 3 4 5 6 7 8 9 10 11
Public final Message Obtainmessage (int.) {return Message.obtain (this, what);} public Staticmessage obtain (Handler H, int what) {message M = obtain (); M.target = h;//you can see that the Message is associated with the current handler m.what = what; return m;}

The above is just a little explanation of the original reason!

1 2
Our usual use of handler is mainly used to deal with multi-threaded asynchronous interaction problems! Since Android requires only the UI thread to update the user interface and accept user buttons and touch events!

Then you must ensure that the UI thread cannot be blocked, and that the time-consuming operation must be opened with a new thread to handle!

So the question is, how will the latest data be fed back to the user after the time-consuming operation is over? While we are currently working on worker threads, it is not possible to make UI updates.

So what do we do? The latest data must be passed to the UI thread to handle! Now send it to handler! But what the hell did handler do? A brief description follows:

The UI thread in which the activity is created is associated with Looper and MessageQueue, and then we create our own handler on the UI line thread, so handler is part of the UI thread, so it can interact with the UI thread!
The looper of the UI thread has been looping MessageQueue read the message that meets the requirements to the target that belongs to it handler to handle! So, we just put the latest data in the worker thread into the MessageQueue of the looper associated with handler, but Looper has been in the loop, and once there is a message that meets the requirements, For the first time, send the message to the message's target, handler, to handle it! So, when we create a message, we should specify its target, which is handler!.
But we can also, new Message ()--> Mhandler.sendmessage (msg); This is a special case!

If we get the message object through the Obtainmessage () method, then handler automatically sets the target of the message. Can see the source code!

The simple point is that:

The UI thread or worker thread provides messagequeue,handler to fill in the Message,looper from which to read the message, and then leave it to the message's own target, the handler to handle!! The handler Handlmessag (Message msg) method that is ultimately subordinate to the UI thread is called!!

This is the most important place for Android multi-threaded asynchronous Processing!!

A little wordy Ah!!

Create handler[General inheritance Handlemessage (Message msg) in the UI thread

|

|

Looper can belong to the UI thread or worker thread

|

|

Messgequeue,looper, which belongs to Looper, has been in the loop () operation, executing msg.target.dispatchMessage (msg) in loop (); Handler Handlemessage ( Message msg)
|

|

Gets the message in the worker thread and then passes through the handler to the MessageQueue

When you create a looper, the-----------------creates a MessageQueue that belongs to the Looper

Private Looper () {

Mqueue = new MessageQueue ();

Mrun = true;

Mthread = Thread.CurrentThread ();

}

----2-----View

Post (Runnable action)

Postdelay (Runnable action, long miliseconds)

-----3-----Activity

Runonuithread (Runnable action)

The implementation of this method is simple:

Public final void Runonuithread (Runnable action) {

if (Thread.CurrentThread ()! = Muithread) {

If the current thread is not a UI thread

Mhandler.post (action);

} else {

Action.run ();

}

}

which

Muithread = Thread.CurrentThread ();

Mhandler = new Handler ()

-----4-----Asynctask

Params,progress,result are data types,

The type of data to be processed by the params

Progress types of processing progress

Result returned after result processing

It is an easy way to process asynchronously!

The order in which the methods are executed:

1)

OnPreExecute ()--executes in the UI thread, doing some initialization operations

2)

Doinbackground (params ... params)-executes in a worker thread, performing time-consuming background processing, in which publishprogress (Progress Progress) can be called for progress processing

3)

Onprogressupdate (Progress Progress)--executes in the UI thread, making progress real-time processing

4) OnPostExecute (result result)--executed in the UI thread, called after Doinbackground (params. Params) is returned

5)

Oncancelled ()--executes in the UI thread, executes after the Asynctask instance calls the Cancle (True) method, and performs some cleanup operations

Some notes:

Asynctask must be created in the UI thread,

Asynctask.execute (params ... params), executed in the UI thread, and executed only once

To call the Execute (params ... params) again, you must recreate the Asynctask object

The latter 3 methods are essentially implemented using handler!

Several multi-threaded implementations in Android

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.