Activity声明周期容易出现的问题
了解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导致的内存泄漏
- 原文链接 : Activitys, Threads, & Memory Leaks
- 原文作者 : AlexLockwood
- 译文出自 : 开发技术前线 www.devtf.cn
- 译者 : chaossss
- 校对者: yinna317
- 状态 : 完成
注:这篇博文涉及的源码可以在 GitHub 上面下载哦
Activity声明周期容易出现的问题的更多相关文章
- android activity声明周期学习笔记
android生命周期图: Activity继承了ApplicationContext: 1:初次加载activity时顺序执行:onCreate()-->onStart()-->onRe ...
- Activity声明周期2
FirstActivity.java import android.os.Bundle; import android.view.View; import android.view.View.OnCl ...
- Activity声明周期1
oncreate():在Activity对象第一次创建时调用 onStart():当Activity变得可见时调用该函数 onResume():当Activity开始准备于用户交互时调用该方法(即获得 ...
- xamarin Android activity生命周期详解
学Xamarin我为什么要写这样一篇关于Android 的activity生命周期的文章 已经学Xamarin android有一段时间了,现在想起当初Xamarin也走了不少的弯路.当然Xamari ...
- Android学习路线(十二)Activity生命周期——启动一个Activity
DEMO下载地址:http://download.csdn.net/detail/sweetvvck/7728735 不像其他的编程模式那样应用是通过main()函数启动的.Android系统通过调用 ...
- activity和fragment的声明周期
Activity生命周期: Fragment生命周期:
- android开发------Activity生命周期
这几天工作比较忙,基本没有什么时间更新播客了. 趁着今晚有点时间,我们来简单说一下什么是Activity生命周期和它们各阶段的特征 什么是生命周期 在还没有接触android开发的时候,听到有人说Ac ...
- Android-管理Activity生命周期 -开始一个Activity
很多程序都是从main()方法开始启动的,和其他程序不同,android是在activity生命周期的特定状态的特定回调方法中初始化代码的.activity启动和销毁的时候都用很多回调方法. 这里将要 ...
- Activity生命周期解决(有图有真相)
Activity完整的生命周期: 启动Activity的周期历程: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVuZ2t2/font/5a6L5L2 ...
随机推荐
- Java中OutOfMemoryError(内存溢出)的情况及解决办法
java.lang.OutOfMemoryError: Java heap space // TODO Auto-generated method stub Vector v = new Vector ...
- 避免 TCP/IP 端口耗尽
转载:http://www.cnblogs.com/tianzhiliang/archive/2011/06/27/2091214.html 当客户端启动到服务器的 TCP/IP 套接字连接时,客户端 ...
- c# 获取MAC IP TCP列表
转载自baidu:http://hi.baidu.com/jackeyrain/item/ff94efcfd5cf3a3099b498e9 namespace Public { public clas ...
- 查看xcode的路径
sudo /usr/libexec/locate.updatedb locate liblaunch_sim
- ZOJ 1423 (Your)((Term)((Project))) (模拟+数据结构)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=423 Sample Input 3(A-B + C) - (A+(B ...
- SGU Volume 2
SGU200.Cracking RSA------------------------★高斯消元 SGU207.Robbers -------------------------------数论 SG ...
- php 解决大流量网站访问量问题
当一个网站发展为知名网站的时候(如新浪,腾讯,网易,雅虎),网站的访问量通常都会非常大,如果使用虚拟主机的话,网站就会因为访问量过大而引起 服务器性能问题,这是很多人的烦恼,有人使用取消RSS等错误的 ...
- [Python笔记]第十六篇:web框架之Tornado
Tornado是一个基于python的web框架,xxxxx 安装 python -m pip install tornado 第一个Tornado程序 安装完毕我们就可以新建一个app.py文件,放 ...
- PKM(personal knowledge management)
内化 一般含义 一般上,当涉及道德行为时,内化是巩固和植入某人信念.态度和价值的长期过程,而这一过程的实现牵扯到精神分析或行为方法的慎重使用. 当改变道德行为时,一组新的信念.态度和价值代替或适应于所 ...
- git 基础命令
1.git init git 初始化仓库 2.git add . git 添加全部文件 3.git add xxx.txt git 添加单独文件 4.git commit -m "提交的 ...