zoukankan      html  css  js  c++  java
  • Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息

             之前的例子都是我们在子线程(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:main
    09-17 04:29:48.669  28397-28410/cn.lixyz.handlertest D/TTTT﹕ handleMessage:Thread-141
    09-17 04:29:48.669  28397-28410/cn.lixyz.handlertest D/TTTT﹕ 收到了消息对象:100

             上面代码表示,消息是从MainThread发送的,WorkerThread接收到了消息。

             PS:非UI线程默认是没有创建Looper对象的,所以需要主线程向子线程传递消息时,需创建Looper对象并启动循环,子线程才可以循环着从MaessageQueue中取出消息。  

              

             

     

  • 相关阅读:
    JavaScript事件基础知识总结【思维导图】
    浮动广告 相关源码
    网页设计中常用的Web安全字体
    WEB 字体
    js文件被浏览器缓存的思考
    HTML5 LocalStorage
    CXF 中自定义SOAPHeader
    CXF拦截器(Interceptor)LoggingInInterceptor
    WebService注解汇总
    spring websocket 和socketjs实现单聊群聊,广播的消息推送详解
  • 原文地址:https://www.cnblogs.com/xs104/p/4816743.html
Copyright © 2011-2022 走看看