Pro Android学习笔记(九十):了解Handler(4):Worker线程

文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处:http://blog.csdn.net/flowingflying/

对于时间较长处理一般不放在UI线程(即主线程)中,避免出现ANR的现象,我们会另启一个线程,利用handler进行子线程和主线程之间的通信,实现子线程触发UI操作。这种类型的子线程通常称为worker thread。具体实现步骤如下:

1、在主线程创建Handler对象;

2、创建一个线程(即worker线程),将Handler对象传递给该线程;

3、运行线程,如果需要进行UI的操作,通过handler将message加入到主线程的队列中。message实际成为worker线程和主线程的通信桥梁;

4、主线程处理message。

worker线程小例子

小例子很简单,如图。点击菜单,触发处理(1、UI提示开始,2、sleep 10秒,3、UI提示结束),由于处理时间很长,为了避免ANR的情况,该处理将在线程中运行。

Pro Android学习笔记(九十):了解Handler(4):Worker线程_第1张图片

小例子代码:worker线程通过handler实现与主线程的通信

根据对象编程从上之下的设计思想,我们看看主线程中如何启动子线程,并将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();
       }
    } 
    ... ...
}

小例子代码:继承Handler代码

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

/* 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开发相关文章

你可能感兴趣的:(Pro Android学习笔记(九十):了解Handler(4):Worker线程)