欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

主线程给子线程发送消息

程序员文章站 2022-07-03 14:55:19
package com.example.customviewdemo;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.view.View;....
package com.example.customviewdemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Toast;

public class SecondActivity extends AppCompatActivity {

    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMsg();
            }
        });


        new Thread(new Runnable() {
            @Override
            public void run() {
                //run方法执行完了,线程的生命周期就结束了,就被销毁掉
                /**
                 * 1.创建了Looper对象,然后Looper对象创建了MessageQueue
                 * 2.并将当前的Looper对象跟当前的线程(子线程)绑定ThreadLocal
                 */
                Looper.prepare();

                /**
                 * 1.创建了handler对象,然后从当前线程中获取Looper对象,然后获取到MessageQueue对象
                 */
                handler = new Handler() {
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        super.handleMessage(msg);
                        Toast.makeText(SecondActivity.this, msg.obj.toString(), Toast.LENGTH_LONG).show();
                    }
                };


                /**
                 * 1.从当前线程中找到之前创建的Looper对象,然后找到MessageQueue
                 * 2.开启死循环,遍历消息池中的消息
                 * 3.当获取到msg的时候,调用这个msg 的handler的disPatchMsg方法,让msg执行起来
                 */
                Looper.loop();

            }
        }).start();
    }

    public void sendMsg() {
        handler.obtainMessage(2, "我是主线程发送来的消息").sendToTarget();
    }
}

这段代码会导致内存泄漏,需要当Activity退出的时候终止循环

 Looper.loop();

这里面开启了一个死循环,那么这个子线程run方法永远也执行不完。这个子线程是个匿名内部类对象,隐式的强引用,当Activity成会垃圾以后,还有对象引用它,这个对象还在活动状态。

使用静态内部类来替代,不是很完美

不用线程的时候,销毁线程

线程的stop()和destory()是有缺陷的,一般不用他们

如何让run方法执行完,让Looper.loop()执行完就可以

package com.example.customviewdemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Toast;

public class SecondActivity extends AppCompatActivity {

    private Handler handler;
    private Looper myLooper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMsg();
            }
        });


        new Thread(new Runnable() {
            @Override
            public void run() {
                //run方法执行完了,线程的生命周期就结束了,就被销毁掉
                /**
                 * 1.创建了Looper对象,然后Looper对象创建了MessageQueue
                 * 2.并将当前的Looper对象跟当前的线程(子线程)绑定ThreadLocal
                 */
                Looper.prepare();

                /**
                 * 1.创建了handler对象,然后从当前线程中获取Looper对象,然后获取到MessageQueue对象
                 */
                handler = new Handler() {
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        super.handleMessage(msg);
                        Toast.makeText(SecondActivity.this, msg.obj.toString(), Toast.LENGTH_LONG).show();
                    }
                };

                myLooper = Looper.myLooper();

                /**
                 * 1.从当前线程中找到之前创建的Looper对象,然后找到MessageQueue
                 * 2.开启死循环,遍历消息池中的消息
                 * 3.当获取到msg的时候,调用这个msg 的handler的disPatchMsg方法,让msg执行起来
                 */
                Looper.loop();
            }
        }).start();
    }

    public void sendMsg() {
        handler.obtainMessage(2, "我是主线程发送来的消息").sendToTarget();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        myLooper.quit();
    }

 

本文地址:https://blog.csdn.net/jingerlovexiaojie/article/details/107950669