解决android应用被强杀或应用被回收导致的控件或者静态数据空指针问题

    APP长期在后台,有可能导致activity被内存回收,这时候再次点开APP的时候,由于activity里面的数据被清空,控件也变成了null,导致空指针出现。

目前有两种解决思路:

1、使用onSaveInstanceState和onRestoreInstanceState来保存UI状态的,基本上就是在按home键或者其他情况的时候存储数据,然后再次点开APP的时候读取bundle的数据,这种网上太多了,我就不说具体怎么做,这里只说我关于这种思路的看法。
  (1)这种保存数据的做法只能存储数据,解决像list空指针的问题,但是不能解决控件空指针的问题。
  (2)然后实际上一个项目那么多个页面,而且activity和fragment保存数据的方法还不一样,不可能一个一个页面去存储和读取数据的,不太现实。
  (3)网上说的baseactivity重写这2个方法,然后其他activity继承,也不过是存储了公共数据,比如token这些,但是实际上每个页面的数据差的很多,不能这么存的,实际意义很有限。
   感兴趣的小伙伴可以看下该方法的具体实现

2.另一种是我目前使用的,基于内存回收activty,变量也被回收了,做法是在application写一个public static的int变量值,值为-1,然后在启动页的onCreate里面把值变成1,然后在baseactivity的onCreate里面监听这个值,如果是-1说明变量被回收了,这个时候就可以跳转到主页(启动模式一般为SingleTask,保证MainActivty在栈中只有一个并且在最底层),并把页面关了,如果之前有写管理activity的工具类,遍历一下关掉,可以在启动页做这个操作。

这里记录一下第二种思路的解决办法:
  1、在applciation中声明变量flag,用于标志程序是否被杀掉

public class MyApplication extends Application {
    public static int flag = -1;
    ......
}

  2、在启动页(SplashActivity)中改变flag的值

public class SplashActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        MyApplication.flag = 1; //进入应用改变flag值,标识正常进入App
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        handler.sendEmptyMessageDelayed(0, 3000);
    }
 
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            startActivity(new Intent(SplashActivity.this, MainActivity.class));
            finish();
        }
    };
}

  3、新建BaseActivity(除SplashActivity外所有Activity都需要继承这个Activity),在这里判断是否需要重启程序

public abstract class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(MyApplication.flag == -1) { //flag为-1说明程序被杀掉
            protectApp();
        } else {
            setContentView();
            initializeView();
            initializeData();
        }
    }

    protected void protectApp() {
        Intent intent = new Intent(this,MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//清空栈里MainActivity之上的所有activty
        startActivity(intent);
        finish();
    }

    protected abstract void initializeData();

    protected abstract void initializeView();

    protected abstract void setContentView();

}

  4、MainActivity中复写protectApp()方法,直接跳转到启动页,重启activty,重新初始化application中的静态变量

@Override
 protected void protectApp() {
      startActivity(new Intent(this,SplashActivity.class));
      finish();
 }

如果想探究如何模拟app被内存杀死,可以查看这篇文章

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值