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); } }); } }