本文只是一些个人的总结,如有写的不对的,欢迎各路大神指正.
一、activity的启动方式
启动方式分为显示启动和隐式启动,显示启动就是直接指定要启动的activity,隐式启动的话就是没有指明要启动的activity,只要是符合自己要求的都会被启动。
1、显式启动
Intent intent=new Intent(this,B_Activity.class);
startActivity(intent);
显示启动可以设置flags,不同的flags有不用的效果
- flages的使用
//常用的flag:
//清空当前的任务栈中所有activity,然后将目的activity放入栈中,而且只能与FLAG_ACTIVITY_NEW_TASK联合使用
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
//创建一个新的任务栈,然后将目的activity放入新的任务栈中
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//如果任务栈中存在目的activity的实例,将关闭同栈中处于目的activity顶上的其他activity,使目的activity处于栈顶,
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//将目的activity设置为栈顶复用模式
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//不使用跳转动画
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
2、隐式启动
在启动activity的时候不明确要启动哪个,需要匹配在manifest文件中activity的intent-fliter,只有action、category和data完全匹配时才能启动。
- action的理解
action的值为一个字符串,它代表了系统中已经定义的一系列的动作,使用不同的action可以实现不同的效果,比如打电话、发送短信、打开网页等,默认是“DEFAULT”
- category
category用于指定action被执行的环境,通过addCategory()或者在Manifest文件中设置,默认是“CATEGORY_DEFAULT”
- data
通常是URI格式定义的操作数据,如: tel:// ,通过setData()设置
- Extras
主要用于传递目标组件所需额外的数据,通过putExtras()设置。
二、activity的启动模式
1、标准模式(standed)
理解:每次使用intent都会创建一个目的activity的实例。
2、栈顶复用(singlieTop)
理解:启动目的activity时,如果当前任务栈中存在该目的activity,且该activity处于栈顶时不会创建新的activity,否则会创建新的activity,此时效果和标准模式一样。比如栈中从上往下依次存在ABCD四个activity,此时如果使用栈顶复用模式启动A,不会再创建A的实例,继续使用栈顶的A,并会调用A的onNewIntent方法;如果此时启动的B或者C或D,因为B、C、D不处于栈顶,所以会创建他们的新的实例。
和FLAG_ACTIVITY_SINGLE_TOP作用一致
3、栈内复用(singleTask)
理解:启动目的activity时,如果栈内存在目的activity的实例,且处于栈顶,则效果和栈顶复用一样,如果该实例不在栈顶,就会将该目的activity的实例移到栈顶,并且将处于它上方的activity都关闭。比如:栈中从上到下存在ABCD四个activity,使用栈内复用模式启动D时,ABC会被关闭,是D处于栈顶,并且调用D的onNewIntent方法。
和FLAG_ACTIVITY_CLEAR_TOP作用一致
4、singInstance
理解:使用这种模式启动的activity,系统会创建一个新的任务栈,而且栈中只有这一个activity。单栈单例模式。
三、activity的启动过程(源码相关)
在手机桌面点击app图标启动app
其实手机桌面也相当于是一个app程序(Launcher),点击启动图标,会触发item的点击事件,此时Launcher会获取要启动的app的MainActivity信息,然后通过Binder机制与ActivityManagerService进行多次通讯,最终启动activity。
第一步、Launcher通知AMS(ActivityManagerService)启动App的MainActivity
第二步、AMS记录要启动的activity信息,并回复Launcher,需要Launcher处于Pause状态
第三步、Launcher收到消息让自己处于pause状态,然后告知AMS已经处于pause状态,可以启动App的MainActivity了
第四步、AMS没有启动过app的MainACtivity,会创建新的进程,并在新的进程中创建ActivityThread(主线程),并执行main方法
第五步、创建好主线程以后告知AMS,并传入Application进行通讯
第六步、AMS通知App绑定application,并启动App的MainActivity
第七步、启动MainActivity,并创建和关联context,执行onCreate()
四、activity的声明周期
<此处借用网上的一张图片>
五、activity的状态改变(横竖屏切换)
activity的状态改变一般是指activity的配置发生了改变,比如横竖屏的切换,此时activity会调用onSaveInstanceStae()对当前activity的一些数据进行保存,关闭activity,然后重启activity,调用onCreate()和onRestoreInstanceState()进行数据的恢复。
横竖屏切换:
- 在manifest文件中设置screenOrientation的值
<activity android:name=".B_Activity"
android:screenOrientation=""
/>
有以下几种值:
"unspecified":默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的显示方向.
"landscape":横屏显示(宽比高要长)
"portrait":竖屏显示(高比宽要长)
"user":用户当前首选的方向
"behind":和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
"sensor":有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换。
"nosensor":忽略物理感应器,这样就不会随着用户旋转设备而更改了。
- 通过代码设置
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
注意:横竖屏在切换的时候会重新启动activity,所以在切换的时候要及时保存已有数据(onSaveInstanceState()),以及恢复数据(onRestoreInstanceState())。