Android: Background thread pool and UiThread thread pool, androiduithread
Origin
You can specify the Thread pool where Runnable execution is executed in any part of the Code, whether called in the Ui Thread or in the Thread.
Codes
package com.example.androidbackgroundexecuter;import java.util.concurrent.Executor;import android.os.Handler;import android.os.HandlerThread;import android.os.Looper;import android.os.MessageQueue;/** * * @author Zheng Haibo * @Web http://www.mobctrl.net * */public final class GlobalExecutor implements Executor { static final String APP_EXECUTOR = "APP_EXECUTER"; private final Handler mainHandler; private final Handler backgroundHandler; public GlobalExecutor() { if (!isOnMainThread()) { throw new IllegalStateException( "Error!Please init the Executor in the main thread..."); } mainHandler = new Handler(Looper.getMainLooper()); HandlerThread handlerThread = new HandlerThread(APP_EXECUTOR); handlerThread.start(); backgroundHandler = new Handler(handlerThread.getLooper()); } @Override public void execute(final Runnable command) { executeInBackground(command, 0); } /** * execute the command in background thread with a delay of {@link #delay} * * @param command */ public void execute(final Runnable command, int delay) { executeInBackground(command, delay); } /** * execute the command in UiThread * * @param command */ public void executeInUiThread(final Runnable command) { mainHandler.post(command); } /** * execute the command in main thread with a delay of {@link #delay} * * @param command */ public void executeInUiThread(final Runnable command, int delay) { mainHandler.postDelayed(command, delay); } /** * execute the command in background thread with a delay of {@link #delay} * * @param command */ public void executeInBackground(final Runnable command, final int delay) { if (isOnMainThread()) { executeDelayedAfterIdleUnsafe(command, delay); } else { mainHandler.post(new Runnable() { @Override public void run() { executeDelayedAfterIdleUnsafe(command, delay); } }); } } /** * execute the command in background thread * * @param command */ public void executeInBackground(final Runnable command) { executeInBackground(command, 0); } private boolean isOnMainThread() { return Looper.getMainLooper().getThread() == Thread.currentThread(); } private void executeDelayedAfterIdleUnsafe(final Runnable task, final int delay) { Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { backgroundHandler.postDelayed(task, delay); return false; } }); }}
Note that new GlobalExecutor () is required in the main thread.
Example
package com.example.androidbackgroundexecuter;import android.app.Activity;import android.graphics.Color;import android.os.Bundle;import android.os.Process;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity { private GlobalExecutor mGlobalExecutor = null; private Button btn1; private Button btn2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGlobalExecutor = new GlobalExecutor(); btn1 = (Button) findViewById(R.id.btn_1); btn1.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { System.out.println("debug:btn 1 click"); btn1.setBackgroundColor(Color.BLACK); mGlobalExecutor.execute(new Runnable() { @Override public void run() { System.out.println("debug:click1 execute tid = " + Process.myTid() + ",pid=" + Process.myPid()); } }); mGlobalExecutor.executeInUiThread(new Runnable() { @Override public void run() { System.out .println("debug: click1 executeInUiThread tid = " + Process.myTid() + ",pid=" + Process.myPid()); } }); } }); btn2 = (Button) findViewById(R.id.btn_2); btn2.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { System.out.println("debug:btn 2 click"); new Thread(new Runnable() { @Override public void run() { System.out.println("debug: click2(run) tid = " + Process.myTid() + ",pid=" + Process.myPid()); mGlobalExecutor.execute(new Runnable() { @Override public void run() { System.out .println("debug: click2 run execute in thread- tid = " + Process.myTid() + ",pid=" + Process.myPid()); } }); mGlobalExecutor .executeInUiThread(new Runnable() { @Override public void run() { System.out .println("debug: click2 run execute in UiThread- tid = " + Process.myTid() + ",pid=" + Process.myPid()); btn1.setBackgroundColor(Color.RED); } }); } }).start(); } }); }}
Print
Click the buttons btn1 and btn2 one after another. The logs are as follows:
05-20 10:25:49.045: I/System.out(3144): debug:btn 1 click05-20 10:25:49.115: I/System.out(3144): debug: click1 executeInUiThread tid = 3144,pid=314405-20 10:25:49.125: I/System.out(3144): debug:click1 execute tid = 3157,pid=314405-20 10:25:50.105: I/System.out(3144): debug:btn 2 click05-20 10:25:50.105: I/System.out(3144): debug: click2(run) tid = 3582,pid=314405-20 10:25:50.145: I/System.out(3144): debug: click2 run execute in UiThread- tid = 3144,pid=314405-20 10:25:50.175: I/System.out(3144): debug: click2 run execute in thread- tid = 3157,pid=3144
Advantages
We can call the Runnable we want to execute in any thread, which is very convenient.
More communication
Android Development Alliance QQ group: 272209595