重新认识Activity生命周期方法

 取决于你应用的复杂度,可能不必实现每个周期方法,但是,理解每一个方法能保证你的应用能按照使用者的期望来运行。
      正确并合适的实现周期方法有以下好处:
          1、当有电话进来或者切换到其它应用的时候,你的应用不会崩掉;
2、应用关闭后,不会再占用系统资源;
3、用户离开后再返回应用时,不会丢失进度;
4、手机进行横竖屏切换的时候不会崩掉或者丢失进度 。

在Activity的各个状态中,只有以下三种是静态的:
Resumed--在前台处于正常运行状态。
Paused----被另一个半透明的页面遮挡或者被另一个页面部分遮挡,无法响应用户操作,也不能执行代码。
Stopped---此时,界面完全看不到,就好像在后台,Activity的实例,状态信息,成员变量等都被保存,但不能执行代码。

除了这三个以外的其它状态都是临时转换状态,切换很迅速。

一、指定应用的启动Activity(主Activity)
点击桌面的上应用图标后,系统调用主Activity中的onCreate方法,如何把一个Activity设置成主Activity?
在清单文件中注册Activity时,添加:
 <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
如果MAIN action或者LAUNCHER都没有被声明,桌面上将不会出现你的应用图标。
二、创建一个新实例

系统靠调用onCreate方法来创建实例,所以你必须实现onCreate方法,来执行应用的启动逻辑,
这个启动逻辑在整个生命周期中必须且只被执行一次。一般在这个方法中初始化用户界面,初始化全局变量。
一旦onCreate方法执行完毕,onStart和onResume会快速的跟着执行,实际上,onStart方法完成后,Activity就是可见状态了。
三、销毁Activity
onDestroy方法执行后,Activity的实例就被完全的销毁了。
大多数情况下,不必实现此方法,因为,随着Activity的销毁,局部类的引用也被销毁。
大部分的清理工作是在onPause方法和onStop方法中完成,但是如果后台有运行的线程
(这些线程在onCreate方法创建的)或者其它长期运行的资源,如果没有适当的关掉,有可能造成内存的泄漏,
这种情况下,得在onDestroy方法中杀掉它们。
一般情况下,onDestroy是跟着onPause和onStop方法执行的,但是如果调用了finish()方法后,就会跳过
那两个方法,立刻执行onDestroy。

四, Activity的Pausing 和 Resuming
onPause()方法中要做的有:
停止动画和其它占用CPU资源的动作;
仅在用户期望做的改变永久保存时,提交未保存的更改
释放系统资源,例如:广播接收者,传感器的Handle,和其它用户用不到但影响电池电量的资源。
如果你的应用正在使用Camera,在onPause()中,就要这样:
public void onPause(){
super.onPause();//总是放在第一句话
if(mCamera!=null){
mCamera.release();
mCamera=null;
}
}
1、一般情况下,不在onPause()中永久保存用户的更改,除非我们确定用户期望这样(比如邮件的草稿)。
2、另外还要避免在onPause中进行耗费CPU资源的工作,例如不能在此方法中执行写入数据库的操作,这样会降低界面的流畅度,最好把这些高负载的工作放在onStop()方法中。
3、最后还要限制onPause()中执行方法的总数量,以便Activity状态的快速切换。
注意,处于Paused状态的Activity的实例被保存在内存中,所以不需要在通往onResume路上初始化之前的任何变量。
每次Activity回到前台的时候都会调用onResume(),所以需要实现onResume方法初始化在onPause()中释放的变量
五、Activity的stopping 和 restarting
Activity停止和重启的几个关键场景
1、用户打开最近的应用列表,从你的应用切换到其它应用,你应用中当前显示的Activity就被停止了。
如果用户从Home界面的图标或者最近开启的应用列表返回到你的应用,Activity就会重启。
2、用户开启一个新的Activity,当前Activity停止,当第二个Activity处于create状态时,按返回键,第一个Activity重启。
3、运行应用时,来电。

由于在Activity Stop的时候,系统保存Activity的实例到内存中,所以几乎不用实现onStop/onRestart/甚至onStart()方法。
当应用从后台回前台时,会调用onRestart(),之后是onStart()也就是说,不管Activity是新创建还是从台回前台,onStart()方法是必经之路, 所以一些恢复场景的操作和一些检查设备环境的操作可以放在此方法中。
例如检查GPS开启情况:

@Override
protected void onStart() {
    super.onStart();  // Always call the superclass method first
    
    // The activity is either being restarted or started for the first time
    // so this is where we should make sure that GPS is enabled
    LocationManager locationManager = 
            (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    
    if (!gpsEnabled) {
        // Create a dialog here that requests the user to enable GPS, and use an intent
        // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
        // to take the user to the Settings screen to enable GPS when they click "OK"
    }
}

@Override
protected void onRestart() {
    super.onRestart();  // Always call the superclass method first
    
    // Activity being restarted from stopped state    
}
六、Recreating an Activity 重构

有这样一些场景,用户通过返回键,或者是代码中遇到finish()方法,Activity被正常销毁。
另外Activity长时间处于stop 状态,或者前台应用要申请更多的资源,系统也会通过关闭后台进程的方法销毁Activity。

如果你的Activity是通过用户返回键和调用Finish方法被销毁的,系统就认为你不再需要这个Activity的实例了,当然,
这种情况下,再次开启此Activity时,会重新创建另一个新的Activity实例。
然而,如果Activity是系统自己帮你销毁的,那再次开启此Activity时,它就会记得用一个数据集合来创建这个新Activity,这个数据集合用来 描述Activity 被关闭前它的状态。系统用来恢复之前状态所保存的数据称之为:instance state . 并且是一个键值对的集合,
保存在Bundle类中。

注意:默认情况下,当屏幕方向发生变化时,系统都会把当前的Activity销毁后再重构,因为系统认为,
屏幕参数发生了变化,你的Activity可能需要更换合适的资源。
默认情况下,系统用Bundle存放Activity的Layout中各个View对象的状态,一旦Activity重构,它就会自动恢复重要之前的状态,不需要你的参与,但是如果你想在重构后恢复更多的状态信息,比如成员变量的值什么 的。就得用Bundle自己弄了。也就是说,保存与View相关的对象的状态的操作,父类已经替你做好了,如果要有其它什么东西需要保存,就得你自己来。
保存附加的Activity状态信息要重写onSaveInstanceState()方法 ,当用户要离开你的Activity时,系统就会调用此方法,用传入一个Bundle对象,当Activity需要重构的时候,再把这个Bundle对象同时传给onRestoreInstanceState()和onCreate()
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
    savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
    
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}
七、Activity状态的恢复
onRestoreInstanceState()和onCreate()这两个方法都能收到Bundle对象,先说在onCreate()方法中恢复
一、因为不管是重构还是新建Activity实例,都会调用onCreate()方法,所以通过此方法恢复时,要判断Bunlde对象是否为空。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first
   
    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Restore value of members from saved state
        mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance
    }
    ...
}

二、还可以选择实现onRestoreInstanceState()恢复,由于此方法在onStart()方法之后调用,并且只有在Bundle对象不为空时,
系统才会调用,所以不用判断Bundle是否为空
public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);
   
    // Restore state members from saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
记住:不要忘记调用父类的方法,这样View结构的状态才能被存储。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值