Android Activity

来源:互联网 发布:国家外汇管理局 知乎 编辑:程序博客网 时间:2024/06/15 13:26

参考:

Activity:https://developer.android.com/guide/components/activities.html
任务和返回栈:https://developer.android.com/guide/components/tasks-and-back-stack.html


ActivityAndroid 系统中使用最频繁的组件,刚入门 Android 就需要使用它。Activity 包含了许多隐藏的知识,需要深入了解才能更好的使用它


主要内容

  1. Activity 浅析(Android Activity - 1
  2. 生命周期
  3. 退出情况分析(Android Activity - 2
  4. 任务与返回栈
  5. 启动模式
  6. BaseActivity.javaAndroid Activity - 3
  7. 清理返回栈
  8. 屏幕方向

Activity 浅析

ActivityAndroid 四个基本组件之一(Activity / Service / Broadcast Receiver / Content Provider

Activity 能够在屏幕上显示界面,同时能够和用户进行交互

声明

需要在 清单文件 上声明 Activity,在元素 <application> 下增加子元素 <activity>,示例如下:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.zj.activitydemo">    <application        ...        ...                    >        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity android:name=".Main2Activity" />    </application></manifest>

元素 <activity> 必须设置的属性是 android:name,用来指定 Activity 的类名

指定启动 Apk 后第一个 Activity,通过子元素 <intent-filter> 进行设置,内容如下:

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

显式启动

Activity 之间的跳转,需要使用函数 startActivity

void startActivity(Intent intent)

intent 中设定跳转的 Activity,如果需要传递信息,可以设置键值对,示例如下:

Intent intent = new Intent(MainActivity.this, Main2Activity.class);intent.putExtra("String", "var1");intent.putExtra("boolean", true);intent.putExtra("Integer", 3);startActivity(intent);

在目的 Activity 中调用函数 getIntent 获取 Intent 对象,解析键值对获取信息,示例如下:

Intent intent = getIntent();if (intent != null) {    String var1 = intent.getStringExtra("String");    boolean var2 = intent.getBooleanExtra("Boolean", true);    int var3 = intent.getIntExtra("Integer", 0);}

也可以设置 Bundle 对象:

Bundle bundle = new Bundle();bundle.putString("key", "value");intent.putExtra("bundle", bundle);

获取:

Bundle bundle = intent.getBundleExtra("bundle");String str = bundle.getString("key");

如果需要目的 Activity 能够反馈信息给当前 Activity,可以使用函数 startActivityForResult

void startActivityForResult (Intent intent, int requestCode)

除了设置 Intent 对象外,还需要设置参数 requestCode必须大于 0),比如:

Intent intent = new Intent(MainActivity.this, Main2Activity.class);startActivityForResult(intent, 100);

然后在目的 Activity 结束之前,调用函数 setResult:

void setResult (int resultCode)void setResult (int resultCode, Intent data)

参数 resultCode 作为结果码(result code)反馈给调用 Activity,通常是 Activity.RESULT_OK 或者 Activity.RESULT_CANCELED

参数 data 用来返回数据(需要的话

示例如下:

Intent intent = new Intent();intent.putExtra("Hello", "World");setResult(Activity.RESULT_CANCELED, intent);finish();

当目的 Activity 结束,返回到调用 Activity后,会调用函数 onActivityResult

void onActivityResult (int requestCode, int resultCode, Intent data)

参数 requestCode 和参数 resultCode 分别对应之前的参数设置,参数 data 用来保存目的 Activity 反馈给调用 Activity 的数据。示例如下:

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    switch (requestCode) {        case 100:            if (resultCode == RESULT_CANCELED) {                if (data != null) {                    String var = data.getStringExtra("Hello");                    Log.e(TAG, "onActivityResult: " + var);                }            }            break;        default:            super.onActivityResult(requestCode, resultCode, data);    }}

ActivityOptions

参考:ActivityOptions

打开 startActivity 的源码,发现它调用了一个重载函数:

/** * Same as {@link #startActivity(Intent, Bundle)} with no options * specified. * * @param intent The intent to start. * * @throws android.content.ActivityNotFoundException * * @see #startActivity(Intent, Bundle) * @see #startActivityForResult */@Overridepublic void startActivity(Intent intent) {    this.startActivity(intent, null);}

调用函数 startActivity(Intent, Bundle)支持最低版本是 Android 4.1(API 16))

void startActivity (Intent intent, Bundle options)

那么参数 options 有什么用呢,查看源码中对于 options 参数的解释:

...... * @param intent The intent to start. * @param options Additional options for how the Activity should be started. * See {@link android.content.Context#startActivity(Intent, Bundle) * Context.startActivity(Intent, Bundle)} for more details....    @Overridepublic void startActivity(Intent intent, @Nullable Bundle options) {    if (options != null) {        startActivityForResult(intent, -1, options);    } else {        // Note we want to go through this call for compatibility with        // applications that may have overridden the method.        startActivityForResult(intent, -1);    }}

Bundle options 参数是关于 Activity 如何启动的选项

继续查看 android.content.Context#startActivity(Intent, Bundle) 的解释:

Bundle: Additional options for how the Activity should be started.May be null if there are no options. See ActivityOptions for how to build the Bundle supplied here; there are no supported definitions for building it manually.

可以使用 ActivityOptions 来构建这个 Bundle 对象,设置 Activity 的启动画面

具体如何设置,等待以后学习

退出

点击屏幕 回退 键可以退出当前 Activity,也可以使用函数 finish 手动退出:

/** * Call this when your activity is done and should be closed.  The * ActivityResult is propagated back to whoever launched you via * onActivityResult(). */public void finish() {    finish(DONT_FINISH_TASK_WITH_ACTIVITY);}

还有一个函数 finishActivity 可用来结束上一个 Activity,不过测试过后发现并没有效果,在网上查了很多资料也没有一个很好的解释,等待日后解决


生命周期

Android 系统将 Activity 从创建到销毁的整个生命周期分为多个阶段,每个阶段均有回调函数,根据不同的回调函数,执行相应的操作

基本状态

Android 基本状态包括:

  • 创建:启动 Activity
  • 运行:Activity 位于前台并具有用户焦点
  • 暂停:另一个 Activity 位于前台并具有用户焦点,当前 Activity 仍可见
  • 停止:Activity 位于后台,对用户不可见,可能会被 Android 系统终止
  • 恢复:Activity 从后台回到前台并获取用户焦点
  • 终止:退出 Activity

基本生命周期回调函数

根据 Activity 的基本状态,其基本回调函数包括:

  • onCreate
  • onRestart
  • onStart
  • onResume
  • onPause
  • onStop
  • onDestroy

流程图如下所示:

这里写图片描述

两个 Activity 之间生命周期回调函数顺序

当前 Activity 启动新的 Activity 时,两个 Activity 对应的生命周期回调函数会有交叉现象,比如,Activity A 启动了 Activity B,相应的回调函数顺序如下:

  • Activity A 执行暂停,调用 onPause(此时 Activity A 仍处于可见状态)
  • 新建 Activity B 依次调用 onCreate -> onStart -> onResume(此时 Activity B 位于前台并具有用户焦点)
  • 此时 Activity B 已不可见,然后调用 onStop

然后从 Activity B 返回到 Activity A,相应的回调函数顺序如下:

  • Activity B 执行暂停,调用 onPause
  • Activity A 重新回到前台,依次调用 onRestart -> onStart -> onResume
  • Activity B 停止并退出,依次调用 onStop -> onDestroy

测试

下面进行测试说明生命周期回调顺序

新建 BaseActivity.java,用于打印所有的回调函数运行过程:

public class BaseActivity extends AppCompatActivity {    private static final String TAG = "BaseActivity";    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d(TAG, "onCreate: " + getLocalClassName());    }    @Override    protected void onRestart() {        super.onRestart();        Log.d(TAG, "onRestart: " + getLocalClassName());    }    @Override    protected void onStart() {        super.onStart();        Log.d(TAG, "onStart: " + getLocalClassName());    }    @Override    protected void onResume() {        super.onResume();        Log.d(TAG, "onResume: " + getLocalClassName());    }    @Override    protected void onPause() {        super.onPause();        Log.d(TAG, "onPause: " + getLocalClassName());    }    @Override    protected void onStop() {        super.onStop();        Log.d(TAG, "onStop: " + getLocalClassName());    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.d(TAG, "onDestroy: " + getLocalClassName());    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        Log.d(TAG, "onActivityResult: " + getLocalClassName());    }    @Override    protected void onNewIntent(Intent intent) {        super.onNewIntent(intent);        Log.d(TAG, "onNewIntent: ");    }}

情况一:启动 MainActivity,锁屏,然后将应用退到后台,最后退出

启动 MainActivity,经过回调函数 onCreate -> onStart -> onResume

这里写图片描述

屏幕锁屏,经过回调函数 onPause -> onStop

这里写图片描述

屏幕解锁,重新回到应用,经过回调函数 onRestart -> onStart -> onResume

这里写图片描述

点击 主页 键,将应用退到后台,经过回调函数 onPause -> onStop

这里写图片描述

点击应用启动器,将应用重新回到前台,经过回调函数 onRestart -> onStart -> onResume

这里写图片描述

退出应用,经过回调函数 onPause -> onStop -> onDestroy

这里写图片描述

情况二:启动 MainActivity,并跳转到 Main2Activity,然后回退到 MainActivity,最后退出应用

使用函数 startActivityForResult 进行跳转

启动 MainActivity,经过回调函数 onCreate -> onStart -> onResume

这里写图片描述

点击按钮,跳转到 Main2Activity

首先经过 MainActivityonPause

然后经过 Main2ActivityonCreate -> onStart -> onResume

最后经过 MainActivityonStop

这里写图片描述

点击回退按钮,从 Main2Activity 返回到 MainActivity

首先经过 Main2ActivityonPause

然后经过 MainActivityonActivityResult -> onRestart -> onStart -> onResume

最后经过 MainActivityonStop -> onDestroy

这里写图片描述

原创粉丝点击