你的位置:首页 > 操作系统

[操作系统]基础总结之Activity


一、万事开头的序

  网上看见大牛们的博客写的那样精彩,各种羡慕之情溢于言表。几次冲动均想效仿牛人写些博客来记录下自己的心得体会,但均无感亦或是感觉容易被喷,相信很多菜鸟和我一样都有过这样的担忧。万事开头难,不逼一下自己怎么知道自己能不能飞起来。由于本人处于初学阶段,写此博客仅是对前辈总结的review,对自己记忆的加深及后续使用的方便查找。请各位看官将就看看,手下留情。在此谢过!有错的地方或者更好的心得体会欢迎随时骚扰!

二、Activity介绍

Android中常说的四大组件包括:Activity、Service、Broadcast、Content Provider

其中最基础也是最常见的就是今天review的主题:Activity

Activity存在的意义:用户与Android系统的交互的途径

三、Activity的生命周期

老套路先上经典的生命周期图:

(1)正常情况下的生命周期

Activity的生命周期主要由上述8个方法组成

  • onCreate表示Activity已经被创建(初始化)

在该方法中我们可以做一些初始化的相关操作

  1. 加载布局资源文件:setContentView(R.layout.XX);
  2. 初始化数据:findViewById(R.id.XX);
  • onRestart 通常在Activity从不可见, 重新变为可见时, 在onStart之前调用
  • onStart 表示Activity已经显示出来, 但是不能进行交互
  • onResume 表示Activity不仅仅显示出来, 而且已经在前台活动
  • onPause 表示Activity退出前台活动

在该方法中可以做以下操作:
1: 储存数据
2: 停止动画
onStop:表示Acitivity正在停止或者即将被销毁
onDestroy:表示Activity的销毁, 所做的操作和onCreate正好相反
PS: 耗时操作不要放到onPause或onStop中

  1. 首次打开:onCreate()->onStart()->onResume()
  2. 按back键结速应用程序:onPause()->onStop()->onDestory()
  3. 按home键隐藏应用程序:onPause()->onStop()//此时程序未销毁
  4. 再次启动应用程序:onRestart()->onStart()->onResume()
  5. 从Activity(A)跳转到Activity(B):onPause(A)->onCreate(B)->onStart(B)->onResume(B)->onStop(A)

 (2)异常情况下的生命周期

 当用户转动屏幕时,Activity销毁并重建的过程如下:

onPause()->onSaveInstanceState()->onStop()->onDestory()->onCreate()->onStart()->onRestoreInstanceState()->onResume()

系统自带的控件, 如TextView的文本内容Android系统会帮我们保存和恢复
App的状态, 则需要我们自己在onSaveInstanceState和onRestoreInstanceState中保存和恢复

@Overrideprotected void onSaveInstanceState(Bundle outState) {  super.onSaveInstanceState(outState);  Log.i(TAG, "onSaveInstanceState");    outState.putString(BUNDLE_DATA, "xyz");}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {  super.onRestoreInstanceState(savedInstanceState);  Log.i(TAG, "onRestoreInstanceState: " + savedInstanceState.getString(BUNDLE_DATA));}

View Code

我们能否在系统配置更新时, 自己对Activity的生命周期进行控制呢?
答案是可以的, android提供了这样的机制
我们在AndroidManifest.android:configChanges="orientation|screenSize"
再次旋转屏幕看看, Activity并没有销毁和重建了

四、Activity启动模式

与Activity生命周期息息相关的是Activity启动模式,不同的启动模式,导致的Activity生命周期则不同。

Activity有如下4种启动模式:

  • standard
  • singleTop
  • singleTask
  • singleInstance

1: standard

Step 1: (standard launch)FirstActivityCurrent Task Stack:++++FirstActivity
Step 2: (standard launch)SecondActivityCurrent Task Stack:++++SecondActivity++++FirstActivity
Step 3: (standard launch)FirstActivityCurrent Task Stack:++++FirstActivity++++SecondActivity++++FirstActivity

standard下: 总是会新建一个Activity入栈

Standard,默认的启动模式,只要激活了Activity,就会创建一个新的实例,并放入任务栈中,这样任务栈中可能同时存在一个Activity的多个实例。

2: singleTop

Step 1: (standard launch)FirstActivityCurrent Task Stack:++++FirstActivity
Step 2: (standard launch)SecondActivityCurrent Task Stack:++++SecondActivity++++FirstActivity
Step 3: (singleTop launch)SecondActivityCurrent Task Stack:++++SecondActivity++++FirstActivity

singleTop下: 如果栈顶是该Activity, 则不新建, 如果栈顶不是该Activity, 则新建该Activity

SingleTop,激活Activity时,如果栈顶是Activity,就不会创建新的实例,如果栈顶不是这个Activity,则会创建新的实例对象。

3: singleTask

Step 1: (standard launch)FirstActivityCurrent Task Stack:++++FirstActivity
Step 2: (standard launch)SecondActivityCurrent Task Stack:++++SecondActivity++++FirstActivity
Step 3: (singleTask launch)FirstActivityCurrent Task Stack:++++FirstActivity

singleTask下: 如果栈里已经存在该Activity, 即pop到该Activity, 如果栈里没有该Activity, 则新建Activity

singleTask,如果栈中存在Activity的实例,则将栈中该实例以上的其他Activity的实例移除,让该Activity的实例处于栈顶,如果栈中不存在该实例,则创建新的实例。

4: singleInstance

Step 1: (standard launch)FirstActivityCurrent Task Stack:++++FirstActivity
Step 2: (singleInstance launch)ThirdActivityCurrent Task Stack:++++FirstActivity ++++ThirdActivity
Step 3: (standard launch)SecondActivityCurrent Task Stack:++++SecondActivity++++FirstActivity ++++ThirdActivity

singleInstance下: 会新开一个栈, 单独放置该Activity

多个应用共享Activity的一个实例,不论是否是同一个应用,只要是激活该Activity,都重用这个实例。

五、Activity实例

1.Activity注册

1 // in AndroidManifest.2 <activity android:name=".SecondActivity" >3 </activity>

View Code

2.Activity之Intent

 1 // in FirstActivity.java 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4   super.onCreate(savedInstanceState); 5   setContentView(R.layout.activity_first); 6   Button standardButton = (Button) findViewById(R.id.standard_button); 7   standardButton.setOnClickListener(new OnClickListener() { 8     @Override 9     public void onClick(View arg0) {10       Intent intent = new Intent(FirstActivity.this,11           SecondActivity.class);12       startActivity(intent);13     }14   });15 }

View Code

3.Activity之Intent-Filter

1 //in mainifest.2 <intent-filter>3   <action android-name="android.intent.action.MAIN" />4   <category android-name="android.intent.category.LAUNCHER" />5 </intent-filter>

View Code

4.Activity间通信: FirstActivity -> SecondActivity

 1 // in FirstActivity.java 2 public static final String EXTRA_DATA = "extra_data"; 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5   super.onCreate(savedInstanceState); 6   setContentView(R.layout.activity_first); 7   Button standardButton = (Button) findViewById(R.id.standard_button); 8   standardButton.setOnClickListener(new OnClickListener() { 9     @Override10     public void onClick(View arg0) {11       Intent intent = new Intent(FirstActivity.this,12           SecondActivity.class);13       intent.putExtra(EXTRA_DATA, "cba");14       startActivityForResult(intent, REQUEST_CODE);15     }16   });17 }18 // in SecondActivity.java19 @Override20 protected void onCreate(Bundle savedInstanceState) {21   super.onCreate(savedInstanceState);22   setContentView(R.layout.activity_second);23   Intent intent = getIntent();24   Toast.makeText(25       SecondActivity.this,26       "Data from FirstActivity: "27           + intent.getStringExtra(FirstActivity.EXTRA_DATA),28       Toast.LENGTH_LONG).show();29 }

View Code

5.Activity间通信: SecondActivity -> FirstActivity

 1 // in FirstActivity.java 2 protected void onCreate(Bundle savedInstanceState) { 3   super.onCreate(savedInstanceState); 4   setContentView(R.layout.activity_first); 5   Button standardButton = (Button) findViewById(R.id.standard_button); 6   standardButton.setOnClickListener(new OnClickListener() { 7     @Override 8     public void onClick(View arg0) { 9       Intent intent = new Intent(FirstActivity.this,10           SecondActivity.class);11       startActivityForResult(intent, REQUEST_CODE);12     }13   });14 }15 // in SecondActivity.java16 @Override17 protected void onResume() {18   super.onResume();19   Intent intent = new Intent();20   intent.putExtra(EXTRA_DATA, "abc");21   setResult(Activity.RESULT_OK, intent);22 }23 // in FirstActivity.java24 @Override25 protected void onActivityResult(int requestCode, int resultCode, Intent data) {26   if (resultCode != Activity.RESULT_OK) {27     return;28   }29   switch (requestCode) {30   case REQUEST_CODE:31     Toast.makeText(32         FirstActivity.this,33         "Result from SecondActivity: "34             + data.getStringExtra(SecondActivity.EXTRA_DATA),35         Toast.LENGTH_LONG).show();36     break;37   default:38     break;39   }40 }

View Code

6.配置Activity启动模式
静态方式
即在AndroidManifest.

android:launchMode="singleTop"android:launchMode="singleTask"android:launchMode="singleInstance"

动态方式
即在源码中配置

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);