Advertisement

Activity看这篇就够了

阅读量:

文章目录

  • Activity是什么?

  • 如何操作Activity?

  • 在执行action时:

    • 进行category方面的对应配对
    • 考虑到data的具体信息进行相应的配对
    • 精确地处理URI方面的对应关系
  • 最终完成mimeType的配对过程。

  • activity的生命周期

    • 启动新的activity
    • 配置文件发生更改
    • 退出activity
    • onSaveInstanceState和onRestoreInstanceState这两个方法
  • Android的任务优先级栈及其启动机制

    • 启动模式的分类情况如何?
    • 在intent中设置了哪些标志位来影响启动模式?
      • 这些标志位将如何影响activity的执行流程?
      • 请详细说明intent标志位的作用。
      • 需要特别注意哪些特定场景下的intent设置?
      • 如何通过intent参数配置不同的start-up流程?

什么是Activity?

在Android四大组件中,Activity的使用频率最高。作为呈现用户界面的主要方式之一,它不仅被广泛用于操作交互,并且也是实现其他功能的基础模块。

怎么使用Activity?

使用Activity有两种方式一种是显示调用,一种是通过隐式调用。

显示调用直接用类名进行调用,这个比较简单就没啥好说的了。

复制代码
    context.startActivity(Intent(context, ActivitySecondActivity::class.java))
    
    
      
    
    代码解读

隐式调用有多不同,而是通过action+category+data来匹配的。

例如:
首先声明IntentFilter

复制代码
    <activity android:name=".ActivitySecondActivity">
    <intent-filter>
        <action android:name="com.wfeii.second" />
        <category android:name="com.wfeii,category" />
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
    </activity>
    
    
      
      
      
      
      
      
      
      
    
    代码解读
复制代码
    val intent = Intent()
    intent.action = "com.wfeii.second"
    intent.addCategory("com.wfeii,category")
    intent.setType("image/png")
    context.startActivity(intent)
    
    
      
      
      
      
      
    
    代码解读

隐式规则的匹配有三部分,1. action的匹配,2 category的匹配,3. data的匹配。

action的匹配

Action被视为一个字符串类型。我们能够调用系统预设的Action实例。此外还可以自定义属于自己的Action类型。在intent-filter配置中支持设置多个Action选项。在隐式调用场景下,若Intent中的Action与intent-filter中的任意一个完全一致,则判定为匹配成功。

category的匹配

category被视为一个字符串类型 ,同时支持使用系统预定义的 category 配置 。 intent 中允许主动通过 addCategory 方法进行扩展配置 ,并且也可以选择不进行此类操作 。 当 intent 中主动添加 category 时 ,则要求该 category 必须与 intent-filter 中的声明完全一致才能实现匹配成功 。 如果不主动添加 ,则 intent 会自动包含 default category 'android.intent.category.DEFAULT'

data的匹配

data相关的匹配包含两部分,一个是URI的匹配,一个是mimeType的匹配。

URI的匹配

一个URI由若干部分构成:
scheme://host: port/[path| pathPrefix| pathPattern]
其中:
scheme表示URI的工作模式或命名空间,默认情况下为http
主机名为示例:"www..net"
端口号如80端口
路径为完整的 URI 路径
路径模式可选通配符进行扩展
路径前缀用于指定 URI 的起始位置
当未配置相关 URI 信息时,默认工作模式应设为 file 或 content。

复制代码
    <data android:mimeType="image/*" />
    
    
      
    
    代码解读
mimeType的匹配

Intent中配置mimeType为intent-filter声明下的mimeType子类集合从而使得匹配得以成功进行。

复制代码
    <data android:mimeType="image/*" />
    
    
      
    
    代码解读

Notice: Intent同时设置data和type时候必须使用setDataAndType方法。

Activity的生命周期

Activty常用的声明周期的方法为:

  • onCreate:当系统首次创建Activity时会调用该方法,默认情况下可以在该方法中通过setContentView组件设置显示布局,并且也可以与ViewModel绑定以便动态加载数据等等。
  • onStart:启动该Activity以使其可见于用户界面,默认情况下应用会将Activity切换为前台状态并准备好支持互动操作。
  • onResume:表示当前该Activity已经处于活跃状态并位于前台状态,并且已经与用户进行了交互操作。
  • onPause:此方法表示当前不再处于前台状态且已停止所有相关操作,默认情况下执行非常简单无需保存数据或执行网络请求等复杂操作。
  • onStop:表示当前不再处于活跃状态也不再可见于用户界面因此我们可以在此时暂停动画效果或者释放不必要的资源占用空间。
  • onDestroy:表示当前该Activity即将被销毁这是其最后一个回调动作执行此操作可能的原因包括用户主动退出配置发生变更或者系统自动回收资源等情形。
在这里插入图片描述

我们来一一说明影响生命周期的场景:

启动新Activity

启动一个新Application通常是对其生命周期产生显著影响的主要因素

  1. 启动新Activity后原Activity不可见
在这里插入图片描述
  1. 启动新Activity后原Activity还是可见的
在这里插入图片描述

这就是启动Activity的所有内容。

配置文件发生变化

当Activity配置文件发生变更时,默认情况下Activity会销毁并重建。
从onPause开始依次执行onStop、onDestroy、onCreate、onStart和finally:onResume。

退出Activity

Activity可见的情况,也就是在前台,退出ActivityA的执行顺序如下图:

在这里插入图片描述

onSaveInstanceState与onRestoreInstanceState方法

在常规情况下,在Activity的生命周期中存在一个常见的事件。然而有两个特别重要的事件:onSaveInstanceState和onRestoreSSIP方法。在Activity可能面临被系统终止(Kill)之前会触发onSaveSSIP事件,在该事件中将保存当前的状态信息;而当Activity重新启动时会触发onRestoreSSIP事件,在该事件中将恢复上一次保存的状态信息。

savesInstanceState可能是在onPause之前的时间段内被调用,在onPause到onStop之间被触发,并且也可能是在onStop之后被处理。

  1. 在Android系统版本号小于11时, onSaveInstanceState 会被在 onPause 之前执行。
  2. 当Android系统版本号小于等于28时,在完成 onPause 操作后至 onStop 开始前会依次执行 onSaveInstanceState
  3. 针对所有Android系统版本号大于或等于28的情况,在完成 onStop 操作后才执行 onSaveInstanceState

Note: 以上基于参考源码, onSaveInstanceState的触发时机网络上一直缺乏可靠的信息来源, 因此无需过分关注其调用时机的具体情况, 它所处的调用时机并非特别关键。

onRestoreInstanceState是在Activity的onStart方法之后执行。

Notice: The onSaveInstanceState method will be invoked when the Application is nearing completion, and you may want to know under what circumstances it will execute.
In addition, this method is specifically called during the process of stopping an Activity, provided that the Activity has not yet completed its lifecycle.
Furthermore, if you wish to delve deeper into the implementation details, you can refer to the handleStopActivity method within the ActivityThread class.

Additionally, it's important to note that this functionality is tightly coupled with the overall application lifecycle management.

In conclusion, understanding when and why onSaveInstanceState is triggered can greatly enhance your ability to manage Application resources effectively.

In summary, this method serves as a critical component in ensuring proper Application termination and resource cleanup.

任务栈与Activity的启动

一个应用可能包含多个任务栈,在Android开发中通过压入和弹出操作(压栈出栈),任务栈能够有效管理Application的状态转移。通过这些机制的变化能够实现我们的展示逻辑,在XML配置中设置相应的参数以及使用Intent标志位来定义Application启动的具体方式。

启动模式有哪几种

我们可以通过manifest的android:launchMode来设置设备的运行方式,具体来说,则分为以下几种运行方式

standard模式也是模式的启动状态,在系统架构设计中每个任务栈中可能存在多个实例

在这里插入图片描述

单线程复用机制:一种基于stack top的位置进行活动管理的方式。在应用运行过程中:

  • 每个task stack(单个线程)中都可以独立地支持多线程或多实例的操作;
  • 同时,在整个应用运行过程中也可以同时运行多个task stack(不同主线程)。当新启动的一个**activity(intent)**已经在当前正在执行的任务stack(即本层task stack)的最顶端位置时,则该activity不会被重新创建,并触发onNewIntent操作;
  • 否则,
  • 系统会根据实际情况自动切换到新的task stack并创建一个新的activity来处理新的intent。
在这里插入图片描述

单线程场景采用栈内复用模式,在子任务空间内部实现资源的有效共享与管理机制,并确保每个子任务空间仅有一个活动实例运行。当主线程执行启动流程时,在当前主线程上会先移除主线程上正在运行的所有上层活动(如父进程),随后主线程将调用该活动的新intent处理方法以继续执行后续操作

在这里插入图片描述
在这里插入图片描述

singleInstance:单一实例模式。该强化版本的任务名为singTask。该模式仅限于附着在启动过的Activity任务栈中,并且每个这样的任务栈只有一个单一实例。

在这里插入图片描述

android:taskAffinity配置为亲属性,在默认状态下会将其设置为当前应用的包名,并且允许开发者进行自定义设置。

通常情况下(singTask模式下),android:taskAffinity仅用于Activity启动时的任务切换操作。

需要注意的是,在singTop或singInstance的任务栈中设置该属性并无实际意义。

如果在singTask模式下进行了配置,则该Activity会被分配到相应的任务栈中。

Note:
建议我们可以采用adb shell dumpsys activity activities命令获取任务栈日志。
具体格式如下:

复制代码
     Stack #1:
    Task id #98
    * TaskRecord{9ab0d7a #98 A=com.wfeii.android U=0 StackId=1 sz=2}
      * Hist #1: ActivityRecord{c8deb3b u0 com.wfeii.android/com.kuaima.testactivity.ActivitySecondActivity t98}
      * Hist #0: ActivityRecord{c1f89f1 u0 com.wfeii.android/.MainActivity t98}
    Task id #97
    * TaskRecord{b8aecf6 #97 A=com.wfeii.android U=0 StackId=1 sz=1}
      * Hist #0: ActivityRecord{c8705d3 u0 com.wfeii.android/com.kuaima.testactivity.ActivityTestActivity t97}
    
    
      
      
      
      
      
      
      
      
    
    代码解读

TaskRecord代表任务栈中的核心记录类型(以下简称A类记录)。其中A类记录指代所有与Android平台功能相关的功能组件。

A类记录中的属性值为com.wfeii.android。

ActivityRecord则代表Android系统中独立运行的应用程序(以下简称Activity)。

每个Activity都是通过AMS(Android Media Services)提供的服务入口实现与外部系统的交互。

Intent中的Flag影响启动模式

当启动Activity时设置与Intent相关的关联标志同样会影响到任务栈的表现。常见的配置包括:

  • Intent.FLAG_ACTIVITY_NEW TASK包含单个task stack内可能存在多个instances。
    它会重新生成一个新的ACTIVITY并确保其TASK STACK已建立;
    直接创建该ACTIVITY并将其实例放置在其顶端;
    如果当前TASK STACK不存在则创建新的TASK STACK并将该ACTIVITY置于顶端。
    与launchMode没有对应功能。
  • Intent.FLAG_ACTIVITY_SINGLE_TOP允许每个TASK STACK内可能存在多个instances或者存在于不同的TASK STacks中。
    与launchMode的singleTop功能一致。
  • Intent.FLAG_ACTIVITY_CLEAR_TOP允许每个TASK Stack内最多只能存在一个instance或者与其他TASK Stacks共享同一个instance。
    如果当前STACK中有ACTIVITY instance则清除其顶端内容;
    如果当前TASK Stack不存在则新建ACTIVITY instance。
    与launchMod无对应功能。

Notice:
我们经常在实际应用中采用intent.FLAG_ACTIVITY_NEW TASK与intent.FLAG_ACTIVITY_CLEAR_TOP相结合的方式,并将其命名为singularity Task以实现singTask的效果。
intent.FLAG_ACTIVITY_NEW TASK与intent.FLAG_ACTIVITY_CLEAR_TOP的结合表示为:
intent.FLAG_ACTIVITY_NEW TASK + intent.FLAG_ACTIVITY_CLEAR_TOP = singularity Task

注意事项:
意图意图FLAG_ACTIVITY_NEWTASK表示无论启动哪个Activity都会附加该intent。这表明每个Activity只能存在于一个任务栈中,并且同一个任务栈内可能允许多个实例。

如果某个Activity的launchMode设置为standard模式,则在启动时有些添加该intent而有些没有会导致同一个任务栈中有多个实例这种情况是不允许的。

全部评论 (0)

还没有任何评论哟~