之前断断续续地学了一些 Android 开发基础,也写过几个简单的 app,但都是特别简单的那种,还有很多知识学完了没有用过,现在已经忘得差不多了。最近找到一本书叫 Android 开发艺术探索(作者叫任玉刚,据说是百度的大牛),2015 年出版的,看完第一章后感觉不错,很适合我这种有点基础的人看,于是决定写个读书笔记,记录自己从书中学习到的知识。

第一章

本章主要介绍了 Activity 相关的一些内容。

1.1 Activity 的生命周期

正常情况下 Activity 的生命周期如下:

// 1.表示 Activity 正在被创建
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

// 2.表示 Activity 正在重新启动,当用户切换已经打开过的 Activity 时才会调用这个方法
@Override
protected void onRestart() {
    super.onRestart();
}

// 3.表示 Activity 正在被启动
@Override
protected void onStart() {
    super.onStart();
}

// 4.表示 Activity 已经可见
@Override
protected void onResume() {
    super.onResume();
}

// 5.表示 Activity 正在暂停
@Override
protected void onPause() {
    super.onPause();
}

// 6.表示 Activity 正在停止
@Override
protected void onStop() {
    super.onStop();
}

// 7.表示 Activity 正在销毁
@Override
protected void onDestroy() {
    super.onDestroy();
}

在某些特殊情况下,Activity 的生命周期可能会发生变化,比如屏幕旋转、内存不足等等,此时 Activity 会被销毁并重新创建,这种情况下会多出两个方法:

// 在 onStop() 方法之前被调用
// 用来保存相关数据
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("test", 123);
}

// 在 onStart() 方法后被调用
// 用来恢复数据,也可以在 onCreate() 方法中恢复,但要判断 savedInstanceState 是否为 null,这里就不需要
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    int value = savedInstanceState.getInt("test");
}

 如果我们不想系统重新创建 Activity,可以在 AndroidManifest.xml 中为 Activity 配置 configChanges 属性,此属性可以指定多个值(哎呀,无法插入 xml 代码好蛋疼):

<activity
android:name=”.MainActivity”
android:configChanges=”orientation|locale|keyboard|keyboardHidden|screenSize”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>

常用的就这么几个,分别表示屏幕旋转、本地设置改变(如切换语言)、键盘改变(如外接键盘)、键盘可访问性改变(显示或隐藏键盘)、屏幕尺寸改变(通常是因为屏幕旋转)。

同时,如果指定了 configChanges 属性,当相关事件发生时,系统会调用 Activity 的如下生命周期方法:

// 表示配置改变,可以根据需要做一些特殊处理
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    Log.d("TEST", "onConfigurationChanged: " + newConfig.orientation);
}

 1.2 Activity 的启动模式

Android 系统有一个 Activity 任务栈的概念,栈是一种后进先出的数据结构,那么任务栈中存放的 Activity 自然也是后进先出的。任务栈是 Android 系统管理 Activity 的方式,至于它的工作原理,这里暂时不做说明,我们主要关注的是 Activity 的启动模式。

Activity 有四种启动模式,分别为:

standard:标准模式,也是系统默认的启动模式,每次启动 Activity 都会创建一个实例,并执行相应的生命周期方法,每个 Activity 也都会被放入任务栈中;

singleTop:栈顶复用模式,如果要启动的 Activity 已经位于栈顶,则复用它,此时就不会调用 onCreate() 和 onStart() 方法,取而代之的是调用 onNewIntent() 方法;

singleTask:栈内复用模式,如果要启动的 Activity 在栈中存在,则复用它,生命周期方法同上,但此时系统会清空在任务栈中此 Activity 上面的所有其他 Activity(重点,拿小本本记下来);

singleInstance:单一实例模式,此种情况下,系统会为 Activity 创建一个单独的、独享的任务栈,如果要启动的 Activity 已经存在,则复用它,生命周期方法同上。

说了这么多,那么如何为 Activity 指定启动模式呢?

作者说了,有两种方法,第一种方法是在 AndroidManifest.xml 中配置:

<activity
android:name=".MainActivity"
android:configChanges="orientation|locale|keyboard|keyboardHidden|screenSize"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

第二种方法是通过代码指定:

private void testLaunchMode()
{
    Intent intent = new Intent(this, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    startActivity(intent);
}

 两种方法都可以指定 Activity 的启动模式,不过第一种方法不能设置 FLAG_ACTIVITY_CLEAR_TOP 标识,第二种方法不能指定 singleInstance 模式,但第二种方式的优先级要高于第一种,实际使用中应该根据需要灵活选择。

上面的代码中提到了 FLAG_ACTIVITY_SINGLE_TOP 和 FLAG_ACTIVITY_CLEAR_TOP,这是 Android 系统预定义的两个常量,是 Activity 的 Flags。系统预定义了很多这样的标识位常量,下面介绍几个常用的标识位:

FLAG_ACTIVITY_NEW_TASK:为 Activity 指定 singleTask 模式,效果和在 AndroidManifest.xml 中指定该模式相同;

FLAG_ACTIVITY_SINGLE_TOP:为 Activity 指定 singleTop 模式,除此之外同上;

FLAG_ACTIVITY_CLEAR_TOP:启动具有此标识位的 Activity,系统会清除与此 Activity 在同一栈中,且在其上面的所有 Activity,通常与 FLAG_ACTIVITY_NEW_TASK 配合使用;

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:表示要启动的 Activity 不在系统的最近任务列表中显示,效果同在 AndroidManifest.xml 中指定 android:excludeFromRecents=”true”。

1.3 节主要讲的是  IntentFilter 的匹配规则,内容也不少,下次再写吧。

版权声明:本文为andorxor原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/andorxor/p/9354926.html