二、活动(Activity)的生命周期

  • 返回栈
  • 活动状态
  • 活动的生存期
  • 体验活动的生命周期
    • 活动被回收后
  • 活动的启动模式
    • standard
    • singleTop
    • singleTask
    • singleInstance
  • 相关实践
    • 获知当前活动
    • 随时随地退出程序
    • 启动活动的最佳写法

返回栈

安卓的活动会覆盖,实现的机制用的是栈

活动状态

四种:

运行状态;
暂停状态;
停止状态;
销毁状态;

活动的生存期

七个

onCreate();
onStart();
onResume();
onPause();
onStop();
onDestroy();
onRestart();

二、活动(Activity)的生命周期_第1张图片

体验活动的生命周期

三个Activity,一个NormalActivity, 一个DialogAcitvity, 一个MainActivity
NormalActivity:

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.normal_layout); 
}

DialogAcitvity:

protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.dialog_layout);
}

配置:

 <activity  android:name=".MainActivity" android:label="@string/app_name" >
     <intent-filter>
         <action android:name="android.intent.action.MAIN" />

         <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
 </activity>
 <activity android:name=".NormalActivity">
 </activity>
 <activity android:name=".DialogActivity" android:theme="@android:style/Theme.Dialog" >

 </activity>

MainActivity:

  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      Log.d(TAG, "onCreate");
      requestWindowFeature(Window.FEATURE_NO_TITLE);
      setContentView(R.layout.activity_main);

      Button startNormalActivity = (Button) findViewById(R.id.start_normal_activity);
      Button startDialogActivity = (Button) findViewById(R.id.start_dialog_activity);

      startNormalActivity.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        Intent intent = new Intent(MainActivity.this, NormalActivity.class);
        startActivity(intent);
    }
});
      startDialogActivity.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        Intent intent = new Intent(MainActivity.this, DialogActivity.class);
        startActivity(intent);
    }
});

  }
  @Override
  protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    Log.d(TAG, "onStart");
  }

  @Override
  protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    Log.d(TAG, "onResume");

  }
  @Override
  protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    Log.d(TAG, "onPause");
  }
  @Override
  protected void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    Log.d(TAG, "onStop");
  }
  @Override
  protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    Log.d(TAG, "Destory");

  }
  @Override
  protected void onRestart() {
    // TODO Auto-generated method stub
    super.onRestart();
    Log.d(TAG, "Restart");
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
  }

依次进入每个活动,MainActivity的状态:
onCeate()->onStart->onResume->

进入Normal:
onPause->onStop

返回:
onRestart->onStart->onResume

点击DialogAcitivity
onPause(没有onStop,因为这是对话框形式,所以MainActivity没有stop)

返回:
onResume

最后再返回:
onPause->onStop->onDestory

活动被回收后

如果内存不足,先开的活动被回收了,在返回那个活动时,会重新onCreate,同时活动的数据也没了。因此需要新的机制:onSaveInstanceState来解决保存回收前的已有数据问题。

@Override
//这里面的Bundle就是onCreate的Bundle参数
protected void onSaveInstanceState(Bundle outState) {
    // TODO Auto-generated method stub
    super.onSaveInstanceState(outState);
    String tempDate = "要保存的内容";
    outState.putString("data_key", tempDate);

}

onCreate里面取数据:

if(savedInstanceState!=null){
    String tempData = savedInstanceState.getString("data_key");
    Log.d(TAG, tempData);
}

Tip:Intent可以和Bundle一起用于传递数据,首先可以将Bundle放在Intent里面,然后传递Intent

活动的启动模式

standard

standard 是活动默认的启动模式,在不进行显式指定的情况下,所有活动都会自动使用这种启动模式。因此,到目前为止我们写过的所有活动都是使用的 standard 式。在 standard 模式(即默认情况)下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置。对于使用standard 模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例
FirstActivity里的onClick:

Intent intent = new Intent(FirstActivity.this, FirstActivity.class);
startActivity(intent);

onCreate里面:
加上:

Log.d("FirstAcitivity",this.toString());

点击按钮也就是自己调用自己,结果:需要自己按多次返回键

singleTop

配置文件中的Activity加上android:launchMode=”singleTop”属性,表示只有一个实例
但是如果活动不是在栈顶,还是会创建多个实例:
FirstActivity和SecondActivity互相循环调用,就不算是singleTop模式,仍然需要按多次返回

singleTask

在整个应用程序的上下文中只有一个实例,就不能循环调用(创建)了,2调用1,因为1已经在栈,所以2直接出栈调用1,2会被销毁。不像上面直接创建一个新的1。SingleTop会往上累加Activity,而singlTask,往下找Activity,找到后进入该Activity并会退出当前活动

singleInstance

指定为 singleInstance 模式的活动会启用一个新的返回栈来管理这个活动(其实如果 singleTask 模式指定了不同的 taskAffinity,也会启动一个新的返回栈) 。那么这样做有什么意义呢?想象以下场景,假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?使用前面三种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance 模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。

案例:
1调用2,2调用3,2设置为singleInstance。
结果是1,3的taskid是相同的,与2不同,说明2放在了另一个栈中,返回时直接从3返回到1,再返回到2,再退出(因为1,3在同一个栈,所以2单独放在最后才退出)。

相关实践

获知当前活动

加上这句(可以知道哪个Activity继承了这个Activity,如果继承了,都会打出BaseActivity,因为这句话加载BaseActivity中的onCreate中)

Log.d("BaseActivity", getClass().getSimpleName());

随时随地退出程序

每次完全退出,都要按返回,知道主活动,如何才能快速的退出
设计一个Collector类,一旦有活动(继承同一个活动)创建,在加入list(基类Activity中的onCreate方法中加入),finishAll()方法可以直接退出(最后一层调用button的onclick里面调用),这样不用一次一次返回了

public static List<Activity> activities = new ArrayList<Activity>();

public static void addActivity(Activity activity){
    activities.add(activity);
}
public static void removeActivity(Activity activity){
    activities.remove(activity);
}
public static void finishAll(){
    for(Activity activity:activities){
        if(!activity.isFinishing()){
            activity.finish();
        }
    }
}

启动活动的最佳写法

假设 SecondActivity 中需要用到两个非常重要的字符串参数,在启动 SecondActivity 的时候必须要传递过来,那么我们很容易会写出如下代码:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("param1", "data1");
intent.putExtra("param2", "data2");
startActivity(intent);

这样写是完全正确的,不管是从语法上还是规范上,只是在真正的项目开发中经常会有对接的问题出现。比如 SecondActivity 并不是由你开发的,但现在你负责的部分需要有启动SecondActivity 这个功能,而你却不清楚启动这个活动需要传递哪些数据。这时无非就有两种办法,一个是你自己去阅读 SecondActivity 中的代码,二是询问负责编写 SecondActivity的同事。你会不会觉得很麻烦呢?其实只需要换一种写法,就可以轻松解决掉上面的窘境.
我们在 SecondActivity 中添加了一个 actionStart()方法,在这个方法中完成了 Intent 的构建,另外所有 SecondActivity 中需要的数据都是通过 actionStart()方法的参数传递过来的,然后把它们存储到 Intent 中,最后调用 startActivity()方法启动 SecondActivity(原因在于函数一般都会注明参数,可以自己看)

public static void actionStart(Context context, String data1, String data2){
    Intent intent = new Intent(context, SecondActivity.class);
    intent.putExtra("param1", data1);
    intent.putExtra("param2", data2);
    context.startActivity(intent);
}

在FirstActivity里面的onClick中加入:

SecondActivity.actionStart(FirstActivity.this, "data1", "data2");

你可能感兴趣的:(二、活动(Activity)的生命周期)