Android只允许UI线程修改UI组件(防止线程冲突)
Handler消息传递机制:解决多线程下其他线程改变界面属性问题
Handler在新线程中发送消息,并在UI线程中接受消息
UI线程主要包括如下:
Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick(),etc
AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel,etc
Mainthread handler: handleMessage(), post*(runnable r), etc
几个重要的方法:
handleMessage(Message msg):用于接受Message以及在主线程中采取相对应的操作
sendEmptyMessage(int what)发送空消息
sendEmptyMessageDelayed(int what,long delayMillis)延迟delayMillis毫秒后发送空消息
sendMessage(Message msg):发送消息
sendMessageDelayed(Message msg,long delayMillis)延迟delayMillis毫秒后发送消息
例子:
public class SecondActivity extends Activity{
TextView testTextView;
private int flag=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
testTextView=(TextView)findViewById(R.id.test_text_view);
final Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what==0x1111){
flag++;
testTextView.setText(String.valueOf(flag));
}
}
};
new Timer().schedule(new TimerTask() {
@Override
public void run() {
mHandler.sendEmptyMessage(0x1111);
}
},0,1000);
}
}
Message:消息对象
Looper:每个线程只允许有一个Looper,负责读取MessageQueue中的消息
MessageQueue:消息队列
Hansler:用于发送和处理消息,其中Message必须送到MessageQueue中,所以当前线程应该要有一
Looper,UI线程中已经自动
初始化好了Looper对象,无需处理;子线程中需要通过Looper的prepare方法创建一个Looper对象,用Loope
的loop()方法启动Looper
不应将费时运算放于UI线程处理,因为可能造成应用无响应:
Android应用无响应判断机制:
按键或者触摸事件在5秒内无响应或者BroadcastReceiver在10秒内无法处理完成或者Service在20秒内无法处理
完成均判断为应用无响应
在非UI线程中创建Handler模拟耗时操作的例子:
public class ThirdActivity extends Activity {
Button threadTest;
HandlerThread handlerThread;
class HandlerThread extends Thread{
public Handler mHandler;
@Override
public void run() {
Looper.prepare();
mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
if (msg.what==0x111){
try {
HandlerThread.sleep(5000);
}catch (Exception e){}
Toast.makeText(ThirdActivity.this,"耗时Thread处理完成!",Toast.LENGTH_LONG).show();
}
}
};
Looper.loop();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
threadTest=(Button)findViewById(R.id.thread_test);
handlerThread=new HandlerThread();
handlerThread.start();
threadTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Message message=new Message();
message.what=0x111;
Bundle bundle=new Bundle();
bundle.putInt("key",message.what);
message.setData(bundle);
handlerThread.mHandler.sendMessage(message);
}
});
}
}