Reprinted the multi-thread usage of Android multi-thread processing, large collection of android

Source: Internet
Author: User

Reprinted the multi-thread usage of Android multi-thread processing, large collection of android

Handler. post (r) does not actually start a new thread, but the run () method in runnable is not executed, so runnable still runs the UI thread.

1. If it is like this, you can operate the ui, but run is still in the main thread. See that the printed Log thread name is main, which indicates that it is the main thread.

This is why the ui can be operated directly in the run method, because it is essentially a ui thread.

Handler. post (new Runnable () {public void run () {Log. e ("current Thread:", Thread. currsponthread. getName (); // print the de result here as main setTitle ("Haha ");}});

 

 

2. the logoff obtained through HandlerThread can start a new thread, but it is impossible to operate the ui in the run method here, but this obviously has a disadvantage. If you execute post (r) multiple times) the method actually follows the HandlerThread thread. If you execute five or n times, it is actually one time and they are serialized. If you download 5 images, you will see the first one.

Practice has proved that only handler with the master thread logoff can operate the ui, while the ui can be operated in the handlerMessage () method of the handler, you can also operate the Ui in The post (r) run method of handler.

When sending a heartbeat packet or an infinite number of consecutive requests to an interface, you can use this HandlerThread to ensure that continuous requests can be completed with one thread.

HandlerThread ht = new HandlerThread ("handler thread"); ht. start (); handler = new Handler (ht. getLooper (); handler. post (new Runnable () {// here the run () method is still waiting for ht. start () calls public void run () {Log. e ("current Thread:", Thread. currsponthread. getName (); // The printed content here is handler thread setTitle ("Haha"); // an error will be returned // android. view. viewRoot $ CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views .}});

Private Runnable mGetTimeRunnable = new Runnable (){

 

@ Override
Public void run (){
Json = HttpUtils. getHttpText (Configs. getServerAddress (mContext ));
Log ("currentThread" + Thread. currentThread (). getName ());

}
};

 

 

In this case, you can build a handler without parameters. Use the handler to send and process messages, and use the handler to start a new thread.

MainHandler = new Handler () {protecket void handlerMessage (Message msg) {setTitle ("Haha"); // No error will be reported} handler. post (new Runnable () {// here the run () method is still waiting for ht. start () calls public void run () {Log. e ("current Thread:", Thread. currsponthread. getName (); // The printed content here is handler thread mainHandler. sendEmpetMessage (); // use mainHandler to send a message // setTitle ("Haha"); // an error is returned // android. view. viewRoot $ CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views .}});

 

Print Log:

3. In fact, the 2nd methods are troublesome and inefficient. Two handler is used, one for initiating a thread and the other for processing messages. The handler of the initiating thread must have logoff, so a HanderThread must be instantiated. the handler that processes messages does not need logoff because it has the Logoff of the main thread by default, so you can process the ui in this handler.

In fact, you only need to instantiate a handler, build a handler without parameters in the main thread, and then send and process messages by it. Instead of handler, the job that creates a Thread directly uses new Thread (r). start (); then it processes logical transactions in the run () method of r.

If you download five images in this mode, you may not see one picture as it is displayed. Maybe 2nd images are displayed first or three images at the same time. The five threads are random.

Private void loadImagesByThread (final String url, final int id) {// multiple threads are created through Thread new Thread (new Runnable () {@ Override public void run () {// TODO Auto-generated method stub Log. e ("current Thread:", "" + Thread. currentThread (). getName (); Drawable drawable = null; try {drawable = Drawable. createFromStream (new URL (url ). openStream (), "image.gif");} catch (MalformedURLException e) {// TODO Auto-generated catch block e. printStackTrace ();} catch (IOException e) {// TODO Auto-generated catch block e. printStackTrace ();} Message msg = mainHandler. obtainMessage (); msg. what = 2012; msg. arg1 = id; msg. obj = drawable; msg. sendToTarget ();}}). start ();}

 

Print Log:

4. AsyncTask

The asynchronous task architecture multi-task model is not very robust. You need to create multiple AsyncTask instances. An AsyncTask is executed only once and cannot be executed repeatedly. A fast-food thread is used up once.

Implement AsyncTask subclass. The most important two methods are doInBackground (params) and onPostExecute (result ). Process time-consuming transactions in the doInBackground () method, return the result, and return the value in the onPostExecute method as the parameter. Then, you can display the result on the ui in onPostExecute.

Steps:

① Instantiate AsyncTask:

After the asynctaskdown function is completed, the task.exe c (pamas) is passed in. The parameter list is dynamic and can be either one or multiple parameters with a variable length.

AsyncTask <params, values, reslut>. The first parameter is passed in to doInBackground (params). The second parameter is the value of data update, and the third parameter is the result returned by the transaction.

② OnPreExecute method:

This method has no parameters or return values. You can make some reminders in this method. For example, show a Dialog or play a Toast to tell the user to start downloading.

 

③ DoInBackground (params) method:

Enter the internal structure of AsyncTask. First, the reslut doInBackground (params) method will be executed. This method will process time-consuming transactions. The exec () parameter will be passed into this method for parameters, the returned value will be used as the onPostExecute () parameter. To update the progress, run the publicProgress () method.

 

④ OnProgressUpdate (values) method:

The parameter of this method must execute the publicProgress () method in the doInBackground () method. This method will pass the parameter to the onProgressUpdate () method, then, you can update and display the ui in this method. For example, the value of the progress bar can be dynamically changed through this values value.

⑤ OnPostExecute (result) method:

Here is the way the transaction is processed. The result of the doInBackground method execution will be passed here if the method returns data. In this method, you can process the Ui and display the processed data on the ui. Comparison, text, and all the results you want.

Private void loadImageByAsyncTask (final String url, final int id) {// construct an asynchronous task so that no handler is needed to process the message DownloadTask task = new DownloadTask (); task.exe cute ("" + id, url); // AsyncTask cannot be executed repeatedly} class DownloadTask extends AsyncTask <String, Integer, Drawable> {int id; @ Override protected Drawable doInBackground (String... params) {// params stores the url and Control id data. // TODO Auto-generated method stub Log. e ("current Thread:", "" + Thread. currentThread (). getName (); Drawable drawable = null; this. id = Integer. parseInt (params [0]); try {drawable = Drawable. createFromStream (new URL (params [1]). openStream (), "image.gif");} catch (MalformedURLException e) {// TODO Auto-generated catch block e. printStackTrace ();} catch (IOException e) {// TODO Auto-generated catch block e. printStackTrace ();} return drawable;} @ Override protected void onPostExecute (Drawable result) {// TODO Auto-generated method stub super. onPostExecute (result); (ImageView) MainActivity. this. findViewById (id )). setImageDrawable (result) ;}@ Override protected void onPreExecute () {// TODO Auto-generated method stub super. onPreExecute () ;}@ Override protected void onProgressUpdate (Integer... values) {// TODO Auto-generated method stub super. onProgressUpdate (values );}}

 

 

Log printed here

 

5. ExecutorServie Thread Pool

It is created through the static method of Executors. There are generally three types:

1. Single thread: Executors. newSingleThreadExecutor ();

2. Fixed Number of threads: Executors. newFixedThreadPool (5 );

3. Dynamic thread: Executors. newCachedThreadPool ();

Here we use five fixed threads for application. The method is to create an ExecutorService object, and then execute submit (r) to initiate a Runnable object. The advantage of using a thread pool for management is that it can ensure the stable operation of the system, and can be used in scenarios with a large number of threads and a high workload, if you want to display 1000 images, If you create 1000 threads for loading, the system will die. This problem can be avoided by using the thread pool. Five threads can be used in turn for execution, and five threads are in one group. After the execution, the threads are not directly recycled, but waiting for the next execution, in this way, the system overhead can be reduced a lot.

Private void loadImagesByExecutors (final String url, final int id) {service. submit (new Runnable () {@ Override public void run () {// TODO Auto-generated method stub Log. e ("current Thread:", "" + Thread. currentThread (). getName (); try {final Drawable drawable = Drawable. createFromStream (new URL (url ). openStream (), "image.gif"); mainHandler. post (new Runnable () {@ Override public void run () {// This will run in the main thread // TODO Auto-generated method stub (ImageView) MainActivity. this. findViewById (id )). setImageDrawable (drawable) ;}});} catch (MalformedURLException e) {// TODO Auto-generated catch block e. printStackTrace ();} catch (IOException e) {// TODO Auto-generated catch block e. printStackTrace ();}}});}

 

 

Log:

 

In fact, it may not be clear that the first method is not multithreading.

1. loadImagesByHandler () uses the Handler. post () method to construct two Handler for communication.

2. loadImagesByThread (). This is the new Thread () Initiating Thread that processes messages in the handler of the main Thread.

3. loadImageByAsyncTask (), which uses asynchronous tasks. All implementations can operate the Ui in its internal structure.

4. loadImagesByExecutors () uses a thread pool to make the thread controllable and ensure stable operation.

In fact, the last three methods are commonly used. The second method is flexible and simple, but not suitable for a large number of tasks. The third method is generally applicable to a single task and a one-time task. The fourth method is generally used for a large number of tasks, scenarios for high-density execution, such as loading images in batches and downloading files in batches.

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.