Android Activity 完全解析(上)

来源:互联网 发布:辛普森有没有杀妻 知乎 编辑:程序博客网 时间:2024/05/29 19:31

       学习 Android 恐怕打交道最多的就是 Activity,只要是我们看到的界面上的东西,几乎都是以 Activity 为载体的,它是一种包含用户界面的组件,用于和用户进行交互,Activity 是基础中的基础,但越是基础的东西,我们就有可能忽视它的重要性,这样我们的基础就会不扎实,所以即使是基础的东西,我们还是很有必要去花时间尽力好好分析一下的,下面我们对活动进行详细的介绍,说到活动恐怕活动的生命周期我们就不得不去研究,来看概览图




Activity 的生命周期全面分析:


一、正常情况下一个 Acitivity 会经历如下的生命周期:


Activity经典生命周期图,来自Google官网



1)onCreate

这是 Activity 生命周期的第一个方法,这个方法相信我们已经看到了很多次,每个活动我们都重写了这个方法,它会在活动第一次被创建的时候调用,在这个方法中我们可以去做一些初始化的操作,比如调用 setContentView 去加载页面的布局,初始化 Activity 所需的数据等

2)onStart

这个方法在活动由不可见变为可见时调用,这时 Activity 已经可见了,但是还没有出现在前台,还不能和用户进行交互,我们可以理解为 Activity 已经有了,但我们还看不见

3)onResume

这里 Activity 已经可见了,可以和用户进行交互了,这时 Activity 处于栈顶,正在运行,这里要注意和 onStart 进行区分,可以理解为 onStart 和onResume 都表示 Activity 可见,但 onStart 的时候 Activity 还在后台,用户不可见,onResume 的时候在前台,用户可见

4)onPause

这个方法表示 Activity 正在停止,但还没有真正的停止,我们通常在这个方法中将一些消耗资源东西释放,可以存储一些关键的数据,但一定不能做耗时的操作,要不会意向下一个活动的使用

5)onStop

表示 Activity 即将停止,在 Activity 完全不可见得时候调用,可以做一些回收工作,也不能太耗时,这里要注意和 onPause 方法的区分,它和 onPause 方法的主要区别在于,如果新启动的方法是一个对话框式的活动,onPause 方法执行,onStop 方法不执行

6)onDestroy

表示 Activity 即将被销毁,对应于 onCreate 方法,这是 Acitivty 生命周期方法的最后一个回调方法,活动的状态将变为销毁状态

7)onRestart

这个方法在活动由停止状态变为运行状态时调用,这时候活动就是被重新启动了


上面这些都是一些理论的东西,下面我们就来真正的运行代码来看看 Activity 真正的执行情况

/** * 生命周期测试MainActivity */public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private static final String TAG = "MainActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if (savedInstanceState != null) {            String data = savedInstanceState.getString("key");        }        Log.i(TAG, "MainActivity: onCreate");    }    @Override    protected void onStart() {        super.onStart();        Log.i(TAG, "MainActivity: onStart");    }    @Override    protected void onResume() {        super.onResume();        Log.i(TAG, "MainActivity: onResume");    }    @Override    protected void onPause() {        super.onPause();        Log.i(TAG, "MainActivity: onPause");    }    @Override    protected void onStop() {        super.onStop();        Log.i(TAG, "MainActivity: onStop");    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.i(TAG, "MainActivity: onDestroy");    }    @Override    protected void onRestart() {        super.onRestart();        Log.i(TAG, "MainActivity: onRestart");    }    @Override    protected void onSaveInstanceState(Bundle outState) {        super.onSaveInstanceState(outState);        String data = "hello";        outState.putString("key", data);    }    @Override    public void onClick(View v) {        Intent intent = new Intent(MainActivity.this,SecondActivity.class);        startActivity(intent);    }}

这里我们创建了一个 MainActivity 并且重写了 Activity 生命周期的方法,这时候我们运行程序,在 Log 的控制台可以看到如下打印

MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume

这里正好验证了我们上面的理论,这时候我们用户可见,调用 onResume 方法

然后我们点击后退按钮,我们再来看一下控制台的打印内容

MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume
MainActivity: MainActivity: onPause
MainActivity: MainActivity: onStop
MainActivity: MainActivity: onDestroy

这时候一个 Activity 完整的生命周期就执行完毕了

接下来我们不点击后退键,我们点击 Home 键来看一下生命周期的情况

MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume
MainActivity: MainActivity: onPause
MainActivity: MainActivity: onStop

这里要注意 Activity 并没有去执行 onDestroy,这里 Activity 只是变成了不可见状态,并没有被销毁,我们再点击打开应用

MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume
MainActivity: MainActivity: onPause
MainActivity: MainActivity: onStop
MainActivity: MainActivity: onRestart
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume

这里注意到应用并没有调用 onCreate 重新创建,而是只调用了 onRestart,onStart,onResume 方法

这里我们就把在正常情况下的一个 Activity 的生命周期情况介绍完毕,总结如下:


二、多个 Activity 交互的生命周期:


这里我们新建一个 SecondActivity 类,我们在 MainActivity 中设置一个点击按钮,用来跳到 SecondActivity,并且和 MainActivity 一样复写生命周期的方法如下

/** * 生命周期测试SecondActivity */public class SecondActivity extends AppCompatActivity {    private static final String TAG = "SecondActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);        Log.i(TAG, "SecondActivity: onCreate");    }    @Override    protected void onStart() {        super.onStart();        Log.i(TAG, "SecondActivity: onStart");    }    @Override    protected void onResume() {        super.onResume();        Log.i(TAG, "SecondActivity: onResume");    }    @Override    protected void onPause() {        super.onPause();        Log.i(TAG, "SecondActivity: onPause");    }    @Override    protected void onStop() {        super.onStop();        Log.i(TAG, "SecondActivity: onStop");    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.i(TAG, "SecondActivity: onDestroy");    }    @Override    protected void onRestart() {        super.onRestart();        Log.i(TAG, "SecondActivity: onRestart");    }}

现在我们来看分析生命周期的运行情况:首先打开 MainActivity,控制台打印生命周期运行如下:

MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume

这时候我们再点击跳转按钮,控制台打印生命周期如下:

MainActivity: MainActivity: onPause
SecondActivity: SecondActivity: onCreate
SecondActivity: SecondActivity: onStart
SecondActivity: SecondActivity: onResume
MainActivity: MainActivity: onStop

这里我们思考如下内容

1)为什么要先调用 onPause 方法暂停当前显示的 MainActivity

2)为什么要等 SecondActivity 的 onCreate,onStart,onResume 方法执行完才执行 MainActivity的 onStop 方法,为什么不先执行当前 MainActivity的 onPause,onStop 方法呢?

分析如下:

在 MainActivity 打开 SecondActivity 的时候,会先执行 MainActivity 的 onPause 方法,然后执行 SecondActivity 的 onCreate、onStart、onResume 方法,完了再执行 MainActivity 的 onStop 方法,这里面还是有一种思想的,首先执行 MainActivity 的 onPause 方法是要关闭当前 MainActivity 的一些状态信息,如音频,视频等的状态,以免对新打开的 Activity 造成影响,试想我们正在听歌或看电影,这时候打进来一电话,如果我们不把当前的 Activity 先onPause 掉,会使一种怎样的体验,一边听歌,一遍打电话,不敢想象这样的场景,那么为什么又是在 MainActivity 执行完 onPause 而没有 onStop 的情况下就先执行 SecondActivity 的 onCreate,onStart,onResume 方法然后再执行 onStop 方法呢,这是因为考虑到如果在打开 SecondActivity 开启时发生 crash 的情况,这样如果 MainActivity 执行了 onStop 方法则会变为不可见状态,就会呈现出黑屏状态,用户什么都看不到。


三、横竖屏切换的时候 Acitivity 的生命周期:


打开 MainActivity,控制台打印情况如下:

MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume

这时候我们切换为横屏,看一下控制台的打印情况:

MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume
MainActivity: MainActivity: onPause
MainActivity: MainActivity: onStop
MainActivity: MainActivity: onDestroy
MainActivity: MainActivity: onCreate
MainActivity: MainActivity: onStart
MainActivity: MainActivity: onResume

还有就是在我们横竖屏切换的时候 Acitivity 的生命周期先是销毁掉然后会重新创建,所以我们展示的数据要在 onSaveInstanceState 方法中去保存数据,在 MainActivity 中添加如下代码就可以降临时数据进行保存:

    @Override    protected void onSaveInstanceState(Bundle outState) {        super.onSaveInstanceState(outState);        String data = "hello";        outState.putString("key",data);    }

这样数据就保存下来了,那么我们在哪里进行恢复呢?相信我们在一个地方经常看到这个 Bundle savedInstanceState,对,就是在我们的 onCreate 方法里面也有吧一个 Bundle 类型的参数,这个参数一般情况下都是 null,但是如果在活动被系统回收之前通过 onSaveInatanceState 方法来保存数据的话,这个参数就会带有之前所保存的所有数据,我们只需要通过如下方法取出:

  @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if (savedInstanceState != null) {            String data = savedInstanceState.getString("key");        }        Log.i(TAG, "MainActivity: onCreate");    }

取值之后再做相应的操作就好了


四、如何启动系统的 Activity:


启动浏览器

@Override    public void onClick(View v) {        Intent intent = new Intent();        intent.setAction(Intent.ACTION_VIEW);        Uri url = Uri.parse("https://www.baidu.com");        intent.setData(url);        startActivity(intent);    }

启动相册:

@Override    public void onClick(View v) {        Intent intent = new Intent();        intent.setAction(Intent.ACTION_GET_CONTENT);        intent.setType("image/*");        startActivity(intent);    }

发送短息:

 @Override    public void onClick(View v) {        Intent intent = new Intent();        intent.setAction(Intent.ACTION_SEND);        intent.setType("text/plain");        intent.putExtra(Intent.EXTRA_TEXT,"hello");        startActivity(intent);    }

启动电话界面:

 @Override    public void onClick(View v) {        Intent intent = new Intent();        intent.setAction(Intent.ACTION_VIEW);        Uri url = Uri.parse("tel:123456");        intent.setData(url);        startActivity(intent);    }

如果想更多的去学习,可以去查看 Intent 相关的 API点击打开链接



0 0
原创粉丝点击