您的位置:首页 > 移动开发 > Android开发

关于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 bug