第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

阅读数:29 2019 年 10 月 23 日 04:54

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

(活动的生命周期:体验活动的生命周期)

讲了这么多理论知识,也是时候该实战一下了,下面我们将通过一个实例,让你可以更加直观地体验活动的生命周期。

这次我们不准备在 ActivityTest 这个项目的基础上修改了,而是新建一个项目。因此,首先关闭 ActivityTest 项目,点击导航栏 File→Close Project。然后再新建一个 ActivityLifeCycleTest 项目,新建项目的过程你应该已经非常清楚了,不需要我再进行赘述,这次我们允许 Android Studio 帮我们自动创建活动和布局,这样可以省去不少工作,创建的活动名和布局名都使用默认值。

这样主活动就创建完成了,我们还需要分别再创建两个子活动——NormalActivity 和 DialogActivity,下面一步步来实现。

右击 com.example.activitylifecycletest 包→New→Activity→Empty Activity,新建 NormalActivity,布局起名为 normal_layout。然后使用同样的方式创建 DialogActivity,布局起名为 dialog_layout。

现在编辑 normal_layout.xml 文件,将里面的代码替换成如下内容:

复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is a normal activity"
/>
</LinearLayout>

这个布局中我们就非常简单地使用了一个 TextView,用于显示一行文字,在下一章中你将会学到更多关于 TextView 的用法。

然后再编辑 dialog_layout.xml 文件,将里面的代码替换成如下内容:

复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is a dialog activity"
/>
</LinearLayout>

两个布局文件的代码几乎没有区别,只是显示的文字不同而已。

NormalActivity 和 DialogActivity 中的代码我们保持默认就好,不需要改动。

其实从名字上你就可以看出,这两个活动一个是普通的活动,一个是对话框式的活动。可是我们并没有修改活动的任何代码,两个活动的代码应该几乎是一模一样的,在哪里有体现出将活动设成对话框式的呢?别着急,下面我们马上开始设置。修改 AndroidManifest.xml 的<activity>标签的配置,如下所示:

复制代码
<activity android:name=".NormalActivity">
</activity>
<activity android:name=".DialogActivity"
android:theme="@style/Theme.AppCompat.Dialog">
</activity>

这里是两个活动的注册代码,但是 DialogActivity 的代码有些不同,我们给它使用了一个android:theme属性,这是用于给当前活动指定主题的,Android 系统内置有很多主题可以选择,当然我们也可以定制自己的主题,而这里@style/Theme.AppCompat.Dialog则毫无疑问是让 DialogActivity 使用对话框式的主题。

接下来我们修改 activity_main.xml,重新定制主活动的布局,将里面的代码替换成如下内容:

复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/start_normal_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start NormalActivity" />
<Button
android:id="@+id/start_dialog_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start DialogActivity" />
</LinearLayout>

可以看到,我们在 LinearLayout 中加入了两个按钮,一个用于启动 NormalActivity,一个用于启动 DialogActivity。

最后修改 MainActivity 中的代码,如下所示:

复制代码
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG,"onCreate");
setContentView(R.layout.activity_main);
Button startNormalActivity = (Button) findViewById(R.id.start_normal_
activity);
Button startDialogActivity = (Button) findViewById(R.id.start_dialog_
activity);
startNormalActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, NormalActivity.class);
startActivity(intent);
}
});
startDialogActivity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, DialogActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart");
}
}

onCreate()方法中,我们分别为两个按钮注册了点击事件,点击第一个按钮会启动 NormalActivity,点击第二个按钮会启动 DialogActivity。然后在 Activity 的 7 个回调方法中分别打印了一句话,这样就可以通过观察日志的方式来更直观地理解活动的生命周期。

现在运行程序,效果如图 2.24 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.24 MainActivity 界面

这时观察 logcat 中的打印日志,如图 2.25 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.25 启动程序时的打印日志

可以看到,当 MainActivity 第一次被创建时会依次执行onCreate()onStart()onResume()方法。然后点击第一个按钮,启动 NormalActivity,如图 2.26 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.26 NormalActivity 界面

此时的打印信息如图 2.27 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.27 打开 NormalActivity 时的打印日志

由于 NormalActivity 已经把 MainActivity 完全遮挡住,因此onPause()onStop()方法都会得到执行。然后按下 Back 键返回 MainActivity,打印信息如图 2.28 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.28 返回 MainActivity 的打印日志

由于之前 MainActivity 已经进入了停止状态,所以onRestart()方法会得到执行,之后又会依次执行onStart()onResume()方法。注意此时onCreate()方法不会执行,因为 MainActivity 并没有重新创建。

然后再点击第二个按钮,启动 DialogActivity,如图 2.29 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.29 DialogActivity 界面

此时观察打印信息,如图 2.30 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.30 打开 DialogActivity 时的打印日志

可以看到,只有onPause()方法得到了执行,onStop()方法并没有执行,这是因为DialogActivity并没有完全遮挡住MainActivity,此时MainActivity只是进入了暂停状态,并没有进入停止状态。相应地,按下 Back 键返回 MainActivity 也应该只有onResume()方法会得到执行,如图 2.31 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.31 再次返回 MainActivity 的打印日志

最后在 MainActivity 按下 Back 键退出程序,打印信息如图 2.32 所示。

第一行代码:Android(2nd ed)(39):先从看得到的入手——探究活动 2.4.4

图 2.32 退出程序时的打印日志

依次会执行onPause()onStop()onDestroy()方法,最终销毁 MainActivity。

这样活动完整的生命周期你已经体验了一遍,是不是理解得更加深刻了?

评论

发布