Android基础:Activity的生命周期

第一次写博客,就写一个比较简单的吧(也写不出难的东西),这个比较适合入门的萌新,大佬们请绕道。还有第一次写可能有很多不足,或者是写得比较啰嗦,所以有什么不足欢迎大家指正。

一. 返回栈

在讲activity的生命周期之前,我们先说明以下返回栈的概念

  • 其实Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack)。
  • 栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新的活动,它会在返回栈中入栈,并处于栈顶的位置。而每当我们按下Back键或调用finish() 方法去销毁一个活动时,处于栈顶的活动会出栈,这时前一个入栈的活动就会重新处于栈顶的位置。
  • 系统总是会显示处于栈顶的活动给用户。

下图展示了返回栈是如何管理活动入栈出栈操作的。
在这里插入图片描述

二. 活动的生存期

  • onCreate() 。
    这个方法会在活动第一次被创建的时候调用。你应该在这个方法中完成活动的初始化操作,比如说加载布局、绑定事件等。
  • onStart() 。
    这个方法在活动由不可见变为可见的时候调用。
  • onResume() 。
    这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态。
  • onPause() 。
    这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据,但这个方法的执行速度一定要快,不然会影响到新的栈顶活动的使用。
  • onStop() 。
    这个方法在活动完全不可见的时候调用。它和onPause() 方法的主要区别在于,如果启动的新活动是一个对话框式的活动,那么onPause() 方法会得到执行,而onStop() 方法并不会执行。
  • onDestroy() 。
    这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
  • onRestart() 。
    这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。

以上7个方法中除了onRestart() 方法,其他都是两两相对的,从而又可以将活动分为3种生存期。

  • 完整生存期 。
    活动在onCreate() 方法和onDestroy() 方法之间所经历的,就是完整生存期。一般情况下,一个活动会在onCreate() 方法中完成各种初始化操作,而在onDestroy() 方法中完成释放内存的操作。
  • 可见生存期 。
    活动在onStart() 方法和onStop() 方法之间所经历的,就是可见生存期。在可见生存期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两个方法,合理地管理那些对用户可见的资源。比如在onStart() 方法中对资源进行加载,而在onStop() 方法中对资源进行释放,从而保证处于停止状态的活动不会占用过多内存。
  • 前台生存期 。
    活动在onResume() 方法和onPause() 方法之间所经历的就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,我们平时看到和接触最多的也就是这个状态下的活动。

安卓官方的活动生命周期的示意图
在这里插入图片描述

三. 代码

首先我们得创建一个工程(这个就不用多说了),接着创建三个activity(如果一开始没有主activity的话,有主activity就创建两个新的activity),对应三个layout文件。

如下图所示:
在这里插入图片描述

1.xml文件

main_activity

<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>

normal_activity

<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>

dialog_activity

<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>

DialogActivity的活动布局跟NormalActivity活动布局看起来是是一样的,但是我接下来要把DialogActivity这个活动修改成对话框式的活动(对话框式活动就是在屏幕显示一个小对话框,相当于键盘的那种界面),这有助于我们理解activity的生命周期。

那么,如何设置呢?

修改AndroidManifest.xml的 标签的配置,如下所示:

<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使用对话框式的主题。

2.Java文件

接着就要写我们的Java代码了,当然,主要写的还是我们的MainActivity。

MainActivity

使用 logt 的快捷键先写个TAG,后面再用 logd 快捷键写 log.d() 日志就行了。

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate()");
        setContentView(R.layout.main_activity);
        Button normalac=(Button)findViewById(R.id.start_normal_activity);
        Button dialogac=(Button)findViewById(R.id.start_dialog_activity);
        normalac.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(MainActivity.this,NormalActivity.class);
                startActivity(intent);
            }
        });
        dialogac.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                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()");
    }

}

NormalActivity

@Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("NormalActivity", "onCreate()");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.normal_activity);
    }
    @Override
    protected void onStart() {
        super.onStart();
        Log.d("NormalActivity", "onStart() ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("NormalActivity", "onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("NormalActivity", "onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("NormalActivity", "onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("NormalActivity", "onDestroy()");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("NormalActivity", "onRestart()");
    }

DialogActivity

@Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("DialogActivity", "onCreate()");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_activity);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("DialogActivity", "onStart() ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("DialogActivity", "onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("DialogActivity", "onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("DialogActivity", "onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("DialogActivity", "onDestroy()");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("DialogActivity", "onRestart()");
    }

重写每一个生命周期的方法(加一个输出日志log.d),这样当程序走到哪一步的时候就会在logcat那里打印出日志,你就可以监控activity的活动了,最后运行代码就OK了。
到这里主要代码已经写完了!

最后就看成果了。

打开手机的APP后就是这个样子了(我用真机测试,你用虚拟机也行)
在这里插入图片描述
控制台输出
在这里插入图片描述

接着点第一个Button, START NORMALACTIVITY,进入第二个活动后再点BACK键返回第一个activity。

在这里插入图片描述
接着再点第二个Button,START DIALOGACTIVITY,跟上面一样操作。

接着打印出
在这里插入图片描述
很明显打开NormalActivity时打印的东西和打开DialogActivity时打印的日志是不一样的,因为DialogActivity活动时对话框活动,并没有关闭或者说时停止Mainactivity,因此MainActivity并没有执行onStop()方法。

到这里大家也差不多明白activity的生命周期了吧!

最后再给大家整理一下:

操作顺序为先打开activity A 再点开activity B(activity B为正常activity,非对话框类)

activity Aactivity B
onCreat()
onStart()
onResume()
onPause()
onCreat()
onStart()
onResume()
onStop()

关闭activity B,再关闭activity A。

activity Aactivity B
onPause()
onRestart()
onStart()
onResume()
onStop()
onDestory()
onPause()
onStop()
onDestory()

到这里所有activity的生命周期都已经结束了!

写到这里不容易(哭),毕竟是第一次写文章,感觉有点啰嗦了,大家将就着看吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值