本文目录结构:
一、活动的生命周期
二、活动的启动模式
三、活动间的信息传递之一 —— Intent
一、活动的生命周期
1.返回栈
Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也叫返回栈。在默认情况下,当我们启动了一个活动,那么它会入栈,并处于栈顶的位置。当我们按下返回键或者调用finish方法时,处于栈顶的活动就会出栈。系统总是显示处于栈顶的活动。
2.活动状态
活动的状态可以分为4种:
(1)运行状态
当一个活动处于栈顶的时候,那么它就处于运行状态。系统就不愿意就是回收运行状态的活动,因为这会给用户带来很不好的体验。
(2)暂停状态
当一个活动不处于栈顶但仍然可见时,它就处于暂停状态。比如对话框形式的活动只会占用屏幕中间的区域。系统也不愿意回收这样的活动,只有在内存极低的时候才会考虑去回收。
(3)停止状态
当一个活动不再处于栈顶,并且不可见的时候,就进入了停止状态。系统仍然会为这种活动保存相应的状态和成员变量,但这并不是完全可靠的。当其他地方需要内存,系统就有可能回收掉该活动。
(4)销毁状态
当一个活动被栈移除之后,它就处于销毁状态。系统最愿意回收这样的活动,从而保持手机内存的充足。
3.活动的生命周期
(1)onCreate
它会在活动第一次创建的时候被调用。我们应该在该方法中完成活动的初始化操作,比如加载布局、绑定事件等。
(2)onStart
该方法在活动由不可见变为可见的时候调用。
(3)onResume
该方法在活动准备好和用户交互的时候调用。此时的活动一定处于栈顶的位置。
(4)onPause
该方法在系统准备去启动或恢复另一个活动的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放掉,但该方法的执行速度一定要快,不然会影响到新的栈顶活动的调用。
(5)onStop
该方法在活动完全不可见的时候调用。它和onPause方法不同的是,如果启动的新活动是一个对话框形式的活动,那么onPause方法会被调用,而它不会。
(6)onDestroy
该方法会在活动被销毁之前调用。
(7)onRestart
该方法会在活动从停止状态变为运行状态之前调用。
PS:如果活动被销毁了,但是可能存在临时数据和状态,那要怎么办呢?
①可以调用onSaveInstanceState方法将数据临时保存起来
@Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
String data = "Keep it";
outState.putString("tempData",data);
}
②然后在onCreate方法中判断savedInstanceState是否为空
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
......
if(savedInstanceState != null)
String tempData = savedInstanceState.getString("tempData");
}
二、活动的启动模式
活动的启动模式一共有4种,它们需要在AndroidManifest文件中通过给<activity>标签指定android:launchMode属性来设置。
1.standard
它是活动默认的启动模式。每当有一个活动启动时,它就会入栈并处于栈顶的位置。系统根本不在乎栈里是否已经有了该活动的实例,每次启动活动都会创建一个新的实例。
standard.jpg
2.singleTop
当活动指定为该模式时,在启动活动时如果发现栈顶的活动已经是该活动,则系统会直接使用它,不会再创建新的活动实例。但如果该活动不在栈顶时再启动该活动时,还是会创建新的实例的。
singleTop.jpg
3.singleTask
当活动处于该模式时,每次启动活动时系统首先会在栈里检查是否存在该活动的实例,如果发现有则直接使用,并把在该活动之上的所有活动出栈。如果没发现则创建一个新的活动实例。
singleTask.jpg
4.singleInstance
当活动处于该模式时,系统会启用一个新的栈来管理这个活动。它可以解决共享活动实例的问题。比如:活动B为该模式,然后A启动B,B启动C,那么第一次按下返回键时系统会回到A,再按下一次时会回到B,再按下一次则退出应用。一个栈里的活动没有了之后才会去到另一个栈。
singleInstance.png
三、活动间的信息传递之一 —— Intent
1.显式Intent
(1)构造方法
//Intent intent = new Intent(Context packageContext,Class<?> cls);
//前者为启动活动的上下文,后者为想要启动的目标活动
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
(2)setComponent方法
ComponentName componentName = new ComponentName(this, SecondActivity.class);
Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
(3)setClass/setClassName方法
Intent intent = new Intent();
intent.setClass(this, SecondActivity.class);
// 或者intent.setClassName(this, "top.longsh1z.www.SecondActivity");
// 或者intent.setClassName(this.getPackageName(), "top.longsh1z.www.SecondActivity");
startActivity(intent);
2.隐式Intent
顾名思义,隐式Intent不会明确的指出想要启动的activity,而是通过指定action和category等信息让系统来选择要启动的活动。
首先,在AndroidManifest文件中,目标活动要有<intent-filter>标签,里面包含<action><category>子标签,只有这两个子标签中的内容同时匹配才能够生效。比如:
<activity android:name=".ui.Main2Activity">
<intent-filter>
<action android:name="top.longsh1z.www.Main2Activity"/>
<!--该category是一种默认的category-->
<!--在调用startActivity方法时会自动将这个category加到intent中-->
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
设置intent有两种方法:
(1)构造方法
Intent intent = new Intent("top.longsh1z.www.Main2Activity");
//如果category不是默认的话要再加下面的一条语句
//比如在AndroidManifest中自定义的category为
//top.longsh1z.www.Main2Activity_category,那么该语句为
//intent.addCategory("top.longsh1z.www.Main2Activity_category");
startActivity(intent);
(2)setAction方法
Intent intent = new Intent();
intent.setAction("top.longsh1z.www.Main2Activity");
//如果category不是默认的话同上
startActivity(intent);
3.更多隐式Intent的用法
我们也可以调用系统中固有的活动,比如系统的浏览器,拨号等等。比如调用系统浏览器:
//Intent.ACTION_VIEW是系统内置的动作,其常量值为android.intent.action.VIEW
Intent intent = new Intent(Intent.ACTION_VIEW);
//这条语句的意思是打开百度,具体其他用法请自己搜索
intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(intent);
另外,在一个活动的<action>标签里也可以写成系统内置的动作。当然这个前提是你的程序要有这样的功能,不然的话就会报错。
4.向下一个活动传递数据
使用intent.putExtra方法放消息,使用intent.getStringExtra方法拿消息。
//放消息进intent中
String data = "Hello world!";
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("MyData",data);
//其中data不一定只限于字符串,也可以为int,boolean类型
startActivity(intent);
//取消息
Intent intent = getIntent();
String data = intent.getStringExtra("MyData");
//若传递的数据为其他类型,则为getXxxExtra方法,比如getIntExtra,getBooleanExtra方法
5.返回数据给上一个活动
总体思路为(这里假设是FActivity<简写为F>)跳到SActivity<简写为S>,再S返回数据给F)
先在F中使用startActivityForResult方法向S传递一个唯一的请求码,
然后在S中使用setResult方法将结果码和数据返回给F,
最后F在onActivityResult中通过请求码和结果码拿到返回的数据。
//F中:
Intent intent = new Intent(F.this,S.class);
startActivityForResult(intent,1);//这里请求码为1
//S中:
Intent intent = new Intent();
intent.putExtra("dataReturn","I am dataReturn.");
setResult(RESULT_OK,intent);
//第一个参数一般只使用RESULT_OK或RESULT_CANCELED这两个值
//F中:
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
//第一个参数为请求码,是为了区分是哪个activity返回的数据,即数据来源
//第二个参数是判断处理结果是否成功
//第三个参数就是返回的数据
switch(requestCode){
case 1:
if(resultCode == RESULT_OK){
String data = intent.getStringExtra("dataReturn");
}
break;
}
}
网友评论