Day2 Activity生命周期/启动模式/最佳实践
Android是使用任务(Task)来管理活动的,这个栈被称作返回栈(Back Stack)。
Activity类中定义了7个回调方法:
onCreate()
。在活动第一次被创建时调用,应该在这个方法中完成活动的初始化操作,比如加载布局、绑定事件等。
onStart()
。这个方法在活动由不可见变为可见的时候调用。
onResume()
。这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。
onPause()
。在系统准备去启动或者恢复另外一个活动的时候调用。通常在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据。
onStop()
。这个方法在活动完全不可见的时候调用。它和onPause()方法的主要区别在于,如果启动的新活动是一个对话框式的活动,那么onPause()方法会得到执行,而onStop()方法并不会执行。
onDestroy()
。在活动被销毁之前调用,之后活动的状态将变为销毁状态。
onRestart()
。这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
以上7个方法除了onRestart()
方法,其他都是两两相对的。
当MainActivity第一次被创建时会依次执行onCreate()
、onStart()
、onResume()
方法;
当有其他Activity完全遮挡住时,会执行onPause()
、onStop()
方法;
重新返回后会执行onRestart()
、onStart()
、onResume()
方法;
当出现没有完全遮挡住MainActivity的Activity时,只会执行onPause()
方法;
当返回MainActivity时也只有onResume()
方法会得到执行;
在MainActivity按下Back键退出程序时会依次执行onPause()
、onStop()
、onDestroy()
方法,最终销毁MainActivity。
创建对话框式Activity:
在AndroidManifest.xml中修改<activity>
的标签配置,如下:
</activity>
<activity android:name=".NormalActivity" >
</activity>
<activity android:name=".DialogActivity"
//添加Android内置对话框式主题
android:theme="@android:style/Theme.Dialog">
</activity>
Activity被回收的处理方法:onSaveInstanceState()
回调方法
这个方法可以保证在活动被回收之前一定会被调用,onSaveInstanceState()
方法会携带一个Bundle类型的参数,Bundle提供了一系列的方法用于保存数据,比如可以使用putString()
方法保存字符串,使用putInt()
方法保存整型数据,每个保存方法需要传入两个参数,第一个参数是键,用于后面从Bundle中取值,第二个参数是真正要保存的内容。
在MainActivity中添加如下代码就可以将临时数据进行保存:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//检查是否有之前保留的数据
if(savedInstanceState!=null){
String tempData = savedInstanceState.getString("data_key");
Log.d(TAG, tempData);
}
Tips:Intent还可以结合Bundle一起用于传递数据,首先可以把需要传递的数据都保存在Bundle对象中,然后再将Bundle对象存放在Intent里。到了目标活动之后先从Intent中取出Bundle,再从Bundle中一一取出数据。
Activity的启动模式:standard/singleTop/singleTask/singleInstance
通过在AndroidManifest.xml中通过给<activity>
标签指定android:launchMode
属性来选择启动模式。
standard
standard是Activity默认的启动模式,在standard模式下,每当启动一个新的活动,它就会在返回栈中入栈,并处于栈顶的位置,对于使用standard模式的活动,系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动的一个新的实例。
singleTop
当活动的启动模式指定为singleTop,在启动活动时如果发现返回栈的栈顶已经是该活动,则认为可以直接使用它,不会再创建新的活动实例。
修改启动模式方法:在AndroidManifest.xml中
<activity
android:name=".FirstActivity"
//在此处修改
android:launchMode="singleTop"
android:label="This is FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
当MainActivity并未处于栈顶位置时,这时再启动MainActivity,还是会创建新的实例。
singleTask
当活动的启动模式指定为singleTask,每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的所有活动统统出栈(调用它们的onDestroy()
方法),如果没有发现就会创建一个新的活动实例。
singleInstance
指定为singleInstance的活动会启用一个新的返回栈来管理这个活动(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈)。singleInstance用来实现其他程序和我们的程序共享活动实例。
当处于新栈的活动(SecondActivity)跳转到新的默认启动模式的活动(ThirdActivity)时,新活动会和最初的活动(FirstActivity)在同一个栈,所以返回后会直接从ThirdActivity跳转到FirstActivity(因为位于同一个返回栈),当再Back时,由于第一个返回栈空了,所以会跳到第二个返回栈(即SecondActivity所在的返回栈)
Activity的最佳实践
知晓当前是在哪一个活动
首先新建一个BaseActivity类(New Java Class 即可,无需布局文件、注册),然后让BaseActivity继承自AppCompatActivity,并重写onCreate()
方法,如下所示:
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("BaseActivity", getClass().getSimpleName());
}
}
然后让项目中所有活动继承自BaseActivity即可,通过观察logcat中的打印信息即可知晓当前界面对应的是哪一个活动了。
随时随地退出程序
解决思路:用一个专门的集合类对所有的活动进行管理就可以了。
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<>();
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();
}
}
}
}
在活动管理器中,通过一个List来暂存活动,然后提供了addActivity()
方法用于向List中添加一个活动,提供了一个removeActivity()
方法用于从List中移除活动,最后提供了一个finishAll()
方法用于将List中存储的活动全部销毁掉。
接下来修改BaseActivity中的代码:
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("BaseActivity", getClass().getSimpleName());
//新增活动
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除活动
ActivityCollector.removeActivity(this);
}
}
从此以后,不管想在什么地方退出程序,只需要调用ActivityCollector.finishAll()
方法就可以了。
例如在ThirdActivity中点击按钮直接退出程序:
public class ThirdActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("ThirdActivity","Task id is "+getTaskId());
setContentView(R.layout.third_layout);
Button button3 = (Button) findViewById(R.id.button_3);
button3.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
//结束所有程序
ActivityCollector.finishAll();
}
});
}
}
还可以在销毁所有活动的代码后面再加上杀掉当前进程的代码,以保证程序完全退出:
android.os.Process.killProcess(android.os.Process.myPid());
其中,killProcess()
方法用于杀掉一个进程,它接收一个进程id参数,可以通过myPid()
方法来获得当前程序的进程id。需要注意的是,该方法只能用于杀掉当前程序的进程,不能杀掉其他程序。
启动活动的最佳写法:
在SecondActivity中添加actionStart()
方法:
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);
}
今后启动SecondActivity时,只需要一行代码:
SecondActivity.actionStart(FirstActivity.this, "data1","data2");
撸Dota2去咯!
Day2 Activity生命周期/启动模式/最佳实践的更多相关文章
- android83 Activity的生命周期,启动模式,返回时传递数据
#Android四大组件 * Activity * BroadCastReceiver * Service * ContentProvider #Activity生命周期 * oncreate:Act ...
- Android学习路线(十二)Activity生命周期——启动一个Activity
DEMO下载地址:http://download.csdn.net/detail/sweetvvck/7728735 不像其他的编程模式那样应用是通过main()函数启动的.Android系统通过调用 ...
- Activity的生命周期& 启动模式
1.Activity的生命周期 生命周期这个事情,是android工程师最基础的知识,所以今天要讲的是一些不一样的东西. 1.1 OnStart,OnResume,OnPause,OnStop 他们的 ...
- Activity生命周期以及启动模式对生命周期的影响(二)
前面一篇文章概述了Android四大组件之一的Activity生命周期方法的调用先后顺序,但对于非标准启动模式下Activity被多次调用时的一些生命周期方法并未详细阐述,现在针对该情况着重记录. 现 ...
- android Activity生命周期(设备旋转、数据恢复等)与启动模式
1.Activity生命周期 接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行.暂停和停止三种状态,onCreate.onStart.onResume.o ...
- android学习笔记 activity生命周期&任务栈&activity启动模式
activity生命周期 完整生命周期 oncreate->onstart->onresume->onpause->onstop->ondestory 使用场景:应用程序 ...
- Android查缺补漏--Activity生命周期和启动模式
一.生命周期 onCreate():启动Activity时,首次创建Activity时回调. onRestart():再次启动Activity时回调. onStart():首次启动Activity时在 ...
- activity生命周期实例(不同启动模式)
1.生命周期的几个阶段介绍: onCreate: 表示activity被创建,做一些初始化工作如调用setContentView去加载界面布局资源.初始化Acitivity所需数据等. onResta ...
- Activity生命周期以及启动模式对生命周期的影响
前天用户体验反馈的一个需求,要求每次进入应用都定位到首页;这个操作很明显不适合放在首页Activity(启动模式为SingleTask)的onResume中,如果对Activity的启动模式和生命周期 ...
随机推荐
- VERITA Netbackup日常巡检详细说明
VERITA备份日常监控 一. 相关检查方法.命令 1.1 启动NBU的图形管理界面: /usr/openv/netbackup/bin/jnbSA & 1.2字符界面命令: 1.2.1cat ...
- PHPmailer群发Gmail的常见问题
博主小白一枚,phpmailer只会一些基本的用法,就这样一个邮件的群发功能也难住了我一周,下面把我遇到的问题给大家总结一下 1.Could not authenticate 首先,如果你没有使用循环 ...
- redis 系列 在 vs上 set,get 键值
1.启动两个 cmd,一个用于打开服务,一个用于运行客户端. 详细步骤可见上一篇文章 2.下载nuget的 ServiceStack.Redis; ,并在using中引用 ,详细步骤可见上一篇文章 ...
- VC-基础:VS2010/MFC-1MFC消息映射
Windows消息分类 Windows消息分为系统消息和用户自定义消息.Windows系统消息有三种: 1.标准Windows消息.除WM_COMMAND外以WM_开头的消息是标准消息.例如,WM_C ...
- MyEclipse的快捷键大全(超级实用,方便)
常用快捷键 1. [ALT+/] 能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类.方法和属性的名字时,多体验一下[ALT+/]快捷键带来的好处吧. 2. [Ctrl+O] 显示类 ...
- 【shopex】真正可用的app开发机制
shopex的app开发机制详解 网上流传的shopex4.8.5的app开发教程,不仅说得不明不白,而且由于版本问题,照着做根本是做不成的. 知其然,亦要知其所以然. shopex提供了的一个干 ...
- vue学习笔记-:class
当items.state为true时使用class='rad2state',否则为rad2(默认).
- Python全栈day 03
Python全栈day 03 一.运算符补充 in ,逻辑运算符,判断某字符或某字符串是否在一个大的字符串中,输出得到bool型数据. value = '我是中国人' v = '我' if v in ...
- Python学习笔记:logging(日志处理)
在一个软件中,日志是可以说必不可少的一个组成部分,通常会在定位客户问题或者记录软件使用情况等场景中会用到.logging模板块是Python的一个内置标准库,用于实现对日志的控制输出,对于平常的日志输 ...
- Python学习之编程基础
学习Python之前首先我们要了解Python是什么? question 1:Python是什么? answer:Python是一门编程语言.(什么是编程语言?) 语言:语言是不同个体之间沟通的介质. ...