文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处:http://blog.csdn.net/flowingflying/android
对于时间较长处理通常不放在UI线程(即主线程)中,避免出现ANR的现象,咱们会另启一个线程,利用handler进行子线程和主线程之间的通讯,实现子线程触发UI操做。这种类型的子线程一般称为worker thread。具体实现步骤以下:编程
一、在主线程建立Handler对象;ide
二、建立一个线程(即worker线程),将Handler对象传递给该线程;函数
三、运行线程,若是须要进行UI的操做,经过handler将message加入到主线程的队列中。message实际成为worker线程和主线程的通讯桥梁;学习
四、主线程处理message。this
小例子很简单,如图。点击菜单,触发处理(一、UI提示开始,二、sleep 10秒,三、UI提示结束),因为处理时间很长,为了不ANR的状况,该处理将在线程中运行。.net
根据对象编程从上之下的设计思想,咱们看看主线程中如何启动子线程,并将handler的对象传递到线程中。后面在补上相关的Handler集成和子线程的执行Runnable的实现。线程
public class MainActivity extends Activity {
... ...
@Override //点击菜单触发子线程
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if( id == R.id.menu_worker_thread){
testWorkerThread();
return true;
}
return super.onOptionsItemSelected(item);
}
private Handler reportHandler = null;
private Thread workerThread = null;
private void testWorkerThread(){
//【1】在主线程建立Handler对象
if(reportHandler == null){
reportHandler = new ReportStatusHandler(this);
}
//将handler传递至建立的线程,并开启线程
if(workerThread!= null && workerThread.getState() != Thread.State.TERMINATED){
showinfo("Thread is new or alive, but not terminated"); //在Logcat和textview中显示信息
}else{
showinfo("Old thread existed and terminated, create an new one");
workerThread = new Thread( new WorkerThreadRunnable(reportHandler) );
workerThread.start();
}
}
... ...
}设计
ReportStatusHandler集成Handler,根据message的内容进行相应的UI处理,和以前的学习没有什么差异。
public class ReportStatusHandler extends Handler{
private MainActivity parentActivity = null;
public static final String DATA_MESSAGE="cn.flowingflying.proandroid.testhandler.message";
public ReportStatusHandler(MainActivity activity){
parentActivity = activity;
}
@Override //【4】根据message的内容进行相应的UI处理,UI处理将在UI线程,即主线程中进行,所以ReportStatusHandler对象也应在主线程中建立。
public void handleMessage(Message msg) {
Bundle b = msg.getData();
String s = b.getString(DATA_MESSAGE);
// 在此进行UI操做,包括textview的和Toast的处理
…… UI处理
}
}
/* Runnable这是java中对线程执行内容的具体实现 */
public class WorkerThreadRunnable implements Runnable{
Handler handler = null; //记录在主线程建立的handler参考
//【2】在构建函数中将主线程的handler传递过来
public WorkerThreadRunnable(Handler h){
handler = h;
}
@Override //子线程的执行内容,本例用sleep来进行模拟,在sleep的开始和结束子线程须要与UI线程互动,实际上咱们还能够每sleep一秒就触发一次互动。
public void run() {
informUi("WorkerThread is start running...");
for(int i = 0; i < 10; i ++){
try{
Thread.sleep(1000);
… … // Tell Ui thread to do something here ,for example informUi(…….);
}catch(Exception e){
Log.e("WorkerThreadRunnable",e.toString());
}
}
informUi("WorkerThread is finished...");
}
//【3】经过handler消息将message放入主线程的队列,实现子线程和主线程的通讯
private void informUi(String s){
Message msg = handler.obtainMessage();
Bundle b = new Bundle();
b.putString(ReportStatusHandler.DATA_MESSAGE, s);
msg.setData(b);
handler.sendMessage(msg);
}
}
相关小例子源代码可在Pro Android学习:了解Handler小例子中下载。
相关连接: 个人Android开发相关文章