Handler引起的内存泄露
一般我都写handler的时候是这样的:
public class MyActivity extends Activity{
private final Handler myHandler = new Handler(){
public void handleMessage(Message msg){
//。。。。
}
};
}
public class MyActivity extends Activity{
private final Handler myHandler =newHandler(){
@Override
public void handleMessage(Messagemsg){
// ...
}
}
@Override
protected void onCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);// 发送一个延迟十分钟的消息
mLeakyHandler.postDelayed(newRunnable(){@Overridepublicvoidrun(){/* ... */}},1000*60*10);
// 然后结束当前页面
finish();
}
}
我们执行了Activity的finish方法,被延迟的消息会在被处理之前存在于主线程消息队列中10分钟,而这个消息中又包含了Handler的引用,而Handler是一个匿名内部类的实例,其持有外面的MyActivity的引用,所以这导致了无法回收,进行导致MyActivity持有的很多资源都无法回收,这就是我们常说的内存泄露。MyActivity
如何解决呢???
思路就是避免使用非静态内部类。
继承Handler时
1.放在单独的类文件中。。
2.使用静态内部类。 因为静态内部类不会持有外部类的引用,就不会导致外部类实例的内存泄露。
当你需要在静态内部类中调用外部的Activity时,我们可以使用弱引用来处理。另外关于同样也需要将Runnable设置为静态的成员属性。
public class
MyActivity
extends Activity { /** * Instances of static inner classes do not hold an implicit
* reference to their outer class.
*/
private static class MyHandler extends Handler{
private final WeakReference<SampleActivity> mActivity;
public MyHandler(SampleActivityactivity){
mActivity=newWeakReference<SampleActivity>(activity);
}
@Override public void handleMessage(Messagemsg){
SampleActivityactivity=mActivity.get();
if(activity!=null){
// ...}
}
}
private final MyHandler mHandler=newMyHandler(this);
/**
* Instances of anonymous classes do not hold an implicit
* reference to their outer class when they are "static".
*/
private static final Runnables Runnable=newRunnable(){
@Override
public void run(){
/* ... */
}
};
@Override
protected void onCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
// Post a message and delay its execution for 10 minutes.
mHandler.postDelayed(sRunnable,1000*60*10);
// Go back to the previous
Activity.finish();
}
}
其实在Android中很多的内存泄露都是由于在Activity中使用了非静态内部类导致的,就像本文提到的一样,所以当我们使用时要非静态内部类时要
格外注意,如果其实例的持有对象的生命周期大于其外部类对象,那么就有可能导致内存泄露。个人倾向于使用文章的静态类和弱引用的方法解决这种问题。
Handler引起的内存泄露的更多相关文章
- Android handler 可能会造成内存泄露
Android handler 可能会造成内存泄露 Android Studio 使用 Handler 时: private Handler handler = new Handler(){ @Ove ...
- Android 中 Handler 引起的内存泄露
在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.其实这可能导致内存泄露,代码中哪里可能导致内存泄露,又是如何导致内存泄露的呢?那我们就慢慢分析一下.http://w ...
- 【转】内部Handler类引起内存泄露
如果您在Activity中定义了一个内部Handler类,如下代码: public class MainActivity extends Activity { private Handl ...
- Handler 引起的内存泄露
先看一组简单的代码 1 2 3 4 5 6 7 8 9 public class SampleActivity extends Activity { private final Handler mHa ...
- Android 从java字节码告诉你 为什么Handler会造成内存泄露
很多人面试的时候,都知道Handler 极易造成内存泄露,但是有一些讲不出来为什么,好一点的 会告诉你looper msg 之类的,但是你再往下问 为什么msg持有handler handler为什么 ...
- Android中Handler引起的内存泄露
在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用.通常我们的代码会这样实现. 1 2 3 4 5 6 7 8 9 public class SampleActivit ...
- Android中Handler导致的内存泄露
http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html Consider the follo ...
- Android性能优化——之防止内存泄露
又是好久没有写博客了,一直都比较忙,最近终于有时间沉淀和整理一下最近学到和解决的一些问题. 最近进行技术支持的时候,遇到了几个崩溃的问题,都是OOM异常,一般OOM异常给人的感觉应该是加载大图片造成的 ...
- Android之内存泄露、内存溢出、内存抖动分析
内存 JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆.栈和方法区.栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放.优点:速度快.堆(heap) ...
随机推荐
- UVA-10827(前缀和降维)
题意: 给一个n*n的正方形,第一行和最后一行粘在一块,第一列和最后一列粘在一块,求这个环面上的最大的子矩形; 思路: 直接暴力是O(n^6)的复杂度,可以把前缀和求出来,这样就可以只用枚举四条边界就 ...
- Ruby: Print WIN32OLE method names in Ruby
class WIN32OLE def list_ole_methods method_names = ole_methods.collect {|m| m.name} puts m ...
- python-----实现print不换行
python中print输出是默认换行的,那如何我们不想换行,且需要用多个print函数输出时,就需要改变print默认换行的属性: 例: print('Hello') print('!') 输出结果 ...
- nc之二:nc命令详解
NetCat,在网络工具中有“瑞士军刀”美誉,其有Windows和Linux的版本.因为它短小精悍(1.84版本也不过25k,旧版本或缩减版甚至更小).功能实用,被设计为一个简单.可靠的网络工具,可通 ...
- JS按字节截取字符长度实例2
/* * param str 要截取的字符串 * param L 要截取的字节长度,注意是字节不是字符,一个汉字两个字节 * return 截取后的字符串 */ function cutStr(str ...
- C - Soldier and Cards
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description Two bo ...
- linux中用管道实现父子进程通信
1 用户要实现父进程到子进程的数据通道,可以在父进程关闭管道读出一端, 然后相应的子进程关闭管道的输入端. 2 先用pipe()建立管道 然后fork函数创建子进程.父进程向子进程发消息,子进程读消息 ...
- springboot redis工具类
package com.vv.boot.util; import java.util.List; import java.util.Map; import java.util.Set; import ...
- poj 1182 食物链【带权并查集】
设相等的边权为0,吃的边权为,被吃的边权为2,然后用带权并查集在%3的意义下做加法即可 关系为简单环的基本都可以用模环长的方式是用带权并查集 #include<iostream> #inc ...
- bzoj 3277: 串 & bzoj 3473: 字符串【后缀自动机||后缀数组】
建一个广义后缀自动机(每加完一个串都返回root),在parent树上dpsum记录合法长度,打着时间戳往上跳,最后每个串在自动机上跑一变统计答案即可. 后缀数组理解起来可能方便一点,但是难写,就只说 ...