Android 切换线程的方式[我常用的]
1. Handler.post[切换至主线程]
2. new Thread().start()[切换至子线程]
3. 线程池 ThreadPoolExecutor.execute()[切换至子线程]
4. runOnUiThread[切换至主线程]
然后写代码看一下他们之间的执行关系[代码中一看就清晰了]
package calldead.redwolf.threaddemo;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 思考各种切线程方式之间的主从关系
*/
public class MainActivity extends AppCompatActivity {
private String TAG = "RedWolfChao";
// 线程池 1
private ThreadPoolExecutor mThreadPoolExecutor =
new ThreadPoolExecutor(3, 5, 1,
TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(100));
// Handler
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
execThread();
}
private void execThread() {
// 直接执行[主线程]
Log.i(TAG, "[Name] = " + Thread.currentThread().getName() + " [ID] = " + Thread.currentThread().getId());
// new Thread[子线程]
new Thread(new Runnable() {
@Override
public void run() {
Log.i(TAG, "newThread [Name] = " + Thread.currentThread().getName() + " [ID] = " + Thread.currentThread().getId());
runOnUiThread(new Runnable() {
@Override
public void run() {
// 子线程中runOnUiThread [主线程]
Log.i(TAG, "newThread_runOnUi [Name] = " + Thread.currentThread().getName() + " [ID] = " + Thread.currentThread().getId());
}
});
}
}).start();
// 线程池执行 [子线程]
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.i(TAG, "ThreadPoolExecutor [Name] = " + Thread.currentThread().getName() + " [ID] = " + Thread.currentThread().getId());
// 线程池runOnUi [主线程]
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i(TAG, "ThreadPoolExecutor_runOnUi [Name] = " + Thread.currentThread().getName() + " [ID] = " + Thread.currentThread().getId());
}
});
}
};
mThreadPoolExecutor.execute(runnable);
// 直接runOnUi 没啥意义 读源码就知道了 [主线程]
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.i(TAG, "runOnUi [Name] = " + Thread.currentThread().getName() + " [ID] = " + Thread.currentThread().getId());
}
});
//
mHandler.post(new Runnable() {
@Override
public void run() {
Log.i(TAG, "mHandler.post [Name] = " + Thread.currentThread().getName() + " [ID] = " + Thread.currentThread().getId());
}
});
}
}
日志打印如下 ;
01-11 14:04:10.826 12804-12804/calldead.redwolf.threaddemo I/RedWolfChao: [Name] = main [ID] = 1
01-11 14:04:10.826 12804-12804/calldead.redwolf.threaddemo I/RedWolfChao: runOnUi [Name] = main [ID] = 1
01-11 14:04:10.830 12804-12829/calldead.redwolf.threaddemo I/RedWolfChao: ThreadPoolExecutor [Name] = pool-1-thread-1 [ID] = 208
01-11 14:04:10.833 12804-12828/calldead.redwolf.threaddemo I/RedWolfChao: newThread [Name] = Thread-207 [ID] = 207
01-11 14:04:10.850 12804-12804/calldead.redwolf.threaddemo I/RedWolfChao: mHandler.post [Name] = main [ID] = 1
01-11 14:04:10.850 12804-12804/calldead.redwolf.threaddemo I/RedWolfChao: ThreadPoolExecutor_runOnUi [Name] = main [ID] = 1
01-11 14:04:10.850 12804-12804/calldead.redwolf.threaddemo I/RedWolfChao: newThread_runOnUi [Name] = main [ID] = 1
结论 :
-
主线程[UI]只有一个
-
其它子线程可以有任意个
如图 :
附带runOnUiThread源码 :
注释翻译 :
在UI线程上运行指定的操作。如果当前线程是ui-hread,则立即执行该操作。如果当前线程不是UI线程,则该操作将发布到UI线程的事件队列。