// private Handler mHandler=new Handler(){//导os包
// @Override
// public void handleMessage(Message msg) {
// super.handleMessage(msg);
// switch (msg.what){
// case 1:
//
// break;
//
// case 2:
//
// break;
//
// }
// }
// };
Activity这样使用Handler会存在内存泄漏的问题
解决:
1Handler使用静态内部类创建 2对所持有的Activity引用变为弱引用
原因:
1在Java 中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用,静态的内部类不会持有外部类的引用。
2由于Handler不再持有外部类对象的引用,导致程序不允许你在Handler中操作Activity中的对象了。所以你需要在Handler中增加一个对Activity的弱引用(WeakReference)。
//创建静态内部类
private static class MyHandler extends Handler {
//持有弱引用MainActivity,GC回收时会被回收掉.
WeakReference<OkhttpTestActivity> mWeakReference;
private MyHandler(OkhttpTestActivity mainActivity) {
mWeakReference = new WeakReference<>(mainActivity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what)
{
case 1:
if(mWeakReference.get()!=null){
mWeakReference.get().mTv.setText(msg.getData().getString("response"));
}else {
Log.e("wy","Activity销毁,弱引用也随之销毁");
}
break;
case 2:
break;
}
}
}
Handler handler = new MyHandler(this);
子线程中发送消息
Bundle mBundle= new Bundle();
mBundle.putString("response",response.toString());
Message msg=Message.obtain();
msg.what=1;
msg.setData(mBundle);
handler.sendMessage(msg);
使用okhttp异步请求进行网络访问,全代码
implementation("com.squareup.okhttp3:okhttp:4.8.1")
package com.wintec.netframworktest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
import java.io.IOException;
import java.lang.ref.WeakReference;
import androidx.appcompat.app.AppCompatActivity;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class OkhttpTestActivity extends AppCompatActivity {
OkHttpClient client;
private TextView mTv;
//创建静态内部类
private static class MyHandler extends Handler {
//持有弱引用MainActivity,GC回收时会被回收掉.
WeakReference<OkhttpTestActivity> mWeakReference;
private MyHandler(OkhttpTestActivity mainActivity) {
mWeakReference = new WeakReference<>(mainActivity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what)
{
case 1:
if(mWeakReference.get()!=null){
mWeakReference.get().mTv.setText(msg.getData().getString("response"));
}else {
Log.e("wy","Activity销毁,弱引用也随之销毁");
}
break;
case 2:
break;
}
}
}
Handler handler = new MyHandler(this);
//@SuppressLint("HandlerLeak")
// private Handler mHandler=new Handler(){//导os包
// @Override
// public void handleMessage(Message msg) {
// super.handleMessage(msg);
// switch (msg.what){
// case 1:
//
// break;
//
// case 2:
//
// break;
//
// }
// }
// };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTv = (TextView) findViewById(R.id.tv);
Request request = new Request.Builder()
.url("https://wap.peopleapp.com/article/5933922/5852020")
.build();
client = new OkHttpClient();
// OkHttp的同步请求会阻塞当前线程,因此不能在UI线程中请求,需要开启子线程,在子线程中发送请求。
// new Thread(new Runnable() {
// @Override
// public void run() {
// try {
// Log.e("wy","okhttp同步请求返回: "+ client.newCall(request).execute().toString());
// mTv.setText(client.newCall(request).execute().toString());
// } catch (IOException mE) {
// mE.printStackTrace();
// }
// }
// }).start();
// 异步请求
Call call=client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.e("wy","okhttp异步请求response返回:"+response.toString());
// android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
// mTv.setText(response.toString());
// 使用Handler进行线程通讯
Bundle mBundle= new Bundle();
mBundle.putString("response",response.toString());
Message msg=Message.obtain();
msg.what=1;
msg.setData(mBundle);
handler.sendMessage(msg);
// OkhttpTestActivity.this.runOnUiThread(new Runnable() {
// public void run() {
// mTv.setText(response.toString());
// }
// });
}
@Override
public void onFailure(Call call, IOException e) {
Log.e("wy","okhttp异步请求异常:"+e);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);
}
}
在我们以后开发中使用handler时,就可以使用静态类和弱引用,这样可以避免内存泄漏现象,达到内存优化的目的。