1.3 清单文件中的Activity
清单文件中的Activity
Activity是一个应用组件,每个Activity都会获得一个用户绘制用户界面的窗口。窗口通常充满屏幕,但也可以小于屏幕浮在其它窗口上。
一个应用通常由多个彼此松散的Activity组成。一般一个应用会指定一个Activity为主Activity,首次启动应用的时候,会呈现给用户主Activity。
在清单文件(AndroidManifest.xml)中声明
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
<activity>元素主要属性
属性名 | 作用 |
---|---|
android:name | 组建名,Activity源文件所在的相对路径 |
android:screenOrientation | Activity在屏幕当中显示的方向 |
android:configChanges | Activity捕捉设备状态变化。 当所指定属性(Configuration Changes)发生改变时,回调 onConfigurationChanged()函数。 1. 设备旋转(orientation), 2. 键盘隐藏(keyboardHidden), 3. 屏幕尺寸(screenSize) |
android:exported | 表示该组件是否能够被其它应用程序组件调用或者交互。 该属性默认值依赖于它所包含得过滤器(intent-filter)。 如果没有 intent-filter ,则表明该组件只能通过显示Intent调用,所以默认值为false。如果含有 intent-filter ,则表明该组件能通过隐式Intent调用,所以默认值为true。 |
android:launchMode | activity启动模式。四种: Standard,SingleTop,SingleTask,SingleInstance |
android:taskAffinity | Activity所吸附的任务栈,该属性一般在lauchMode为singleTask模式才生效。默认taskAffinity于根Activity相同,即应用的包名。 |
android:windowSoftInputMode | 键盘弹出后,界面调整模式 1. 当获取焦点时是否弹出键盘 2. 是否减少Activity主窗口大小以腾出空间给软键盘 |
android:allowTaskReparenting | 当某个拥有相同affinity任务栈即将返回前台时,当前Activity是否能从启动它得任务栈中转移到与它相同Affinity相同任务栈中去。 默认值,false,只能停留在启动它得任务栈。 利用该值的特性,可以强行让一个不再显示的Activity转移到另外的任务栈中。 典型的应用,就是让一个程序的Activity转移到另外的应用程序中。 |
android:alwaysRetainTaskState | 系统是否一直维持任务栈的状态。该属性只对任务栈根Activity有效,默认值false。 通常,用户从launch界面重新打开应用的时候,系统会清空任务栈中根Activity以上所有Activity,比如说,用户停留在主界面很长时间没有操作了。 当将该值设置为true的时候,总是返回任务的最后状态,比如说,浏览器应用打开了多个页面,用户不期望下次打开浏览器的时候,之前的页面全部清空了。 |
android:clearTaskOnLaunch | 每次从launch启动应用时,是否清楚根Activity以上所有的Activity,默认值false |
android:enabled | 该组件是否能够被实例化。默认true |
android:excludeFromRecents | 该Activity是否排除在用户最近任务列表。默认值false。 |
android:finishOnTaskLaunch | 当从launch再次启动任务时,是否finish该实例,默认值false。 |
android:multiprocess | 是否可以把Activity新实例放入到启动它的组件所在的进程中。 |
Intent
Intent是一个消息传递对象。Intent作用
- 指定当前组件的动作
- 组件之间传递数据
Intent 有两种,一种是显示Intent,一种是隐式Intent。
- 显示Intent 按名称指定要启动的组件。在自己应用内使用显示Intent来启动组件。
- 隐式Intent 不指定特定的组件,而是在AndroidManife.xml文件中声明要执行的常规操作,从而容许其它应用中的组件来处理它。
intent-filter
在使用隐式Intent启动组件的时候,Android系统会通过Intent中的三个信息action
data
category
与在AndroidManifest.xml文件中注册的组件中的intent-filter
进行比较,当匹配一致的时候,启动对应的组件。
在清单文件中intent-filter
有三个元素action
data
category
,Intent的过滤器(intent-filter),按照以下优先关系查找:action->data->category
action
intent-filter
必须包含一个,或者多个action
元素,否则该组件匹配不到任何的Intent。Intent中的action与其中的任一个action在字符串形式上完全相同,action方面就匹配成功。系统定义了一些标准的action属性,比如ACTION_MAIN
代表Application入口,ACTION_VIEW
,ACTION_WEB_SEARCH
等
data
data由两部分组成mimeType和URI,data可以仅设置其中一项,或者都设置。
- mimeType 是指媒体类型,例如imgage/jpeg,auto/mpeg4和viedo/*等
- URI 则是由scheme、host、port、path | pathPattern | pathPrefix这4部分组成
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern >]
category
Intent中如果出现了category,不管几个category,对于每个category来说,他必须是过滤器中定义的category,才能匹配成功。系统默认设置了Intent的category为android.intent.category.DEFAULT
隐式Intent实例
1. 通过浏览器打开网页
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
2. 通过网页打开本地应用
网页html
</html>
<body>
<div id="header">
<a href="my.special.scheme://192.168.2.126/param1/param2">link open app
</a>
</div>
</body>
</html>
当点击网页上超链接"link open app"时,会隐式启动我们在清单文件中注册的Activity,清单文件AndroidManifest.xml内容如下:
<activity android:name=".intentfilter.IntentFilterTestActivity" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="my.special.scheme"/>
</intent-filter>
</activity>
Activity启动方式launchMode
在理解launchMode属性前,先要理解taskAffinity属性,Affinity英文翻译为吸附, 可以简单的理解为任务相关性。
- 这个参数标识了一个Activity所需任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。
- 可以单独指定每一个Activity的taskAffinity属性覆盖默认值
- 一个任务的affinity决定于这个任务的根activity(root activity)的taskAffinity
- 在概念上,具有相同的affinity的activity(即设置了相同taskAffinity属性的activity)属于同一个任务。
- 为一个activity的taskAffinity设置一个空字符串,表明这个activity不属于任何task。
taskAffinity属性不对standard和singleTop模式有任何影响,即时你指定了该属性为其他不同的值,这两种启动模式下不会创建新的task
Standard 标准模式
image当前任务栈内已经有AActivity
实例,以Standard模式启动AActivity
,会新建实例,并入栈。
总结:
- Activity默认的启动模式,该模式下,每次启动Activity都会新建Activity实例
singleTop 栈顶复用模式
image当以singleTop模式启动Activity时
- 若当前任务栈中没有该实例,或者该实例不是在栈顶,则启动方式和Standard相同,会新建Activity实例
- 若当前任务栈中含有该实例,并且在当前Activity任务栈的栈顶,此时不会新建Activity实例,只会触发位于栈顶实例Activity的
onNewIntent(Intent intent)
方法。
singleTask 栈内复用模式
image image总结:
当singleTask模式启动Activity时,首先会根据taskAffinity去寻找当前是否存在一个对应名字的任务栈
- 若当前任务栈中含有该实例,会复用该实例,回调
onNewIntent(Intent intent)
方法,并且将栈内位于singleTask以上的Activity清空 - 若当前任务栈中没有该实例,则会新建实例,在新建实例时,如果taskAffinity属性和启动它的Activity taskAffinity属性不一样,则会创建新的任务栈。如果当前存在taskAffinity值相同的Activity任务栈的时候,会将新创建的Activity实例,放入到taskAffinity值相同的任务栈中。
singleInstance 全局单例模式
该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例。