了解activity的生命周期,不仅仅是回答面试官的几个小问题:下面这篇文章不错,截取个人认为优秀的部分分享给大家,欢迎交流.感谢原作者 

 /**
* 示例向我们展示了在 Activity 的配置改变时(配置改变会导致其下的 Activity 实例被销
* 毁)存活。此外,Activity 的 context 也是内存泄漏的一部分,因为每一个线程都被初始
* 化为匿名内部类,使得每一个线程都持有一个外部 Activity 实例的隐式引用,使得
* Activity 不会被 Java 的垃圾回收机制回收。
*/
public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exampleOne();
} private void exampleOne() {
new Thread() {
@Override
public void run() {
while (true) {
SystemClock.sleep(1000);
}
}
}.start();
}
}

Activity 配置发生改变会使 Activity 被销毁,并新建一个 Activity,我们总会觉得 Android 系统会将与被销毁的 Activity 相关的一切清理干净,例如回收与 Activity 关联的内存,Activity 执行的线程等等……然而,现实总是很残酷的,刚刚提到的这些东西都不会被回收,并导致内存泄漏,从而显著地影响应用的性能表现。

Activity 内存泄漏的根源

每一次配置的改变都会使 Android 系统新建一个 Activity 并把改变前的 Activity 交给垃圾回收机制回收。但因为线程持有旧 Activity 的隐式引用,使该 Activity 没有被垃圾回收机制回收。

我们把该线程类声明为私有的静态内部类就可以解决这个问题:

     /**
* 示例通过将线程类声明为私有的静态内部类避免了 Activity context 的内存泄漏问题,但
* 在配置发生改变后,线程仍然会执行。原因在于,DVM 虚拟机持有所有运行线程的引用,无论
* 这些线程是否被回收,都与 Activity 的生命周期无关。运行中的线程只会继续运行,直到
* Android 系统将整个应用进程杀死
*/
public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exampleTwo();
} private void exampleTwo() {
new MyThread().start();
} private static class MyThread extends Thread {
@Override
public void run() {
while (true) {
SystemClock.sleep(1000);
}
}
}
}

通过上面的代码,新线程再也不会持有一个外部 Activity 的隐式引用,而且该 Activity 也会在配置改变后被回收。

下面是一种解决办法:

    /**
* 除了我们需要实现销毁逻辑以保证线程不会发生内存泄漏,其他代码和示例2相同。在退出当前
* Activity 前使用 onDestroy() 方法结束你的运行中线程是个不错的选择
*/
public class MainActivity extends Activity {
private MyThread mThread; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
exampleThree();
} private void exampleThree() {
mThread = new MyThread();
mThread.start();
} /**
* 私有的静态内部类不会持有其外部类的引用,使得 Activity 实例不会在配置改变时发生内
* 存泄漏
*/
private static class MyThread extends Thread {
private boolean mRunning = false; @Override
public void run() {
mRunning = true;
while (mRunning) {
SystemClock.sleep(1000);
}
} public void close() {
mRunning = false;
}
} @Override
protected void onDestroy() {
super.onDestroy();
mThread.close();
}
}

通过上面的代码,我们在 onDestroy() 方法中结束了线程,确保不会发生意外的线程的内存泄漏问题。如果你想要在配置改变后保留该线程(而不是每一次在关闭 Activity 后都要新建一个线程),那我建议你使用 Fragment 去完成该耗时任务。百度一篇叫作“Handling Configuration Changes with Fragments”应该能满足你的需求,在API demo中也提供了很好理解的例子来为你阐述相关概念。

在Activity中使用Thread导致的内存泄漏

注:这篇博文涉及的源码可以在 GitHub 上面下载哦

Activity声明周期容易出现的问题的更多相关文章

  1. android activity声明周期学习笔记

    android生命周期图: Activity继承了ApplicationContext: 1:初次加载activity时顺序执行:onCreate()-->onStart()-->onRe ...

  2. Activity声明周期2

    FirstActivity.java import android.os.Bundle; import android.view.View; import android.view.View.OnCl ...

  3. Activity声明周期1

    oncreate():在Activity对象第一次创建时调用 onStart():当Activity变得可见时调用该函数 onResume():当Activity开始准备于用户交互时调用该方法(即获得 ...

  4. xamarin Android activity生命周期详解

    学Xamarin我为什么要写这样一篇关于Android 的activity生命周期的文章 已经学Xamarin android有一段时间了,现在想起当初Xamarin也走了不少的弯路.当然Xamari ...

  5. Android学习路线(十二)Activity生命周期——启动一个Activity

    DEMO下载地址:http://download.csdn.net/detail/sweetvvck/7728735 不像其他的编程模式那样应用是通过main()函数启动的.Android系统通过调用 ...

  6. activity和fragment的声明周期

    Activity生命周期: Fragment生命周期:

  7. android开发------Activity生命周期

    这几天工作比较忙,基本没有什么时间更新播客了. 趁着今晚有点时间,我们来简单说一下什么是Activity生命周期和它们各阶段的特征 什么是生命周期 在还没有接触android开发的时候,听到有人说Ac ...

  8. Android-管理Activity生命周期 -开始一个Activity

    很多程序都是从main()方法开始启动的,和其他程序不同,android是在activity生命周期的特定状态的特定回调方法中初始化代码的.activity启动和销毁的时候都用很多回调方法. 这里将要 ...

  9. Activity生命周期解决(有图有真相)

    Activity完整的生命周期: 启动Activity的周期历程: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVuZ2t2/font/5a6L5L2 ...

随机推荐

  1. TCP/IP 协议理解

    TCP/IP 协议(Transmission Control Protocol / internet Protocol),因特网互联协议,又名网络通讯协议.通俗而言:TCP负责发现传输的问题,一有问题 ...

  2. Windows Socket五种I/O模型

    转载:http://www.cnblogs.com/tianzhiliang/archive/2010/08/31/1813637.html 如果你想在Windows平台上构建服务器应用,那么I/O模 ...

  3. 我和ASP.NET MVC有个约会

    很早之前在项目中使用的软件架构模式,一直想着写一写加深自己对它的理解.但总是一天拖着一天,趁着现在闲,跟大家唠唠嗑这个东西. 首先什么是 MVC(Model-View-Controller) 呢?不得 ...

  4. jquery 关于event.target使用的几点说明介绍

    event.target说明:引发事件的DOM元素. this和event.target的区别js中事件是会冒泡的,所以this是可以变化的,但event.target不会变化,它永远是直接接受事件的 ...

  5. 水题(素数表)NYOJ素数距离

                描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度素数,则输出左侧的值及相应距离. 如果输入的整数本身就是素数,则输 ...

  6. Codeforces 553D Nudist Beach(图论,贪心)

    Solution: 假设已经选了所有的点. 如果从中删掉一个点,那么其它所有点的分值只可能减少或者不变. 如果要使若干步删除后最小的分值变大,那么删掉的点集中肯定要包含当前分值最小的点. 所以每次删掉 ...

  7. mongo数据库使用小结

    db.userId5555.aggregate({$unwind:"$tcjl"},{$match:{"_id":"0e549864-2a56-43c ...

  8. JavaScript各种遍历方式详解

    为了方便例子讲解,现有数组和json对象如下 var demoArr = ['Javascript', 'Gulp', 'CSS3', 'Grunt', 'jQuery', 'angular']; v ...

  9. StrongReference

    原创作品:未经本人允许,不得转载前段时间写项目时遇到了一个问题,就是从网络获取图片资源的问题,总是出现OOM异常,经过几天的努力,终于处理的还算是可以使用,OOM的处理一直都是很头疼的问题.对于三级缓 ...

  10. php生成二维码

    <?php $urlToEncode="163.com";   generateQRfromGoogle($urlToEncode);   function generate ...