Android筆記(三十二) Android中線程之間的通訊(四)主線程給子線程發送訊息

來源:互聯網
上載者:User

標籤:

         之前的例子都是我們在子線程(WorkerThread)當中處理並發送訊息,然後在主線程(UI線程)中擷取訊息並修改UI,那麼可以不可以在由主線程發送訊息,子線程接收呢?我們按照之前的思路寫一下代碼:

package cn.lixyz.handlertest;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Button;public class MainActivity extends Activity {    private Button button;    private Handler handler;    private int i = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.d("TTTT", "onClick:" + Thread.currentThread().getName());                Message msg = handler.obtainMessage();                handler.sendMessage(msg);            }        });        WorkerThread wt = new WorkerThread();        wt.start();    }    class WorkerThread extends Thread {        @Override        public void run() {            super.run();            handler = new Handler() {                @Override                public void handleMessage(Message msg) {                    super.handleMessage(msg);                    Log.d("TTTT", "收到了訊息對象");                }            };        }    }}
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:layout_marginTop="30dp"        android:text="Send Message" /></LinearLayout>
activity_main.xml

         上面的問題貌似沒什麼錯誤,但運行時卻出錯

         拋出異常:

09-17 04:01:31.655  15854-15869/? E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-120    Process: cn.lixyz.handlertest, PID: 15854    java.lang.RuntimeException: Can‘t create handler inside thread that has not called Looper.prepare()            at android.os.Handler.<init>(Handler.java:200)            at android.os.Handler.<init>(Handler.java:114)            at cn.lixyz.handlertest.MainActivity$WorkerThread$1.<init>(MainActivity.java:48)            at cn.lixyz.handlertest.MainActivity$WorkerThread.run(MainActivity.java:48)

  

         提示我們沒有調用Looper.prepare(),無法建立線程,原因是非主線程中預設是沒有建立Looper對象的,需要先調用Looper.prepare()啟用Looper。修改一下上面的代碼。

package cn.lixyz.handlertest;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;import android.view.View;import android.widget.Button;public class MainActivity extends Activity {    private Button button;    private Handler handler;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Message msg = handler.obtainMessage();                msg.what = 100;                handler.sendMessage(msg);                Log.d("TTTT", "sendMessage:" + Thread.currentThread().getName());            }        });        WorkerThread wt = new WorkerThread();        wt.start();    }    class WorkerThread extends Thread {        @Override        public void run() {            super.run();            Looper.prepare();            handler = new Handler() {                @Override                public void handleMessage(Message msg) {                    super.handleMessage(msg);                    Log.d("TTTT", "handleMessage:" + Thread.currentThread().getName());                    int i = msg.what;                    Log.d("TTTT", "收到了訊息對象:" + i);                }            };            Looper.loop();        }    }}
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:layout_marginTop="30dp"        android:text="Send Message" /></LinearLayout>
activity_main.xml

         運行結果:

09-17 04:29:48.669  28397-28397/cn.lixyz.handlertest D/TTTT﹕ sendMessage:main09-17 04:29:48.669  28397-28410/cn.lixyz.handlertest D/TTTT﹕ handleMessage:Thread-14109-17 04:29:48.669  28397-28410/cn.lixyz.handlertest D/TTTT﹕ 收到了訊息對象:100

         上面代碼錶示,訊息是從MainThread發送的,WorkerThread接收到了訊息。

         PS:非UI線程預設是沒有建立Looper對象的,所以需要主線程向子線程傳遞訊息時,需建立Looper對象並啟動迴圈,子線程才可以迴圈著從MaessageQueue中取出訊息。  

          

 

 

         

 

Android筆記(三十二) Android中線程之間的通訊(四)主線程給子線程發送訊息

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.