Android编码的常见错误及解决方法分享
来源:才华咖 本文已影响2.55W人
来源:才华咖 本文已影响2.55W人
在android编码中,会有一些简便的写法和编码习惯,会导致我们的代码有很多内存泄露的问题,在这里做一个已知错误的总结:
1、编写单例的时候常出现的错误。
错误方式:
public class Foo{ private static Foo foo; private Context mContext; private Foo(Context mContext){ text = mContext; } // 普通单例,非线程安全 public static Foo getInstance(Context mContext){ if(foo == null) foo = new Foo(mContext); return foo; } public void otherAction(){ (); …. } }
错误原因:
如果我们在Activity A中或者其他地方使用nstance()时,我们总是会顺手写一个『this』或者『mContext』(这个变量也是指向this)。试想一下,当前我们所用的Foo是单例,意味着被初始化后会一直存在与内存中,以方便我们以后调用的时候不会在此次创建Foo对象。但Foo中的『mContext』变量一直都会持有Activity A中的『Context』,导致Activity A即使执行了onDestroy方法,也不能够将自己销毁。但『applicationContext』就不同了,它一直伴随着我们应用存在(中途也可能会被销毁,但也会自动reCreate),所以就不用担心Foo中的『mContext』会持有某Activity的引用,让其无法销毁。
正确方式:
public class Foo{ private static Foo foo; private Context mContext; private Foo(Context mContext){ text = mContext; } // 普通单例,非线程安全 public static Foo getInstance(Context mContext){ if(foo == null) foo = new Foo(pplicationContext()); return foo; } public void otherAction(){ (); …. } }
2、使用匿名内部类的时候经常出现的错误
错误方式:
public class FooActivity extends Activity{ private TextView textView; private Handler handler = new Handler(){ @override public void handlerMessage(Message msg){ } }; @override public void onCreate(Bundle bundle){ eate(bundle); setContextView(vity_foo_layout); textView = (TextView)findViewById(View); Delayed(new Runnable(){ @override public void run(){ ext(“ok”); }; },1000 * 60 * 10); } }
错误原因:
当我们执行了FooActivity的finish方法,被延迟的消息会在被处理之前存在于主线程消息队列中10分钟,而这个消息中又包含了Handler的引用,而Handler是一个匿名内部类的实例,其持有外面的FooActivity的'引用,所以这导致了FooActivity无法回收,进而导致FooActivity持有的很多资源都无法回收,所以产生了内存泄露。
注意上面的new Runnable这里也是匿名内部类实现的,同样也会持有FooActivity的引用,也会阻止FooActivity被回收。
一个静态的匿名内部类实例不会持有外部类的引用。
正确方式:
public class FooActivity extends Activity{ private TextView textView; private static class MyHandler extends Handler { private final WeakReference
3、在使用handler后,记得在onDestroy里面veCallbacksAndMessages(object token);
veCallbacksAndMessages(null); // removeCallbacksAndMessages,当参数为null的时候,可以清除掉所有跟次handler相关的Runnable和Message,我们在onDestroy中调用次方法也就不会发生内存泄漏了。
开发中需要注意的点以免内存泄漏:
1.不要让生命周期长于Activity的对象持有到Activity的引用 2.尽量使用Application的Context而不是Activity的Context 3.尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用(具体可以查看细话Java:”失效”的private修饰符了解)。如果使用静态内部类,将外部实例引用作为弱引用持有。 4.垃圾回收不能解决内存泄露,了解Android中垃圾回收机制
获取context的方法,以及使用上context和applicationContext的区别:
ontext,返回当前View对象的Context对象,通常是当前正在展示的Activity对象。 pplicationContext,获取当前Activity所在的(应用)进程的Context对象,通常我们使用Context对象时,要优先考虑这个全局的进程Context。 3,aseContext():用来获取一个ContextWrapper进行装饰之前的Context,可以使用这个方法,这个方法在实际开发中使用并不多,也不建议使用。 返回当前的Activity实例,如果是UI控件需要使用Activity作为Context对象,但是默认的Toast实际上使用ApplicationContext也可以。
大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释:
数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。
数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。
数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视)
注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。
好了,这里我们看下表格,重点看Activity和Application,可以看到,和UI相关的方法基本都不建议或者不可使用Application,并且,前三个操作基本不可能在Application中出现。实际上,只要把握住一点,凡是跟UI相关的,都应该使用Activity做为Context来处理;其他的一些操作,Service,Activity,Application等实例都可以,当然了,注意Context引用的持有,防止内存泄漏。
Windows的常见故障和解决方法
Windows10 弹出defender的解决方法
Thinkpad笔记本开机显示Tointerrruptnormalstartup解决方法
关于javascript中encodeURI和decodeURI的使用方法
Word 2003分栏方法及常见问题的解决方法
解决PHP的failed opening required问题的方法
ADO编程常见问题及解决办法
Android读取本地json文件的方法
android SDk中常用的java包功能介绍
WindowsXP内存读写错误的解决方法
解决PHP中的Cannot modify header information 问题
关于打印时提示您不是administrator无法打印问题的解决方法
Win10系统提示Officebackgroundtaskhandler.exe弹窗问题的解决方
Windows系统常见的几个故障及解决方法
八年级英语下册Unit 6 An old man tried to move a Mountain period one说课稿
自我介绍几个常见误区以及解决方法
Traditional New Year Foods英语阅读
GMAT数学Induction题型的解决方法
关于GREArgument常见误区及解决方法
Android系统手机数据备份方法
关于高中英语常见I beg your pardon口语词语的用法
英语六级作文Discrimination in Education
MySQL安装时出现current root password的解决方法
奥运英语作文:中国跳水队(Diving into Gold: Chinas Dream Team
[英语诗歌及翻译]-working on the railroad
aspose.words解决实现文档格的中创word方法
付出与收获 Hard Work and Income英语作文
ipadmini2黑屏的原因以及解决方法
Windows内存出错的解决方法
解决学车常见错误的方法
Messi Wins Ballon dOr award Again大学英语作文
电脑出现NSIS中Error错误提示的解决方法
World Day to Combat Desertification大学英语作文
北师大一年级下Lesson 5《Food and drink》教案
如何用fuzz技术挖掘Android漏洞 Android漏洞该如何防御
电脑内存常见问题分析及解决方法
运用错误分析理论解释小学生英语学习中的常见错误
Java/Android引用类型及其使用分析
dfrgfat:dfrgfat.exe-应用程序错误解决方法
基于AIDE 的Android 程序开发教学设计论文