因为考虑效率的原因,android中的控件都是线程不安全的,
所以为了防止出现不安全的情况,google规定在能在UI线程中进行UI控件的操作。
因此不能在非主线程中进行UI操作
这个时候,主线程和子线程中的通信就显得很重要了。
接下来就从两个方面开始介绍
从子线程到主线程
从主线程到子线程
现在开始介绍从子线程到主线程的几种方式
1、Handler.sendXXXMessage()等方法
首先在页面创建一个Handler的匿名内部类(os包下的)
重写handleMessage方法
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0x001:
break;
case 0x002:
break;
}
}
};
然后在子线程里调用mHandler.sendEmptyMessage()方法
这里讲两个关键点
Message:
* 1、what属性,用于标示该Message是从哪个子线程发送过来的
* 2、如果只需要传一些简单的数据类型(int),则可以使用Message中的arg1、arg2属性,如果要传一个对象,则可以使用obj属性
* 如果是复杂的数据,则需要通过Bundle
* 3、Message的创建,通常我们都不通过new Message的方式创建Message,
* 出于效率考虑应该使用Message.obtain() 或者 handler.obtainMessage()方式创建Message
* 这两个方法运行机制,如果发现Handler中已经存在了Message对象,则直接拿过来使用,否则创建新的Message对象
handler发送消息的方式:
* sendMessage(Message):发送一个消息对象
* sendEmptyMessage(0x003):当子线程只需要给主线程发送一个通知标示时使用,不需要传递任何数据,参数是what标识符
* sendMessageDelayed(Message, long) 和 sendEmptyMessageDelayed():标示延迟long毫秒以后,发送Message消息
* sendMessageAtTime(Message, long) 和 sendEmptyMessageAtTime():在指定时间发送Message
2、Handler.post方法
主线程只需要创建Handler对象,无需再重写handleMessage方法
在子线程中获得handler对象,通过post方法进行消息的传递,
其中包含一个Runnable的参数,Runnable中的run方法,在主线程中执行
* post(Runnable):
* postDelayed(Runnable, long):延迟发送
* postAtTime():指定固定时间发送
3、Activity.runOnUIThread(Runnable)
这个是Activity里自带的方法,不用Handler了
4、View.post(Runnable)
和第三种有点像,只不过换成了控件的方法
5、AsyncTask
在doInBackground(Params…) 方法里执行耗时逻辑,然后在onPostExecute(Result) 中将结果更新回UI组件。
现在开始讲从主线程到子线程的几种方式
1、Thread、Runnable
最常用的,创建一个新的线程
2、HandlerThread
这个我不是很了解,暂时放在这里,留着以后补充
3、AsyncTask
4、IntentService
这个是一个特殊的服务,服务执行完成后会自动停止
总结:关于多线程编程,主要在于根据不同的需求去修改自己的代码
在不同的线程来回切换间容易出错,同时也要注意内存泄漏等相关问题