首页 > 代码库 > 第四章 Android开发三大基石—Activity、Service和Handler(6)

第四章 Android开发三大基石—Activity、Service和Handler(6)

4.3 Android线程间的通信—消息机制

在Android程序运行中,线程之间或者线程内部进行信息交互时经常会使用到消息,如果我们熟悉这些基础的东西及其内部原理,将会使我们的Android开发变的更加容易,从而更好地架构系统。下面,就让我们来看看Android中的消息机制到底是怎样一回事吧。

4.3.1消息的传递—Handler的使用

在Android中,线程之间进行信息交互时经常会使用消息,那么,“消息”是在什么时候使用呢?它的工作原理又是怎么样的呢?

在解释这些之前,我们先来看下面这个Activity:

// import略

public class MainActivity extends Activity implements View.OnClickListener { 

     

    private TextView stateText; 

    private Button btn; 

     

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.message); 

        stateText = (TextView) findViewById(R.id.my_text); 

        btn = (Button) findViewById(R.id.my_btn);

        btn.setOnClickListener(this); 

    } 

    @Override 

    public void onClick(View v) { 

        new WorkThread().start(); 

    } 

    // 工作线程 

    private class WorkThread extends Thread { 

        @Override 

        public void run() { 

            // 这里处理比较耗时的操作               

            // 处理完成后改变状态 

            stateText.setText("completed"); 

        } 

    } 

 

在上面这个Activity中,咋一看,挺正常的,一个TextView,一个Button。但是运行后点击按钮马上就会报错:

ERROR/AndroidRuntime(3658): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views

 

--------------------------------------------
试着放个广告 现在没工作 要生存 没办法
平安陆金所 隶属于平安集团的p2p平台
年投资回报率7%-9% 是替代银行理财的首选
个人经验教训 推荐投资安鑫或者有担保的彩虹项目
不要投资安e 那个几乎无法转让 想提前提现非常困难
网站链接 http://affiliate.lufax.com/action/36XBU
首次投资1000元即可额外赚几百元
--------------------------------------------

到底是怎么回事呢?原因在于,Android系统中的视图组件并不是线程安全的,如果要更新视图,必须在主线程中更新,不可以在子线程中执行更新的操作。

既然这样,我们就在子线程中通知主线程,让主线程做更新操作吧。那么,我们如何通知主线程呢?我们需要使用到Handler对象。

我们稍微修改一下上面的代码:

// import略

public class MainActivity extends Activity implements View.OnClickListener { 

     

    private TextView stateText; 

private Button btn; 

 

private static final int COMPLETED = 1;

 

    private Handler handler = new Handler() { 

        @Override 

        public void handleMessage(Message msg) { 

            if (msg.what == COMPLETED) { 

                stateText.setText("completed"); 

            } 

        } 

};   

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        setContentView(R.layout.message); 

        stateText = (TextView) findViewById(R.id.my_text); 

        btn = (Button) findViewById(R.id.my_btn); 

        btn.setOnClickListener(this); 

    } 

    @Override 

    public void onClick(View v) { 

        new WorkThread().start(); 

    } 

    // 工作线程 

    private class WorkThread extends Thread { 

        @Override 

        public void run() { 

            // 这里处理比较耗时的操作               

        Message msg = new Message(); 

            msg.what = COMPLETED; 

            handler.sendMessage(msg);

        } 

    } 

}

 

通过上面这种方式,我们就可以解决线程安全的问题,把复杂的任务处理工作交给子线程去完成,然后子线程通过Handler对象告知主线程,由主线程更新视图,这个过程中消息机制起着重要的作用。

第四章 Android开发三大基石—Activity、Service和Handler(6)