技术交流1群:46523908
技术交流2群:46505645
NoHttp 源码及Demo托管在Github欢迎大家Star:https://github.com/Y0LANDA/NoHttp
NoHttp是专门做Android网络请求与下载的框架,框架直播视频源码下载地址。
This Handler class should be static or leaks might occur (com.yolanda.nohttp6.activity.ThreadActivity.1)。这个警告写Android的人应该都遇到过,是在用new Handler时提示的:
这个警告的意思是我们这么使用Handler
会发生内存泄漏,有两个解决办法:
1、如果确定我们的Handler
在组件(Activity(Fragment)...)
退出后不会收到异步发来的消息,我们这里用鼠标点击解决方案中的第一个或者第二个选项,开发工具会在Handler
或者组件上添加注解,例如:
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
public void handleMessage(Message msg) {};
};
这样注解之后那个警告就没了。
2、但是这不能保证我们不发生内存泄漏问题,所以Yolanda这里给大家一种解决方案。我们先来做个分析,我们使用Handler发生内存泄漏无非是当我们Activity/Fragment
或者其他组件销毁后,Handler从异步发来消息后更新UI,然后发生了内存泄漏,发生了异常,可能导致APP崩溃。所以我们想到在Handler
中用弱引用来引用Activity/Fragment
。
3、普及一下弱引用的常识,弱引用就是不保证不被垃圾回收器回收的对象,它拥有比较短暂的生命周期,在垃圾回收器扫描它所管辖的内存区域过程中,一旦发现了只具有弱引用的对象,就会回收它的内存,不过一般情况下,垃圾回收器的线程优先级很低,也就不会很快发现那些只有弱引用的对象。弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用的对象被垃圾回收的话,Java虚拟机就会把这个弱引用加入相关的引用队列中。简单些来说,当我们的Activity/Fragment
销毁后这个对象不存在,即被垃圾回收期回收。随意我们用它来做下简单的封装:
public class BaseHandler extends Handler {
private WeakReference<BaseActivity> reference;
public BaseHandler(BaseActivity activity) {
reference = new WeakReference<BaseActivity >(activity);
}
@Override
public void handleMessage(Message msg) {
if (reference != null && reference.get() != null) {
reference.get().handleMessage(msg);
}
}
}
handleMessage(Message)
方法 这里我们以Activity
为例,我们看到上面Hanlder#handleMessage(Message)
被触发后有一个判断if (reference != null && reference.get() != null)
这里判断了弱引用对象是否为null
,如果不为null
就调用它的一个handleMessage(Message)
方法,我们知道Activity
必定是没有void handleMessage(Message msg);
方法的,所以我们写一个抽象类,接下来带大家实现BaseActivity
:
public abstract class BaseActivity extends Activity {
/** * 处理Handler的消息 * * @param msg */
public abstract void handleMessage(Message msg);
}
这样我们使用的时候Activity
继承BaseActivity
接口就可以了,然后重写handleMessage(Message msg);
方法就可以了。
我们这里以Activity
为例来写一个示范:
public class TestHandlerActivity extends BaseActivity {
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new BaseHandler(this);
...
}
@Override
public void handleMessage(Message msg) {
}
}
这里只是用Activity举例,我们平常的Fragment
和Dialog等都可以这么使用。
NoHttp 源码及Demo托管在Github欢迎大家Star:https://github.com/Y0LANDA/NoHttp