关于android应用OOM检查与bug修改
2017-09-15 17:59
686 查看
之前项目崩溃比较频繁,有的手机一直很正常,有的手机动不动就崩了,报的异常是OOM。特别是,在我新加入了一个多图选择框架后,点开多图选择崩溃的概率很高。那时候没有集成leakscanary,分享一下我解决问题的过程吧。
1.Android Studio的Motitors查看内存使用情况。可以看到有的手机内存占用80M左右很平稳,有的115M左右,逐渐飙升,最高达到128就崩了。有的手机能达到140左右,最高限度是256,所以不崩。这里讲一下手机的分配内存情况。手机给每个APP分配了一个最大内存,可以通过代码查看正常分配的内存和最大可分配内存。
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);activityManager.getMemoryClass();
activityManager.getLargeMemoryClass()
一般这两个值为128/256M或者256/512M,那么128M的机型还是比较容易OOM的,可以在manifest里开启最大内存分配:android:largeHeap=”true”。当然这种方式不建议,因为用户看到手机上可用内存变少、累积和许多垃圾后大量gc导致的卡顿会影响体验。
2.观察会发生OOM的手机,发现在splash页面,内存开销已经很大,跳转到主页以后,内存已经115以上,随便开个图片就OOM了。问题在于SplashActivity有内存泄漏的。经过查看,Splash用到的handler都有在onDestroy的时候removeCallback。但是既然还有泄漏,那就还是在handler上作文章。加了弱引用和静态Handler,具体代码如下:
private SkipHandler mHandler; private static class SkipHandler extends Handler { private WeakReference mWeakActivity; public SkipHandler(SplashActivity1 activity) { mWeakActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { SplashActivity1 splashActivity1 = mWeakActivity.get(); if (splashActivity1 == null) { return; } switch (msg.what) { case 0: if (!splashActivity1.shouldFinish) { if (NetUtils.mOutTime(splashActivity1)) { if (MainApplication.getInstance().getUser() == null || MainApplication.getInstance().getUser().getUser() == null || MainApplication.getInstance().getUser().getUser().getType() == 0) { splashActivity1.startActivity(new Intent(splashActivity1, IndexActivity.class)); splashActivity1.finish(); return; } if (MainApplication.getInstance().getUser().getUser().getType() == 2 && MainApplication.getInstance().getUser().getUser().getMonk().getIsPerfect() == 0) { splashActivity1.startActivity(new Intent(splashActivity1, ApplyBuddhaActivity.class).putExtra("type", 0)); splashActivity1.finish(); return; } Intent intent = new Intent(); int currVersion = CommonUtils.getVersionCode(splashActivity1); if (currVersion != -1 && splashActivity1.versionBean != null && splashActivity1.versionBean.getAndroidVersion() > currVersion) { intent.putExtra("versionUpdate", splashActivity1.versionBean); } if (MainApplication.getInstance().getUser() == null || MainApplication.getInstance().getUser().getUser() == null) { intent.setClass(splashActivity1, IndexActivity.class); } else if (MainApplication.getInstance().getUser().getUser().getType() == 2) { intent.setClass(splashActivity1, BuddhaMainActivity.class); } else { intent.setClass(splashActivity1, BelieverMainActivity.class); } splashActivity1.startActivity(intent); splashActivity1.finish(); } else { Intent intent = new Intent(); int currVersion = CommonUtils.getVersionCode(splashActivity1); intent.setClass(splashActivity1, IndexActivity.class); if (currVersion != -1 && splashActivity1.versionBean != null && splashActivity1.versionBean.getAndroidVersion() > currVersion) { intent.putExtra("versionUpdate", splashActivity1.versionBean); } splashActivity1.startActivity(intent); splashActivity1.finish(); b117 } } break; //显示广告页面 case 2: if (TextUtils.isEmpty(mWeakActivity.get().adv_img)) { //没有广告信息 splashActivity1.mHandler.sendEmptyMessageDelayed(0, 1 * 1000); } else { //存在广告页 显示4秒广告 if (splashActivity1.time == 0) {//广告显示结束 splashActivity1.mHandler.sendEmptyMessage(0); } else { if (splashActivity1.time == -1) { splashActivity1.time = 4; splashActivity1.showAdv(); } splashActivity1.btn_skip.setText("跳过(" + splashActivity1.time + ")"); splashActivity1.time--; splashActivity1.mHandler.sendEmptyMessageDelayed(2, 1 * 1000); } } break; } } }
3.经过第2步以后再看内存使用情况,发现内存到达110多的时候就被回收了,OOM的概率大幅减小。然后还有一个BaseActivity里面遇到了环信的连线监听,这个也是一个内部类,也要写成静态的,加上弱引用。这里粘贴一部分代码。
private static class MyConnectionListener implements EMConnectionListener { private WeakReference<BaseActivity> mWeakActivity; public MyConnectionListener(BaseActivity activity) { mWeakActivity = new WeakReference<>(activity); } @Override public void onConnected() { } @Override public void onDisconnected(final int error) { final BaseActivity baseActivity = mWeakActivity.get();
相关文章推荐
- Android;sql数据库:关于删除数据库数据无法刷新listview并且新listview的修改增加功能出现bug的问题
- 关于eclipse的ADT(插件)对xml的android:text属性检查修改
- 关于Android应用的Log检查
- Google回应关于Android恶意程序的远程应用删除
- 关于Android下,修改frameworks/policies/xxx...文件后的编译问题
- 关于毕设3DGPSR程序bug修改
- 关于Android中Bitmap太大导致OOM错误
- 同事给我发的邮件,关于一个程序员如何面对修改Bug和需求变更的感想
- android 关于将应用添加到系统的 分享.. 或者 发送到.. 中
- 关于android创建快捷方式会启动两个应用的问题(二)
- 关于android创建快捷方式会启动两个应用的问题(一)
- 关于Android应用apk的程序签名
- 如何修改应用兼容Android 3.0系统
- 收藏关于android应用开发的博文
- Android2.2源代码中关于生成图片缩略图的一个bug
- 关于应用UCenter同步修改密码问题?
- 应用mina的例子做了一些修改,但有关于连接数的问题
- "getline" bug fix for Microsoft Visual C++ 6.0 关于VC6的getline输入需要两个回车才结束的BUG修改方法
- 关于android开发时,对src中包名的修改
- Enterprise Library深入解析与灵活应用(9):个人觉得比较严重的关于CachingCallHandler的Bug