发表于: 2018-10-14 20:56:49
0 830
一、今天完成的事情
回顾了最近学习的内容,重点学习了之前一直没掌握的但是又非常重要的Context。
关于Context,官方给出的解释 是
Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.
Context提供了关于应用环境全局信息的接口。它是一个抽象类,它的执行被Android系统所提供。它允许获取以应用为特征的资源和类型,是一个统领一些资源(应用程序环境变量等)的上下文。就是说,它描述一个应用程序环境的信息(即上下文);是一个抽象类,Android提供了该抽象类的具体实现类;通过它我们可以获取应用程序的资源和类(包括应用级别操作,如启动Activity,发广播,接受Intent等)。
结合网上的各种博文,从Android系统的角度来理解:Context是一个场景,描述的是一个应用程序环境的信息,即上下文,代表与操作系统的交互的一种过程;从程序的角度上来理解:Context是个抽象类,而Activity、Service、Application等都是该类的一个实现。具体解释可以参考郭霖大神的博文,讲得非常详细 AndroidContext完全解析。
有一个需要注意的注意的地方,Context如果用不好,可能会引起内存泄漏。一般Context造成的内存泄漏,基本都是当Context要被销毁的时候,因为
Context仍被引用导致其销毁失败。
说到内存泄漏,今天我回头看代码时发现了一个之前遗留的问题
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// ...
}
}
我在Activity里(在Fragment里也一样)使用了一个非静态内部类,Android Lint 给出了一个警告:
In Android, Handler classes should be static or leaks might occur.
虽然编译可以通过,运行时似乎也没什么问题,但今天查了一下我才发现使用非静态内部类可能会导致严重的内存泄漏,handler是一个内部类, 内部类会持有外部类的引用,如果此时activty的被退出了. handler持有他的引用,所有这个activity 并不会被销毁,其实还是在内存中.所有就造成的Context泄漏。
具体原因可以参考:How to Leak a Context: Handlers & Inner Classes
正确的写法因该是:
public class VerifyIdentityActivity extends AppCompatActivity {
...
private MyHandler mHandler = new MyHandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verify_identity);
initView();}
...
/**
* 静态内部类MyHandler
*/
private static class MyHandler extends Handler {
private final WeakReference<VerifyIdentityActivity> mActivity;
public MyHandler (VerifyIdentityActivity activity) {
mActivity = new WeakReference<VerifyIdentityActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(mActivity.get() == null) {
return;}
...
}
}
注意这个方法,
if(mActivity.get() == null) {return;
}
必须要有这个方法,通过get()方法可以判断这个对象是否被回收,我们需要判断这个mActivity 是否存在才能做后面的操作。
二、明天计划的事情
开始做任务四
三、遇到的问题
虽然能实现很多功能,但如果让我重做一遍任务三,还是得参照着资料写。
四、收获
对于之前一直不明白得知识点比如Context有了新的理解。
评论