android:Background线程池和UiThread线程池
由来
希望在代码的任何地方,无论是在Ui线程中调用,还是Thread中调用,都能指定Runnable执行的所在的线程池。
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;
}
});
}
}
注意,new GlobalExecutor()是需要在主线程。
使用举例
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();
}
});
}
}
相继点击按钮btn1和btn2,日志如下:
05-20 10:25:49.045: I/System.out(3144): debug:btn 1 click
05-20 10:25:49.115: I/System.out(3144): debug: click1 executeInUiThread tid = 3144,pid=3144
05-20 10:25:49.125: I/System.out(3144): debug:click1 execute tid = 3157,pid=3144
05-20 10:25:50.105: I/System.out(3144): debug:btn 2 click
05-20 10:25:50.105: I/System.out(3144): debug: click2(run) tid = 3582,pid=3144
05-20 10:25:50.145: I/System.out(3144): debug: click2 run execute in UiThread- tid = 3144,pid=3144
05-20 10:25:50.175: I/System.out(3144): debug: click2 run execute in thread- tid = 3157,pid=3144
优点
我们可以在任意线程中调用我们想执行的Runnable,非常方便。
更多交流
Android开发联盟QQ群:272209595
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。