android给子线程传值,主线程给子线程发送消息

该博客探讨了Android中由于Handler和Looper导致的内存泄漏问题。作者指出,当Activity结束时,由于匿名内部类对子线程的强引用,线程无法正常结束,从而引发内存泄漏。解决方案是使用静态内部类并手动调用Looper.quit()来停止消息循环,确保资源的正确释放。文章提供了修改后的代码示例来展示如何避免内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.youkuaiyun.com/jingerlovexiaojie/article/details/107950669

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值