因为手机内存不足的时候,会回收一些app,如果被回收的app中有全局变量,那么再次进入这个app就会出现异常报错。
因为Application是全局变量,内存不足的时候会被回收,这个时候如果不是重启而是恢复之前的页面,系统会重新new 一个Application,所以没回收之前保存在Application中的信息都将没有了,这个时候被恢复的页面就可能因为需要Application中的信息报NullPointerException错。
这说明:系统回收app后,再次进入此软件,Android只是恢复这个应用,并不是重启,它会创建一个新的Application对象并且启动上次用户离开时的activity以造成这个app从来没有被kill掉得假象。
What is Application
Application和Actovotu,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息。通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己 的Application,也很简单创建一个类继承 Application并在manifest的application标签中进行注册(只需要给Application标签增加个name属性把自己的 Application的名字定入即可)。
android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些,数据传递,数据共享 等,数据缓存等操作。
看了大多数都是使用onSaveInstanceState和onRestoreInstanceState来保存UI状态的,基本上就是在按home键或者其他情况的时候存储数据,然后再次点开APP的时候读取bundle的数据,因为一般项目都有多个activity,这样做就比较麻烦了。
这里将一个简单粗暴的方法:activity加载布局之前判断当前程序是否被系统回收,如果是则重新启动app。
具体代码如下:
1.创建 ——一个类保存app是否被回收的两个静态变量。
public class AppStatus {
public static final int STATUS_RECYCLE =-1; //被回收
public static final int STATUS_NORMAL=1; //正常
}
2.创建——AppStatus的管理类,并初始appStatus(APP状态 )的值为被系统回收
public class AppStatusManager {
public int appStatus = AppStatus.STATUS_RECYCLE;//APP状态 初始值被系统回收
public static AppStatusManager appStatusManager;
private AppStatusManager(){}
//单例模式
public static AppStatusManager getInstance() {
if (appStatusManager == null) {
appStatusManager = new AppStatusManager();
}
return appStatusManager;
}
//得到状态
public int getAppStatus() {
return appStatus;
}
//设置状态
public void setAppStatus(int appStatus) {
this.appStatus = appStatus;
}
}
3.创建一个BaseActivity继承 AppCompatActivity,在onCreate方法中判断是否要重启
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//判断app状态
if (AppStatusManager.getInstance().getAppStatus() == AppStatus.STATUS_RECYCLE){
//被回收,跳转到启动页面
Intent intent = new Intent(this, StartActivity.class);
startActivity(intent);
finish();
return;
}
}
}
4.项目中的Activity页面,只需要继承BaseActivity就可以了
public class TestActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
}
5.最后就是启动页面了,在页面跳转前将app状态调为正常
public class StartActivity extends AppCompatActivity {
private ImageView sp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.startup);
sp=(ImageView) findViewById(R.id.imageView);
sp.postDelayed(new Runnable() {
@Override
public void run() {
//页面跳转
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
//app状态改为正常
AppStatusManager.getInstance().setAppStatus(AppStatus.STATUS_NORMAL);
startActivity(intent);
finish();
}
}, 2500);
}
}
这个时候有人可能不明白了,为什么只设置了app的正常状态,就能起到重启的效果?
这个时候我们再回头看一开始说的原因中,就会恍然大悟。在手机内存不足的时候,会回收全局变量,这个时候在AppStatus 中的 STATUS_RECYCLE =-1; //被回收(设置为默认值)
STATUS_NORMAL=1; //正常
两个变量也会被回收,也就是说,在开始页面设置的app状态已经失效。再次恢复页面的时候这些全局变量都会重建,此时app的状态就变成被回收了,在恢复页面的时候判断不通过便会重新启动软件了。
参考:https://blog.csdn.net/Silence_Yong/article/details/82804808
https://blog.csdn.net/xx326664162/article/details/79191853