onCreate
和onDestroy
是配对的,分别表示着Activity的创建和销毁,并且只可能有一次调用。onStart
和onStop
是配对的,是从Activity是否可见这个角度来回调的。(可见了,但没有出现在前台,我们还看不到)onResume
和onPause
是从Activity是否位于前台这个角度来回调的。onRestart
,表示Activity正在重新启动,当前Activity从不可见重新变为可见状态时,onRestart
就会被调用。onPause
之后,新的Activity才能onResume
onPause
、onStop
、onDestroy
均会被调用;onSaveInstanceState
来保存当前Activity的状态(在正常的情况下,系统不会回调这个方法);onRestroreInstanceState
,并且把Activity销毁时onSaveInstanceState
方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState
和onCreate
方法。(先onCreate
再onRestoreInstanceState
,官方推荐用onRestoreInstanceState
)onSaveInstanceState
和onRestoreInstanceState
,查看它们的具体实现就知道系统会自动保存View的哪些数据。在AndroidMainifest.xml
中加入Activity的声明:
android:configChanges = "orientation|keyboardHidden"
以上只是把orientation
和keyboardHidden
锁定,当触发时会回调onConfigurationChanged
(可在Activity重写)方法来代替onSaveInstanceState
。
完整代码可以是这样:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test20190122">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
application>
manifest>
onSaveInstanceState
和onRestoreInstanceState
来存储和回复数据。任务栈是一种“后进先出”的栈结构,每按一下back键,就会有一个Activity出栈,直到栈空位置,当栈中无任何Activity时,系统就会回收这个任务栈。
onCreate
、onStart
、onResume
都会被调用)ApplicationContext
去启动standard模式的Activity的时候会报错,因为非Activity类型的Context
(如ApplicationContext
)并没有所谓的任务栈。解决的方法是为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK
标记位,这样启动的时候就会为它创建一个新的任务栈。onNewIntent
方法会被回调(此方法可被重写,通过它的参数可以取出当前请求的信息)。onNewIntent
方法会被回调。onNewIntent
方法。(2)如果实例不存在,就创建Activity的实例并把Activity压入栈中。任务栈分为前台任务栈和后台任务栈,后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
AndroidMenifest.xml
为Activity指定启动模式。
Intent intent = new Intent();
intent.setClass(MainActivity.this,SecondActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
可用来设定Activity的启动模式,可用来影响Activity的运行状态。
FLAG_ACTIVITY_NEW_TASK
:为Activity指定“singleTask”启动模式。
FLAG_ACTIVITY_SINGLE_TOP
:为Activity指定“singleTop”启动模式。
FLAG_ACTIVITY_CLEAR_TOP
:具有此标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。(一般配合FLAG_ACTIVITY_NEW_TASK
使用)
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
:具有这个标记的Activity不会出现在历史Activity的列表中。(等用于在xml
中指定Activity的属性android:excludeFromRecents="true"
)
隐式调用启动Activity需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息。IntentFilter中的过滤信息有action、category、data。
一个Intent同时匹配action、category、data才算完全匹配,只有完全匹配才能启动目标Activity。
一个Activity中可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可启动对应的Activity。
示例:
<activity
android:name=".SecondActivity"
android:configChanges="screenLayout"
android:label="@string/app_name">
<intent-filter>
<action android:name="com.example.test20190122.c"/>
<action android:name="com.example.test20190122.d"/>
<category android:name="com.example.test20190122.category.c"/>
<category android:name="com.example.test20190122.category.d"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
intent-filter>
activity>
startActivity
或startActivityForResult
会默认为Intent加上android.intent.category.DEFAULT
;android.intent.category.DEFAULT
;category
,不管有几个,每个都要能够和过滤规则中的任何一个category
相同;<data
android:mimeType="string"
android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string" />
mimeType
和URI
。mimeType
指媒体类型(比如image/jpeg、audio/mpeg4-generic、video/*等),URI
的结构:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
URI
例子:
content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info
scheme
:URI的模式,比如,http、file、content等;
host
:URI的主机名,比如,www.baidu.com;
port
:URI的端口号,比如,80;
path
、pathPattern
、pathPrefix
:这三个参数表述路径信息。path
表示完整的路径信息;pathPattern
也表示完整的路径信息,它可以包含通配符“*”,“*”表示0个或多个任意字符。pathPrefix
表示路径的前缀信息。
inten-filter
指定了mimeType
,却没有指定URI
,URI
的的默认值为content
和file
;setDataAndType
方法,不能先调用setDate
再调用setType
,因为这两个方法彼此会清楚对方的值;例如:
intent.setDataAndType(Uri.parse("file://abc"),"image/png");
<intent-filter>
<data android:mimeType="file" android:host="www.baidu.com"/>
...
intent-filter>
<intent-filter>
<data android:mimeType="file"/>
<data android:host="www.baidu.com"/>
...
intent-filter>
Intent intent = new Intent("com.example.test20190122.a");
intent.addCategory("com.example.test20190122.b");
intent.setDataAndType(Uri.parse("file://abc"),"text/plain");
startActivity(intent);
PackageManager
的resolveActivity
方法或者Intent
的resolveActivity
方法。(它们找不到匹配的Activity就会返回null)resolveActivity
能够返回最佳匹配的Activity信息,而PackageManager
的queryIntentActivitis
能返回所有成功匹配的Activity信息。queryIntentActivitis
和resolveActivity
的原型是:public abstract List<ResolveInfo> queryIntentActivities(Intent intent,int flags);
public abstract ResolveInfo resolveActivity(Intent intent,int flags);
第二个参数,如果使用MATCH_DEFAULT_ONLY
这个标记位,就仅仅匹配在intent-filter中声明了
这个category
的Activity。这个标记位的意义在于,只要上述两个方法不返回null,那么startActivity
一定可以成功。因为不含有DEFAULT
这个category
的Activity是无法接收隐式Intent的。
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
这两者的共同作用是用来标明这是一个入口Activity,并且会出现在系统的应用列表中,但少了任何一个都没有实际意义。