感谢这位哥的思路。
这个问题很常见,基本所有app都会遇到这个问题。但是很多开发者都没有处理。
问题的起因:我的app在进入后台后一段时间,可能被系统干掉了,然后通过多任务键,或者图标再点进去操作,出现xxId为null
经过一番探索发现:
app在被系统干掉后,重新进入,是会实例出所有的界面(因为他们都重写了onsaveInstance方法),但是这个界面所有的变量都变为null了(如果没有自己保存的话)。
解决的办法2种
1.每个页面都去重写onsaveInstace方法,去保存数据(对于老项目来说,这个工程量是非常巨大的)(如果是新项目,建议用一个好的框架,统一处理每一个页面变量的存取)
2.比较取巧的办法就是在被干掉重启的时候,重新进入SplashActivity(也就是启动页)。重走一遍流程,数据也就肯定不会出错了(ios系统上,如果出现被系统干掉的情况,也是采用的这种方法)
本文主要就是介绍第二种办法:
原理:
1.在splashActivity的oncreate时候就设置一个全局的变量值。
2.在baseActivity的oncreate中比较这个变量值是否发生变化(app在后台被干掉后重进,该值会变为默认)
3.如果发生了改变,就重进splashActivity,如果没有就正常处理
工具类一个:
/**
* 这个类的作用是保证app进入后台被系统回收之后,再次进入app时重首页进入。
* 配合splashactivity和baseactivity使用
*/
public class RestartUtils {
public static final int STATUS_FORCE_KILLED = -1;//应用在后台被强杀了
public static final int STATUS_NORMAL = 2; //APP正常态
public static final String START_LAUNCH_ACTION = "start_launch_action";
private int appStatus = STATUS_FORCE_KILLED; //默认为被后台回收了
private static RestartUtils appStatusManager;
public static RestartUtils getInstance() {
if (appStatusManager == null) {
appStatusManager = new RestartUtils();
}
return appStatusManager;
}
public int getAppStatus() {
return appStatus;
}
public void setAppStatus(int appStatus) {
this.appStatus = appStatus;
}
}
BaseActivity里面:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
switch (RestartUtils.getInstance().getAppStatus()) {
case STATUS_FORCE_KILLED:
Log.d("thisttt" , "BaseModuledActivity-STATUS_FORCE_KILLED");
restartApp();
break;
case STATUS_NORMAL:
Log.d("thisttt" , "BaseModuledActivity-STATUS_NORMAL");
break;
default:
break;
}
}
private void restartApp() {
Intent intent = new Intent(this,MainActivity.class);
intent.putExtra(START_LAUNCH_ACTION,STATUS_FORCE_KILLED);
startActivity(intent);
}
SplashActivity里面:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
RestartUtils.getInstance().setAppStatus(STATUS_NORMAL);
Log.d("thisttt" , "SplashActivity-setAppStatus");
super.onCreate(savedInstanceState);
}
注意事项有3点:
1.所有的activity包括SplashActivity都需要继承BaseActivity
2.SplashActivity的onCreate中,先设置setAppStatus()。再super.onCreate().
3.首页activity必须singtask(首页activity一般是SplashActivity下一个页面。具体看自己是否免登陆,免登陆就是MainActivity。不免登陆就是LoginActivity)
测试(模拟内存不足,被系统干掉):
很多帖子说用开发者模式的 不保留活动测试,是错误的。下面介绍不保留活动的特效
- 保留app内存数据(全局的单例等),
- 保留activity堆栈数据,
- 再次开启app,会调用onCreate()重新创建栈顶的activity,
所以内存数据还是在的。
正确的办法是开发者模式->后台进程数限制->2个进程->然后开几个其他应用,你的应用就被干掉了。