Android 四大组件解析

本文内容主要来源于网络,参考自文章

Android四大组件分别是:Activity,Service,BroadcastReceiver,ContentProvider。

  1. Activity(活动):通常表现为一个可视化的用户界面。例如,用户的登录页面以及登录后显示的主页通常都是一个Activity。Activity组件主要负责展示用户界面、处理用户交互以及进行数据传递等。
  2. Service(服务):无界面的后台组件,用于执行长期运行的操作,比如在后台下载软件更新安装包等。
  3. BroadcastReceiver(广播接收器):用于接收广播信息,并做出对应处理的组件。比如电量的变化,更改语言选项等。
  4. ContentProvider(内容提供者):应用程序之间共享数据的桥梁,是管理跨程序应用访问的组件,例如访问相册或文件等。

一、Activity

一个应用程序中有0至多个Activity,0个表示该应用程序不包含与用户交互的界面。每个Activity就是一个独立的界面,从一个页面跳转到另一个页面,通常就是从一个Activity跳转到另一个Activity。

1.1 Activity的生命周期

Activity的生命周期包含多个关键阶段,这些阶段反映了Activity在不同状态下的变化。

从Activity创建到销毁的整个过程, 涵盖了生命周期:onCreate(); onStart(); onResume(); onPause(); onStop(); onDestroy();.

  1. onCreate():在Activity首次创建时调用,用于进行初始化操作,如加载布局,绑定数据等。
javascript 复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
  1. onStart(): 当Activity对用户可见时调用,此时Activity还未处于前台,不能与用户交互。
  2. onResume(): 当Activity进入前台并开始与用户交互时调用,此时Activity处于运行状态。比如页面已完全显示可见,用户可以点击按钮操作。
  3. onPause(): 当Activity失去焦点,但仍有部分可见时调用,常用于存储一些临时数据或停止一些消耗资源的操作。
javascript 复制代码
@Override
protected void onPause() {
    super.onPause();
    // 保存临时数据
}
  1. onStop(): 当Activity完全不可见时调用,此时Activity已停止运行。
  2. onDestory(): 当Activity被销毁之前调用,用于释放资源和清理工作。
javascript 复制代码
@Override
protected void onDestroy() {
    super.onDestroy();
    // 释放资源
}
  1. onRestart():Activity从停止状态重新启动时调用。首页Activity从后台回到前台。

1.2 Activity的启动方法

Activity的启动方法也可以叫做Activity间的跳转,分隐式跳转和显式跳转。在Android中,Activity的启动是通过Intent来表达的,Intent是组件之间通信的媒介,专门提供组件互相调用的相关信息,Intent的启动方式,大致分为两种: 显式启动和隐式启动。

1.2.1 显式启动

明确指定要启动的Activity的class或者包名.activity类名。显示启动提供了三种方式:

  1. Class跳转
javascript 复制代码
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
  1. 包名跳转
javascript 复制代码
Intent intent = new Intent(); 
intent.setClassName(FirstActivity.this,"com.test.launchapplication.SecondActivity");
startActivity(intent);
  1. ComponentName跳转
javascript 复制代码
Intent intent = new Intent()
ComponentName componentName = new ComponentName(FirstActivity.this,SecondActivity.class);
intent.setComponent(componentName);
startActivity(intent);

1.2.2 隐式启动

隐式启动是通过指定Intent的Action(动作)、Category(类别)、Data(数据)等信息,让系统根据这些信息来寻找合适的Activity来进行启动。

  1. 在AndroidManifest.xml文件中 定义action和category属性:
javascript 复制代码
<activity android:name=".MainActivity">
	      <intent-filter>
	            <action android:name="android.intent.action.MAIN"/>
	            <category android:name="android.intent.category.LAUNCHER"/>
	      </intent-filter>
</activity>

其中action的name可以自定义,category默认的配置为

<category android:name="android.intent.category.DEFAULT"/>

  1. 在java 文件中写入逻辑代码
javascript 复制代码
Intent intent = new Intent("android.intent.action.MAIN");
startActivity(intent);

1.3 Activity的启动模式

Activity有四种启动模式:standard、singleTop、singleTask、singleInstance.

  1. standard(标准模式):Activity的默认模式,每次启动一个Activity,都会创建一个新的实例并将其压入任务栈中,无论该Activity是否已经存在于任务栈里。这种模式下,多个相同的Activity实例可以同时存在于任务栈中。例如,在一个应用中多次启动同一个Activity,就会有多个该Activity的实例依次入栈。
javascript 复制代码
// 在代码中以standard模式启动Activity
Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);
  1. singleTop(栈顶复用模式):如果新启动的Activity已经位于任务栈的栈顶,那么不会创建新的Activity实例,而是直接复用栈顶的实力,并调用其onNewIntent();方法。若该Activity不在栈顶,则会创建新的实例并压入栈中。例如,当应用处于某个Activity界面时,再次启动该Activity,如果它在栈顶,就不会创建新实例。
javascript 复制代码
// 在AndroidManifest.xml中设置Activity为singleTop模式
<activity
    android:name=".TargetActivity"
    android:launchMode="singleTop">
</activity>
  1. singleTask(栈内复用模式):系统会先检查任务栈中是否已经存在该Activity的实例。如果存在,系统会将该Activity实例之上的所有Activity出栈,使该Activity实例处于栈顶,并调用onNewIntent();方法;如果不存在,则创建新的Activity实例并压入栈中。这种模式常用于应用的主界面,确保主界面在任务栈中只有一个实例。
javascript 复制代码
// 在AndroidManifest.xml中设置Activity为singleTask模式
<activity
    android:name=".TargetActivity"
    android:launchMode="singleTask">
</activity>
  1. singleInstande(全局唯一模式):该模式下的Activity会独占一个任务栈,即该Activity在整个系统中只有一个实例,并且该实例当度存在于一个任务栈中。当启动该Activity时,如果该Activity所在的任务栈不存在,则会创建一个新的任务栈,并将该Activity实例放入其中;如果该任务栈已经存在,则直接复用该实例。这种模式适用于需要独立运行且不予其他Activity共享任务栈的场景,如闹钟提醒界面。
javascript 复制代码
// 在AndroidManifest.xml中设置Activity为singleInstance模式
<activity
    android:name=".TargetActivity"
    android:launchMode="singleInstance">
</activity>

二、Service

Service用于在后台执行长时间运行的操作,不提供用户界面。它可以在应用程序的进程中运行,也可以跨进程运行。

2.1 Service生命周期

生命周期常用方法:

  1. onCreate():在Service被创建时调用,主要用于进行一些初始化操作,如初始化变量、注册广播接收器等。例如。在音乐播放Service中,可以在onCreate()方法里初始化音乐播放对象。
  2. onStartCommand():每次通过startService()启动Service时会调用该方法。此方法会接收启动Service时传递的Intent对象,可根据其中的数据来执行相应的操作。比如,在文件下载Service中,可以从Intent中获取要下载的文件URL,然后开始下载任务。
  3. onBind():当有客户端调用bindService()方法绑定Service时调用,该方法需要返回一个IBinder对象,用于与客户端进行通信。例如,在一个提供数据查询服务的Service中,可返回一个实现了IBinder接口的对象,客户端通过该对象调用Service中的方法回去数据。
  4. onDestroy():在Service被销毁时调用,用于释放Service所占用的资源,如关闭数据库连接,停止线程等。比如,在音乐播放Service销毁时,需要停止音乐播放并释放音乐播放器资源。

不同的启动方式会使Service经历不同的生命周期流程。

2.1.1 启动式Service

通过startService()启动,适用于执行一次性任务,如下载文件,播放音乐。

首先会调用onCreate()方法进行初始化,接着调用onStartCommand()方法执行具体的服务操作。当Service不在需要时,可调用stopService()或在Service内部调用stopSelf()来停止Service,此时会调用onDestroy()方法释放资源。

实例代码如下:

javascript 复制代码
// 启动Service
Intent intent = new Intent(this, MyService.class);
startService(intent);

// 停止Service
stopService(intent);

2.1.2 绑定式Service

通过bindService()绑定,提供长期服务,比如后台计算,数据同步。

跟启动式Service一样,首先调用onCreate()方法,然后调用onBind()方法返回IBinder对象。当客户端调用unbindService()解除绑定时,会依次调用onUnbind()和onDestroy()方法。示例代码如下:

javascript 复制代码
// 绑定Service
Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

// 解除绑定
unbindService(serviceConnection);

三、BroadcastReceiver

在Android系统中用于接收广播消息的组件,其工作原理给予Android的消息传递机制。当系统或应用发出一个广播消息时,Android系统会将这个消息发送给所有注册了相应广播意图的BroadcastReceiver。BroadcastReceiver在接收到广播消息后,会根据其内部定义的逻辑执行相应的操作,且这个过程是异步的,不会阻塞主线程。

3.1 广播的类型

广播分为两种:系统广播和自定义广播。

  1. 系统广播:顾名思义,系统广播是由系统发出,比如电池电量低,网络状态发生变化,屏幕开关等。
  2. 自定义广播:由应用发出,用于应用内部或应用间的通信。比如在APP中定义一个广播,当某个任务完成后发出广播消息,在应用内接收广播消息的逻辑中就会收到该条消息。

3.2 广播的注册方式

BroadcastReceiver的注册方式分为两种:静态注册和动态注册。

  1. 静态注册:在AndroidManifest.xml中注册,即使应用未运行也能接收广播,适用于接收系统广播。
javascript 复制代码
// 注册
<application
    ...
    <receiver
        android:name=".MyBroadcastReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.example.MY_STATIC_BROADCAST" />
        </intent-filter>
    </receiver>
</application>

// 接收
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 处理接收到的广播
        Toast.makeText(context, "接收到静态广播", Toast.LENGTH_SHORT).show();
    }
}
  1. 动态注册:在代码中通过registerReceiver()注册,常用于应用运行时接收广播。适用于监听应用内部的广播,如用户点击某个按钮后发出的消息。
javascript 复制代码
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    private BroadcastReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 创建广播接收器实例
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // 处理接收到的广播
                Toast.makeText(context, "接收到广播", Toast.LENGTH_SHORT).show();
            }
        };

        // 创建IntentFilter,指定要接收的广播类型
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.example.MY_CUSTOM_BROADCAST");

        // 注册广播接收器
        registerReceiver(receiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销广播接收器
        unregisterReceiver(receiver);
    }
}

四、ContentProvider

主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行操作。

ContentProvider具有以下特点

  1. 数据共享:可实现不同应用程序间的数据共享。
  2. 独立性:创建的ContentProvider是独立类型,与Activity和应用本身无直接关联。
  3. 唯一标识:每个ContentProvider都有一个唯一的authority,用于外部应用与对应ContentProvider数据进行交互,为保证其唯一性,通常将其写成和应用程序一样的包名。
  4. 统一接口:提供了统一的增删查改接口。
  5. 权限控制:可通过自定义权限对ContentProvider的访问进行控制,保证数据安全。

本文主要对Android四大组件做一个概念介绍,具体详解请关注后续内容。

感谢看完全文,比心!

相关推荐
Digitally1 小时前
适用于安卓、iOS 和电脑的最新文件共享应用评测指南
android·ios·电脑
__Witheart__2 小时前
搭建编译 HW-T3568 安卓固件的环境
android
Bowen_J2 小时前
Flutter 屏幕旋转适配
android·flutter·ios
程序员陆业聪10 小时前
绕过Frida/Xposed的最后防线:SVC直接系统调用与Native反Hook实战
android
程序员陆业聪10 小时前
WebView与原生JS交互:JSBridge生产级实现与安全防护
android
我命由我1234513 小时前
Android 开发问题:MlKitException: An internal error occurred during initialization.
android·java·java-ee·android jetpack·android-studio·androidx·android runtime
Meteors.14 小时前
Android自定义 View 三核心方法详解
android
2501_9160074714 小时前
前端开发常用软件与工具全面指南
android·ios·小程序·https·uni-app·iphone·webview
赏金术士14 小时前
Android Tinker 热修复集成与使用指南 1.9.15.2
android·热修复·tinker