Android 主线程与子线程之间的通信,子线程与子线程之间的通信

1.主线程发消息,子线程执行操作

其实一般情况下,主线程执行完所有必备逻辑后,再直接new Thread().start();(注意,没考虑内存泄漏),因为我们一般没有必要让子线程一直卡在某一步,等待消息后才执行,如果子线程不卡着,子线程执行完后自动结束。当然,新start的Thread我们要确定它什么时间执行还是比较麻烦的。但真的需要主线程发消息,子线程收到消息后执行操作,可以使用下面这个方法。

//先创建一个子线程HandlerThread handlerThread = new HandlerThread("name");//没看过源码,不知道参数具体作用,只知道是名字,类型为StringhandlerThread.start();//记得要开始线程/** * 注意,下面这才是重点(忽略我不规范的注释) * handler的handleMessage(Message msg)方法在哪一个线程执行,与handler在哪一个线程new没有关系,只与它所绑定的Looper有关, * 而Looper又与所在的线程绑定(一一对应),所以handler相当于与Looper身后的线程绑定。handler不带Looper参数的构造方法默认 * 与当前线程的Looper绑定,主线程默认配置Looper,而子线程需要调用Looper.prepare()后才被系统配置,因此子线程中handler的初 * 始化要放在Looper.prepare()和Looper.loop()(这是一个死循环)之间,基础不够扎实,还不知道找子线程中使用loop(),会不会造 * 成内存泄漏 */Handler mHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {    @Override    public boolean handleMessage(Message msg) {        //这部分的操作都是在子线程中执行的        return false;    }});

当然,也可以自定义一个thread类,提供一个接口出来,接口方法可以根据自身需求定义,thread里的run方法里是个死循环,然后主线程调用接口了,子线程才执行后面的操作(非常不推荐)

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    MyThread myThread = new MyThread();    OnMessageArrivedListener onMessageArrivedListener = myThread.getOnMessageArrivedListener();    new Thread(myThread).start();    //根据自己的时机调用    onMessageArrivedListener.onMessageArrived();}class MyThread implements Runnable{        private boolean hasArrived = false;    private OnMessageArrivedListener onMessageArrivedListener = new OnMessageArrivedListener() {        @Override        public void onMessageArrived() {            hasArrived = true;        }    };    public OnMessageArrivedListener getOnMessageArrivedListener(){        return onMessageArrivedListener;    }        @Override    public void run(){        while(!hasArrived){}        //下面执行子线程操作    }}interface OnMessageArrivedListener{    void onMessageArrived();}

可不可以用在主线程里使用的handler发送消息,自定义的子线程收到消息后再执行后续的操作呢?可以,就是有一点麻烦,需要在子线程拥有自身的Looper后,才可以,这就很麻烦了,尽管子线程可以直接把Looper或者handler开放出来,但主线程却不知何时才能使用它,这个强烈不建议使用。

 

2.子线程发消息,主线程执行操作

这个是最简单,也是用的最多的

我们可以在主线程创建一个全局的或者final修饰的handler对象,初始化之后,再调用newThread().start();然后在子线程中直接使用handler就可以了,非常简单方便

private Handler mHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    mHandler = new Handler(new Handler.Callback() {        @Override        public boolean handleMessage(Message msg) {            //这里的操作在主线程执行            return false;        }    });    new Thread(new Runnable() {        @Override        public void run() {            mHandler.sendEmptyMessage(1);        }    }).start();}

还有一种方式,就是在子线程里创建handler对象,前面说过,handler里handleMessage在哪个线程执行与在哪new无关,这种方式同样十分简单方便

new Thread(new Runnable() {    @Override    public void run() {        Handler handler = new Handler(getMainLooper(), new Handler.Callback() {            @Override            public boolean handleMessage(Message msg) {                //这里的操作在主线程执行                return false;            }        });    }}).start();

3.子线程与子线程之间通信

个人建议是用主线程做中间媒介,一个子线程执行完了,发消息给主线程,主线程收到消息后再创建下一个子线程,相当于间接地实现了子线程与子线程之间的通信

如果你觉得这个不满意,我自己还想了一种方法,不过这方法我自己个人都不建议,建议去其他博客找更好的方法

这个方法跟之前提的也差不多,就是,两个子线程都引用同一个接口对象,在收消息的子线程创建接口实例对象,发消息的子线程执行完操作后调用这个接口的方法,方法根据自己需求定义,收消息的子线程因为引用相同的接口实例对象,从而达到获取消息的目的

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    GetMessageThread getMessageThread = new GetMessageThread();    SendMessageThread sendMessageThread = new SendMessageThread();    //此时他们还只是个孩子。。。他们还只是一个类对象,还不是子线程    sendMessageThread.setOnMessageArrivedListener(getMessageThread.getOnMessageArrivedListener());    //执行完下面的代码他们就是了,注意顺序,尽管可能没什么用    new Thread(getMessageThread).start();    new Thread(sendMessageThread).start();}interface OnMessageArrivedListener{    void onMessageArrived(Object object);//所有都是自定义,可根据需求修改,返回值类型也是自定义}class GetMessageThread implements Runnable{    private boolean isOk = false;    private OnMessageArrivedListener onMessageArrivedListener = new OnMessageArrivedListener() {        @Override        public void onMessageArrived(Object object) {            //根据收到的消息决定isOk的值            //如            isOk = true;        }    };    //返回接口对象给发消息的子线程    public OnMessageArrivedListener getOnMessageArrivedListener(){        return onMessageArrivedListener;    }    @Override    public void run(){        while (true){            if(isOk){                //执行操作                break;            }        }    }}class SendMessageThread implements Runnable{    private OnMessageArrivedListener onMessageArrivedListener;    public void setOnMessageArrivedListener(OnMessageArrivedListener onMessageArrivedListener){        this.onMessageArrivedListener = onMessageArrivedListener;    }        @Override    public void run(){        //执行操作,根据需要的时机调用接口方法        Object o = new Object();//自己决定传什么        while(true){            if(onMessageArrivedListener != null){                onMessageArrivedListener.onMessageArrived(o);                break;            }        }    }}

这个方法因为我自身计算机系统基础不是很扎实,我自己都不知道会不会造成死锁,设计师说,这真的是糟糕透了!所以我也强烈不推荐这个方法

2019/5/8 留言:
没有修改博文,但还是要特别说一下,一定一定不要随随便便就用new Thread(),麻烦给Thread传一个名字啊,new Thread(CustonName)就好了,出现泄漏至少还能定位到哪里出的问题,不然你看到的只有Thread-1,Thread-2。。。

其实如果觉得比较麻烦,不妨试一下三方库EventBus,还是挺好用的,消息几乎哪里都可以达到

更多相关文章

  1. Android仿人人客户端(v5.7.1)——网络模块处理的架构
  2. Android开发:什么是IBinder
  3. Android(安卓)RxJava:细说 线程控制(切换 / 调度 )(含Retrofit实例讲
  4. android:framework了解一下
  5. [转]android消息机制,异步和多线程
  6. 如何去写Android(安卓)init.rc (Android(安卓)init language)
  7. Android(安卓)AsyncTask源码剖析
  8. android开发――通过子线程更新界面UI
  9. Android之入门:多线程更新UI界面

随机推荐

  1. Android程序退出彻底关闭进程的方法
  2. Android(安卓)Handler 泄漏
  3. 手机rom的那些坑
  4. Android使用外部字体
  5. android 手机屏幕密度等级和屏幕逻辑尺寸
  6. TranslateAnimation动画
  7. Android中振动器(Vibrator)的使用
  8. Android(安卓)SDK Manager:failed to ins
  9. Android如何实现引导页
  10. Android源码分析之Framework的MediaPlaye