Android四大组件之Activity

1.正常的周期

OnCreate: 生命周期的第一个方法,可以做一些初始化的操作
onRestart: 表示activit正在重新启动,这一般是当activity从不可见变成可见时调用,一般是由用户行为导致
OnStart:这是说明activity正在被启动,即将开始。
OnResume:表示activity已经可以看见了,并且出现在前台,已经与用户进行交互了。在这里OnStart和OnResume都是出现已经可见了,但是OnStart还在后台而OnResume已经出现在了前台
OnPause:表示activity正在停止,这个时候OnStop马上回被调用,在这里已经进行一些数据存储,动画显示等不耗时的操作,因为OnPause要执行完才能执行其他activity的OnResume。
OnStop:表示activity即将停止,在这里可以做一些资源比较有重量的回收,但是也不能太过耗时。
OnDestroy:最后一个方法,表示activity活到头了,在这里可以做一些回收工作和资源释放

OnStart和OnResume、OnPause和OnStop这两对方法没有什么实质性的不同,OnResume是可见周期的最后一个方法已经结束了,OnStart是还正在启动,OnPauses要执行完之后才能执行新activity的方法,OnStop是结束周期中简的一个

2.异常的生命周期

1、资源相关的系统配置发生改变导致activity被杀死重建
竖屏时变成横屏,由于设置了不同资源图片,activity会销毁重建。他会执行
onPauseonSaveInstanceStateonStoponDestroy
然后
onCreateonStartonResume
onSaceInstanceState是在异常结束activity时才会执行的方法,他会保存当前activity的状态同时会在新创建的activity调用onRestoreInstanceState方法并且将onSaceInstanceState方法保存的bundle传递给onCreate。我们可以在onSaceInstanceState中存储一些数据,在onRestoreInstanceState或者onCreate中读取,有一点onRestoreInstanceState如果执行那么Bundle是不会为空的,但是onCreate中就不知道了

2、资源不足导致优先级低的activity被杀死
优先级:前台activity
可见非前台activit(比如弹出一个对话框)
后台activit
杀死activity后,就会在有内存的时候通过onSaceInstanceState 保存onRestoreInstanceState恢复
可以通过设置android:configChanges=”orientation” 静止重建

3.Activity启动模式

1、存在的意义:
多次启动同一个activity,多次创建同一个实例,这是很傻的行为
1.standard(默认)每次启动activity都会重新创建实例
2.singleTop(栈顶复用模式) 判断activity是否在任务栈顶,如果在直接引用,同时调用onNewIntent方法,如果不在就创建新的实例。
3.singleTask(栈内复用模式) 判断栈中是否有这个实例,如果有那么就使用这个实例,如果没有那么就创建一个,这个activity会调用onNewIntent
4.singleInstance(单实例模式)这个是 singleTask 模式的加强版,它除了具有 singleTask 模式的所有特性外,它还有一点独特的特性,那就是此模式的 Activity 只能单独地位于一个任务栈,不与其他 Activity 共存于同一个任务栈。

2、什么是任务栈:
这是一个activity的参数TaskAffinity,这个参数标识了activity所需要的任务栈,默认情况下任务栈的名字为包名,我们可以给每个activity命一个名字,同名的是名字就是在一个任务栈,它主要是和singleTask或者allowTaskReparenting结合使用。
TaskAffinityallowTaskRepaernting一起使用且allowTaskRepaerntingtrue的时候如果当一个应用A的activity启动了一个应用B的activity,那么这个B应用的activity会直接从A的任务栈跑到B的任务栈。当返回桌面,点击应用B,他不会启动住activity,而会显示应用A启动的acitivity

设置启动模式有两种方法:
1.通过launchMode指定
2.通过Intent.addFlage指定
第二种的优先级比第一种要高,第二种无法指定为第四种模式

3、Activity隐式调用
隐式调用能够设置一些过滤信息,如果不匹配将无法启动activity
需要匹配:action、category、data
Action:是一个字符串,这里指定匹配是字符串相同,在xml文件中如过指定了action,如果在intent中没有设置,那么是无法匹配成功的,想要匹配必须intent中的字符串与action的字符串相同。
Category:Category中必须要有一个android.intent.Category.DEFAULT,而且intent可以不指定Category
Date:规则跟action一样,如果定义了那么就要指定,Date主要是一个规则,用来放置url

我们还可以在配置文件的activity中设置android:screenOrientation属性来设置他的横竖屏显示portrait(竖屏),landscape (横屏)

全屏的 Activity
要使一个 Activity 全屏运行,可以在其 onCreate()方法中添加如下代码实现:

// 设置全屏模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
WindowManager.LayoutParams.FLAG_FULLSCREEN); 
// 去除标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);

4.使用 Intent 通信

在 Android 中,不同的 Activity 实例可能运行在一个进程中,也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在 Activity 之间传递消息。Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。

在上面的实例中通过 Activity. startActivity(intent)启动另外一个 Activity 的时候,我们在 Intent 类的构造器中指定了“收件人地址”。

如果我们想要给“收件人”Activity 说点什么的话,那么可以通过下面这封“e-mail”来将我们消息传递出去:

Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
 // 创建一个带“收件人地址”的 email 
Bundle bundle =new Bundle();// 创建 email 内容
bundle.putBoolean("boolean_key", true);// 编写内容
bundle.putString("string_key", "string_value"); 
intent.putExtra("key", bundle);// 封装 email 
startActivity(intent);// 启动新的 Activity

那么“收件人”该如何收信呢?在 OtherActivity类的 onCreate()或者其它任何地方使用下面的代码就可以打开这封“e-mail”阅读其中的信息:

Intent intent =getIntent();// 收取 email 
Bundle bundle =intent.getBundleExtra("key");// 打开 email 
bundle.getBoolean("boolean_key");// 读取内容
bundle.getString("string_key");

上面我们通过 bundle对象来传递信息,bundle维护了一个 HashMap<String, Object>对象,将我们的数据存贮在这个 HashMap 中来进行传递。但是像上面这样的代码稍显复杂,因为 Intent 内部为我们准备好了一个 bundle,所以我们也可以使用这种更为简便的方法:

Intent intent =new Intent(EX06.this,OtherActivity.class);  
intent.putExtra("boolean_key", true);  
intent.putExtra("string_key", "string_value");  
startActivity(intent);

接收:

Intent intent=getIntent();  
intent.getBooleanExtra("boolean_key",false);  
intent.getStringExtra("string_key");