Android组件

Activity

Activity 类是 Android 应用的关键组件,而 Activity 的启动和组合方式则是该平台应用模型的基本组成部分。在编程范式中,应用是通过 main() 方法启动的,而 Android 系统与此不同,它会调用与其生命周期特定阶段相对应的特定回调方法来启动 Activity 实例中的代码。当一个应用调用另一个应用时,调用方应用会调用另一个应用中的 Activity,而不是整个应用。通过这种方式,Activity 充当了应用与用户互动的入口点。

声明

<manifest ... >
    <application ... >
        <activity android:name=".ExampleActivity" 唯一的必要属性,指定Activity类名称
        android:permission="com.google.socialapp.permission.SHARE_POST"> 声明权限
            <intent-filter>
                <action android:name="android.intent.action.SEND"/> 设置过滤器
            </intent-tilter>
        </activity>
    </application ... >
    ...
</manifest >

生命周期

Activity Lifecycle

为了在 Activity 生命周期的各个阶段之间导航转换,Activity 类提供六个核心回调:onCreate()onStart()onResume()onPause()onStop()onDestroy()。当 Activity 进入新状态时,系统会调用其中每个回调。

93cd4611-1c96-4120-b6c1-95e651701c58.png

  • onCreate()

会在系统创建 Activity 时触发。

必须实现此回调,实现应该初始化 Activity 的基本组件:例如,应该在此处创建视图并将数据绑定到列表。必须在此处调用 setContentView() 来定义 Activity 界面的布局。

onCreate() 完成后,下一个回调将是 onStart()

  • onStart()

onCreate() 退出后,Activity 将进入“已启动”状态,并对用户可见。

此回调包含 Activity 进入前台与用户进行互动之前的最后准备工作。

  • onResume()

系统会在 Activity 开始与用户互动之前调用此回调。

此时,该 Activity 位于 Activity 堆栈的顶部,并会捕获所有用户输入。应用的大部分核心功能都是在 onResume() 方法中实现的。

onResume() 回调后面总是跟着 onPause() 回调。

  • onPause()

当 Activity 失去焦点并进入“已暂停”状态时,系统就会调用 onPause()

例如,当用户点按“返回”或“最近使用的应用”按钮时,就会出现此状态。当系统为您的 Activity 调用 onPause() 时,从技术上来说,这意味着您的 Activity 仍然部分可见,但大多数情况下,这表明用户正在离开该 Activity,该 Activity 很快将进入“已停止”或“已恢复”状态。

如果用户希望界面继续更新,则处于“已暂停”状态的 Activity 也可以继续更新界面。例如,显示导航地图屏幕或播放媒体播放器的 Activity 就属于此类 Activity。即使此类 Activity 失去了焦点,用户仍希望其界面继续更新。

onPause() 执行完毕后,下一个回调为 onStop()onResume(),具体取决于 Activity 进入“已暂停”状态后发生的情况。

onStop()

当 Activity 对用户不再可见时,系统会调用 onStop()

出现这种情况的原因可能是 Activity 被销毁,新的 Activity 启动,或者现有的 Activity 正在进入“已恢复”状态并覆盖了已停止的 Activity。在所有这些情况下,停止的 Activity 都将完全不再可见。

系统调用的下一个回调将是 onRestart()(如果 Activity 重新与用户互动)或者 onDestroy()(如果 Activity 彻底终止)。

onRestart()

当处于“已停止”状态的 Activity 即将重启时,系统就会调用此回调。

onRestart() 会从 Activity 停止时的状态恢复 Activity。

此回调后面总是跟着 onStart()

onDestroy()

系统会在销毁 Activity 之前调用此回调。

此回调是 Activity 接收的最后一个回调。通常,实现 onDestroy() 是为了确保在销毁 Activity 或包含该 Activity 的进程时释放该 Activity 的所有资源。

// 正常显示
Activity Lifecycle: onApplyThemeResource: 
Activity Lifecycle: onCreate: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onStart: 
Activity Lifecycle: onResume: 
Activity Lifecycle: onAttachedToWindow: 

// 息屏 or 退出应用
Activity Lifecycle: onPause: 
Activity Lifecycle: onStop: 
Activity Lifecycle: onSaveInstanceState: 

// 亮屏,从后台打开
Activity Lifecycle: onRestart: 
Activity Lifecycle: onStart: 
Activity Lifecycle: onResume: 

// 横屏
Activity Lifecycle: onPause: 
Activity Lifecycle: onStop: 
Activity Lifecycle: onSaveInstanceState: 
Activity Lifecycle: onDestroy: 
Activity Lifecycle: onDetachedFromWindow: 
Activity Lifecycle: onApplyThemeResource: 
Activity Lifecycle: onCreate: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onStart: 
Activity Lifecycle: onRestoreInstanceState: 
Activity Lifecycle: onResume: 
//什么时候看见
Activity Lifecycle: onAttachedToWindow: 

//小窗
Activity Lifecycle: onDestroy: 
Activity Lifecycle: onApplyThemeResource: 
Activity Lifecycle: onCreate: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onCreateView: 
Activity Lifecycle: onStart: 
Activity Lifecycle: onRestoreInstanceState: 
Activity Lifecycle: onResume: 

启动模式

LaunchMode

说明

standard

系统在启动该 Activity 的任务中创建 Activity 的新实例

singleTop

如果当前任务的顶部已存在 Activity 的实例,则系统会通过调用其 onNewIntent() 方法来将 intent 转送给该实例,而不是创建 Activity 的新实例。

singleTask

系统会创建新任务,并实例化新任务的根 Activity。但是,如果另外的任务中已存在该 Activity 的实例,则系统会通过调用其 onNewIntent() 方法将 intent 转送到该现有实例,而不是创建新实例。Activity 一次只能有一个实例存在。

singleInstance

"singleTask" 相似,唯一不同的是系统不会将任何其他 Activity 启动到包含该实例的任务中。该 Activity 始终是其任务唯一的成员;由该 Activity 启动的任何 Activity 都会在其他的任务中打开。

Service

Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。

  • 前台服务:前台服务执行一些用户能注意到的操作。

  • 后台服务:后台服务执行用户不会直接注意到的操作。

  • 绑定服务:当应用组件通过调用 bindService() 绑定到服务时,服务即处于绑定状态。绑定服务会提供客户端-服务器接口,以便组件与服务进行交互、发送请求、接收结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。

注意:服务在其托管进程的主线程中运行,它既创建自己的线程,也在单独的进程中运行(除非另行指定)。如果服务将执行任何 CPU 密集型工作或阻止性操作(例如 MP3 播放或联网),则应通过在服务内创建新线程来完成这项工作。通过使用单独的线程,您可以降低发生“应用无响应”(ANR) 错误的风险,而应用的主线程仍可继续专注于运行用户与 Activity 之间的交互。

<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService" />
      ...
  </application>
</manifest>

生命周期

服务生命周期。左图显示使用 startService() 创建的服务的生命周期,右图显示使用

bindService() 创建的服务的生命周期。

d5f9714e-4886-40b7-948a-8c91bb689177.png

Activity 可以结合使用显式 Intent 与 startService(),从而启动上文中的示例服务。

Intent(this, HelloService::class.java).also { intent ->
    startService(intent)
}

  • 启动服务

该服务在其他组件调用 startService() 时创建,然后无限期运行,且必须通过调用 stopSelf() 来自行停止运行。此外,其他组件也可通过调用 stopService() 来停止此服务。服务停止后,系统会将其销毁。

  • 绑定服务

该服务在其他组件(客户端)调用 bindService() 时创建。然后,客户端通过 IBinder 接口与服务进行通信。客户端可通过调用 unbindService() 关闭连接。多个客户端可以绑定到相同服务,而且当所有绑定全部取消后,系统即会销毁该服务。(服务不必自行停止运行。)

BroadcastReceiver

一种广泛运用在应用程序之间传输信息的机制,通过发送 Intent 来传送我们的数据

注册 > 创建 BroadcastReceiver子类并实现 onReceive(Context, Intent)

<receiver android:name=".MyBroadcastReceiver"  android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
    </intent-filter>
</receiver>

    class MyBroadcastReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
        
        }
    }

系统软件包管理器会在应用安装时注册接收器。然后,该接收器会成为应用的一个独立入口点,这意味着如果应用当前未运行,系统可以启动应用并发送广播。系统会创建新的 BroadcastReceiver 组件对象来处理它接收到的每个广播。此对象仅在调用 onReceive(Context, Intent) 期间有效。一旦从此方法返回代码,系统便会认为该组件不再活跃。

发送广播可以通过 sendOrderedBroadcast(Intent, String)sendBroadcast(Intent)LocalBroadcastManager.sendBroadcast 进行。

  1. sendOrderedBroadcast(Intent, String) 方法一次向一个接收器发送广播。当接收器逐个顺序执行时,接收器可以向下传递结果,也可以完全中止广播,使其不再传递给其他接收器。接收器的运行顺序可以通过匹配的 intent-filter 的 android:priority 属性来控制;具有相同优先级的接收器将按随机顺序运行。

  2. sendBroadcast(Intent) 方法会按随机的顺序向所有接收器发送广播。这称为常规广播。这种方法效率更高,但也意味着接收器无法从其他接收器读取结果,无法传递从广播中收到的数据,也无法中止广播。

  3. LocalBroadcastManager.sendBroadcast 方法会将广播发送给与发送器位于同一应用中的接收器。如果您不需要跨应用发送广播,请使用本地广播。这种实现方法的效率更高(无需进行进程间通信),而且您无需担心其他应用在收发您的广播时带来的任何安全问题。

Intent().also { intent ->
    intent.setAction("com.example.broadcast.MY_NOTIFICATION")
    intent.putExtra("data", "Notice me senpai!")
    sendBroadcast(intent)
}

可以在发送广播时声明发送器或接收器的权限

sendBroadcast(Intent("com.example.NOTIFY"), Manifest.permission.SEND_SMS)
<uses-permission android:name="android.permission.SEND_SMS"/>

ContentProvider

内容提供者,它是用在不同的应用程序之间共享数据时,可以把一个应用的数据提供给其他的应用使用。

2bf2cbd4-209b-4625-9094-22f0a52f2651.png