1.线程
1.我们知道Android中的所有组件都是运行在UI线程中的,因为Android中的UI控件是线程不安全的,所以不能再子线程中操作UI控件。
2.Android的另一特性就是UI线程(主线程)不能执行耗时操作,容易阻塞UI线程,UI线程被阻塞5秒钟,就会报ANR(Application not response),所以所有耗时操作,都应在子线程(工作线程中进行)。
由上可知:我们UI线程经常需要数据来更新界面展示,而数据的来源很多事从网络获取或者本地数据库,或者文件读写操作,而这些操作都是耗时操作必须放在子线程中进行。
所以,如何将工作线程中获取的数据通知到主线程中用以View的更新,就是Android中的一个问题。
Android 系统自带UI线程和非UI线程交互方式(三种):
1.runOnUiThread(Runnable runnable)方法
View.post(Runnable runnable);
View.postDelayed(Runnable runnable ,long long);
runOnUiThread(new Runnable() { @Override public void run() { // 可以做一些UI控件的视图的更新操作,该方法默认实现已经在主线程当中 } });
new Thread(new Runnable(){ @Override public void run() { imageView.post(new Runnable(){ @Override public void run() { // 也是运行在UI线程 imageView.setImageResource(R.id.login); } }); } }).start();
2.AsyncTask Android系统自身实现的简单的异步网络框架AsyncTask<String, Void, byte[]> asyncTask = new AsyncTask<String, Void, byte[]>() { @Override protected void onPreExecute() { super.onPreExecute(); // 主线程中,执行后台线程之前先回调此方法。可以做一些准备工作 } @Override protected byte[] doInBackground(String... params) { return new byte[0]; // 子线程中,params } @Override protected void onPostExecute(byte[] bytes) { super.onPostExecute(bytes); // 默认在主线程中,bytes 为后台线程执行的结果 } }; asyncTask.execute("传入后台线程的参数,即为doInBackground(params)的参数,类型和构造方法中泛型相对应。");
3.Handler/ Message /MessageQueue /Looper /Thread 消息机制 (开发中用的最多)
1.值得一提的是Handler永远是和MessageQueue 绑定的,无论它的创建位置是在主线程还是在子线程。Android 的UI线程(主线程)默认实现了一个MessageQueue,但是
WorkThread(子线程)中默认是没有实现MessageQueue的,所以我们要将Handler 对象和子线程中的MessageQueue相互绑定关联,就必须先为改子线程建立消息循环。
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.execute(new Runnable() {
@Override
public void run() {
/* private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}*/
Looper.prepare();//建立消息循环 :Looper构造里有构造MessageQueue 和只有当前线程。并将其赋值给Looper的 mQueue ,mThread的成员
Handler handler = new Handler(Looper.myLooper()) { // Handler 的构造是将当前的handler和当前线程中的MessageQueue ,Looper关联起来,
//Looper.myLooper(),获得当前线程的Looper,默认的空构造中也有该段代码,
// 如果是new Handler(getMainLooper())就是将handler和主线程的MessageQueue相互绑定。
// Handler中有一个成员mLooper,就是构造的时候传递进去的,空构造默认是Looper.myLooper()
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
Looper.loop();// 开启消息队列循环
}
});