主线程给子线程发送消息

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();
    }

 

你可能感兴趣的:(Handler源码)