您的位置:首页 > 移动开发 > Android开发

Android运行在主线程和子线程浅释

2016-09-27 18:14 225 查看
//new子线程的HandlerThread
private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
sWorkerThread.start();
}
private static final Handler sWorker = new Handler(sWorkerThread.getLooper());

//运行在主线程
private void runOnMainThread(Runnable r, int type) {
if (sWorkerThread.getThreadId() == Process.myTid()) {
// If we are on the worker thread, post onto the main handler
mHandler.post(r);
} else {
r.run();
}
}
//运行在工作线程
public static void runOnWorkerThread(Runnable r) {
if (sWorkerThread.getThreadId() == Process.myTid()) {
r.run();
} else {
// If we are not on the worker thread, then post to the worker handler
sWorker.post(r);
}
}


new一个主线程的Handler将当前runnable运行在主线程,只要mHandler.post就可以了。比如更新ui就可以直接搞了。

public static class PipelineThreadHandler extends Handler }
mHandler=new PipelineThreadHandler();


系统复用同一个handler 运行在主线程

public class PipelineThread extends Thread {
private static final String LOG_TAG = "PipelineThread";
private static final String THREAD_NAME_PREFIX = "Pipeline-";

private static PipelineThread sInstance;

private Handler mHandler;

public PipelineThread() {
super();
setName(THREAD_NAME_PREFIX + getName());
}

public PipelineThread(String name) {
super();
setName(THREAD_NAME_PREFIX + name);
}

public void run() {
try {
// preparing a looper on current thread
// the current thread is being detected implicitly
Looper.prepare();

// now, the handler will automatically bind to the
// Looper that is attached to the current thread
// You don't need to specify the Looper explicitly
synchronized (this) {
mHandler = new PipelineThreadHandler();
this.notifyAll();
}

// After the following line the thread will start
// running the message loop and will not normally
// exit the loop unless a problem happens or you
// quit() the looper (see below)
Looper.loop();
} catch (Throwable t) {
Log.e(LOG_TAG, "halted due to an error", t);
}
}

/**
* Gets the instance of handler. This method should only be invoked after the Pipeline thread
* has been started. If this method is invoked before the Pipeline thread has been started, it will throw
* the PipelineThreadException.
*
* @return
*/
public Handler getHandler()
throws PipelineThreadException {
synchronized (this) {
if (this.getState() == Thread.State.NEW) {
throw new PipelineThreadException("Pipeline thread " + this.getName() + " not started.");
}

if (mHandler == null) {
try {
Log.d(LOG_TAG, "Going to wait for handler to be initialized.");
this.wait();
Log.d(LOG_TAG, "Wait over. Handler is " + mHandler);
} catch (InterruptedException e) {
Log.e(LOG_TAG, e.getMessage(), e);
}
}
}

return mHandler;
}

public static synchronized final PipelineThread getInstance() {
if (sInstance == null) {
sInstance = new PipelineThread();
sInstance.start();
}

return sInstance;
}

public static class PipelineThreadHandler extends Handler {

}
}
//外部调用采用PipelineThread.getInstance().getHandler()


两个经典的对比主线程和子线程

handler = new Handler(new Handler.Callback() {
//....
Thread.currentThread().getId()); //这里拿到的线程id和主线程是一样的
}

HandlerThread ht = new HandlerThread("MyThread");
ht.start();
Log.d(TAG,"=========>" + ht.getId());  //这里拿到的就是子线程id和主线程不一样
handler = new Handler(ht.getLooper(), new Handler.Callback() {
//...
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 线程 Hanlder