记一次app主进程被kill的经历

出现问题

最近在为河北电信做定制游戏平台开发的时候,遇到了一个很奇怪的问题,在某些盒子上,从平台打开某些游戏,玩上几分钟,然后该退出游戏,回到公司的游戏平台后,便出现了页面数据丢失的问题。
排查了几天(在这不得不吐槽电信的官僚主义,好话说尽,给予各种承诺,依然不提供可以进行adb调试的测试盒子)。最终发现是由于盒子内存太小(几年前的标准,1G内存!!!),当运行大型游戏后,盒子系统自动kill了公司的游戏平台,吐血啊。
该问题如下图所示:


问题.png

如何重现

既然知道了问题出现的原因,重现该问题也就简单了,具体步骤如下:

  • 打开你的app,通过按钮启动其它app

  • 利用adb 命令获取你的app 进程id

      adb shell su
      ps | grep 包名
    

    如下图所示:


    adb kill app.png
  • 利用adb命令kill 掉你的app进程

      kill -9 6796
    
  • 退出你启动的app,返回

解决

既然知道了问题出现的原因,也知道了重现的方法,那么解决问题也就简单了。
但是多次加班的经验告诉我,这想法太天真了!!!!

onRestoreInstanceState 和 onSaveInstanceState 无法挽救被kill的app的命运

按照网上的经验,面对内存数据被回收的情况,只要在onSaveInstanceState保存数据,在页面恢复时利用onRestoreInstanceState读取保存的数据,便可以高枕无忧。

@Override protected void onSaveInstanceState(Bundle outState) {
   //保存数据
   outState.putParcelable("data", mGameDetailEntity);
   //保存当前进程id和当前页面hashCode
   outState.putInt("pid", Process.myPid());
   outState.putInt("hashCode", hashCode());
   super.onSaveInstanceState(outState);
 }

 @Override public void onRestoreInstanceState(Bundle savedInstanceState) {
   super.onRestoreInstanceState(savedInstanceState);
   //恢复数据,并重新设置界面
   mGameDetailEntity = savedInstanceState.getParcelable("data");
   int pid = savedInstanceState.getInt("pid");
   int hashCode = savedInstanceState.getInt("hashCode");
   L.d(TAG, "pid ==> " + pid + ", currentPid ==> " + Process.myPid());
   L.d(TAG, "hashCode ==> " + hashCode + ", currentHashCode ==> " + hashCode());
   if (pid != Process.myPid() || hashCode != hashCode()) {
     isKilled = true;
   }
   setGameData(mGameDetailEntity);
   FL.d(TAG, "Activity被kill, 重新调用");
 }

但是多年爬坑的经历告诉我,网上的例子存在的意义只在于参考!!!
当App被kill掉后,如果只在activity中处理onSaveInstanceStateonRestoreInstanceState;不做其它任何处理,当前界面倒是正常了,当但你返回其它界面时,便会出现下图所示的情况。

gg.png

what?我不是保存了数据了吗?怎么还会出现这崩溃的情况?

继续使用adb命令查看线程,如下图所示


app 进程 id 变了.png

我们kill掉的app 的进程id为 6796 ,现在却变成了 7938!!
这也就意味着,系统重新启动了一个进程,相当于系统重新给app分配了内存,如果你的app有多个activity或者application中有实例化对像(这是不可避免的)。将会遇到我的情况,activity报空指针异常,或者某些数据报空指针异常。

如何完美解决该问题

我只能很抱歉的告诉你,对于这问题,目前还没有完美的解决方案,os自动重启进程,这已经不是我们能控制的范围了,现在是不是意味着我们已经不能解决这问题了;
当然不是,办法是人想的:
既然系统自动重启进程(鬼知道系统会不会走我的流程操作),干脆一不做二不休,自己重启app了,重新走一遍启动流程

解决方案:

  • 重新回到onRestoreInstanceState方法,在activity全局变量中,添加一个boolean(isKilled)用来判断app是否被kill掉,如果被kill掉,那么在onRestoreInstanceState给isKilled 赋值为true;
  • 执行最关键的步骤,在onBackPressed方法中,重启整个app
    public void onBackPressed(){
      if (isKilled) {
        reStartApp();
        return;
      }
      super.onBackPressed();
    }
    
    public void reStartApp(){
      Intent intent = new Intent(this, LauncherActivity.class);
       int pId = 123456;
       PendingIntent pi = PendingIntent.getActivity(this, pId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
       AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
       mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pi);
       System.exit(0);
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,561评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,218评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,162评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,470评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,550评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,806评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,951评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,712评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,166评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,510评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,643评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,306评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,930评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,745评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,983评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,351评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,509评论 2 348

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,770评论 25 707
  • Android初级: 1.了解Android系统架构 应用层: Java应用开发工程师开发的所有应用程序比如地图,...
    醉馬当前闯阅读 4,643评论 2 32
  • 如何能让我们的应用能够在系统后台持续地运行是一个自Android从娘胎里出来时就议论不停的话题,而且这似乎成了一个...
    骏骏的简书阅读 1,104评论 1 19
  • 假期归来,再见到同事们,不免话语更多一些,也显得更亲热一些,几句闲聊之后,大家就把话题转移到孩子身上,大家你一言我...
    活着不易阅读 182评论 0 4
  • 上次我们了一些RecycleView的初步使用过程,对比来看ListView,似乎没有什么好多的区别。今天我们来学...
    Aaron96阅读 1,312评论 5 6