android-APP长期运行于后台,重启后如何避免异常

问题的详细描述是这样的:
android中,当我们按home键(一般指手机的物理按钮的中间那个键)回到手机桌面,此时app并没有退出,而是一直运行与后台中,此时如果我们点击app图标,还是会进入刚刚的界面之中。但是这存在一个问题,就是如果内存紧张或者当我们回到桌面,点击了别的应用造成内存紧张,此时再通过点击图标进入app,此时会出现异常。这样造成的用户感觉非常不好!

其实,归纳起来,并不仅仅这种情况下造成数据丢失,造成数据丢失的情况有如下几种:
(1)、当用户按下HOME键时。
  这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。
  (2)、长按HOME键,选择运行其他的程序时。
  (3)、按下电源按键(关闭屏幕显示)时。
  (4)、从activity A中启动一个新的activity时。(这种情况应该是,当我们在activity A时,此时通知栏有其他的通知,我们点击通知启动activity B,此时我们进入别的应用)
  (5)、屏幕方向切换时,例如从竖屏切换到横屏时。

值得幸运的是,android对此提供了非常好的解决办法!

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState() 会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。

  在activity被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个activity被杀死前调用,当该activity在将来某个时刻回来时可以恢复其先前状态。
  

@Override
 protected void onSaveInstanceState(Bundle outState) {
 System.out.println("BaseActivity.onSaveInstanceState()");
  outState.putString("loginname", Application.LOGINNAME);
  outState.putInt("classId", Application.classId);
  outState.putSerializable("classinfos", 
    (ArrayList<ClassInfo>)Application.getInstance().getClassInfos());
  super.onSaveInstanceState(outState);
 }

 @SuppressWarnings("unchecked")
 @Override
 protected void onRestoreInstanceState(Bundle savedInstanceState) {
  System.out.println("BaseActivity.onRestoreInstanceState()");
  super.onRestoreInstanceState(savedInstanceState);
  if (savedInstanceState != null) {
   Application.LOGINNAME = savedInstanceState.getString("loginname");
   Application.classId = savedInstanceState.getInt("classId");
   Application.getInstance().setClassInfos(
     (List<ClassInfo>)savedInstanceState.getSerializable("classinfos"));
  }
 }

实例代码如上,通过重写上面两个方法保存一些需要当前界面或者整个应用需要使用的数据,缓存起来,等到重新启动时,这些数据依然存在,这样重启之后不会造成app异常退出!

需要提醒的是,我们开发一个app的时候,activity是非常多的,一个界面中需要的数据很多,并且不知道用户会在哪个activity中按下Home键退回到了手机桌面,这样该如何处理呢?
此时的解决办法是,使用一个基本BaseActivity,在BaseActivity重写onSaveInstanceState和onRestoreInstanceState两个方法,然后每个界面Activity继承基类BaseActivity,这样不必每个activity重写这两个方法,同时,不管在哪个activity中按下home键,都会把数据保存起来,重启之后数据不至于丢失!

———————————— 分隔符—————————————-
另外,还有一个地方需要说明,有些app可能想每次点击应用图标的时候,都能够进入主界面,不管此时app处于什么状态,不管app此时是否运行与后台,这时可以使用activity的配置

<activity      android:name="com.whut.bag.android.activity.WelcomeActivity"
            android:label="@string/app_name"         android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:screenOrientation="portrait"
            android:launchMode="singleTask"
             >

         <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>
        </activity>

启动的activity中配置android:launchMode=”singleTask”即可。这样配置,保证每次点击应用图标,都进入主界面内,不管此时app是否运行与后台之中。

参考:http://blog.csdn.net/caesardadi/article/details/20382815

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android系统为了优化功耗和资源管理,会在一定条件下限制后台运行应用。但是,如果我们开发的应用需要在后台长时间运行,可以通过以下几种方法来实现: 1. 前台服务(Foreground Service):前台服务是一种优先级较高的服务,可以将应用置于可见状态,使其在后台长时间运行。通过在service的onCreate方法中调用startForeground方法,将服务设置为前台服务,同时在通知栏显示一个通知,以提醒用户该服务正在运行。 2. jobScheduler:JobScheduler是一种用于调度后台任务执行的系统服务。通过创建一个JobScheduler任务,指定任务的执行条件和周期,系统会在合适的时间执行任务。可以使用setPersisted方法来设置任务在设备重启后继续执行。 3. WorkManager:WorkManager是一个用于管理后台任务调度的库。可以使用WorkManager来执行需要在后台长时间运行的任务,并且提供了灵活的任务调度和管理功能。WorkManager利用了JobScheduler或AlarmManager来实现后台任务的调度,并且可以保证任务的持久性。 4. AlarmManager:AlarmManager是一种能够在指定时间触发特定操作的系统服务。我们可以使用AlarmManager来设置一个定时的任务,利用setRepeating方法来指定任务的循环周期。 需要说明的是,为了提高用户体验和遵守系统限制,我们在使用这些方法时,需要合理设置任务的优先级,避免对系统资源的滥用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值