侧边栏

Android四大组件

发布于 | 分类于 客户端/Android

Android 操作系统是一种多用户 Linux 系统,其中的每个应用都是一个不同的用户。就像学习前端开发需要了解浏览器BOM、DOM相关知识一下,学习Android也需要先看看Android系统为Android应用提供了什么能力。

本文将整理Android系统的四大组件。

Android四大组件指的是Activity、Service、BroadcastReceiver和ContentProvider。

  • Activity:Activity是Android应用程序的主要界面,用户与应用程序进行交互的入口点,它表示拥有界面的单个屏幕。每个Activity都拥有自己的生命周期,开发者需要了解如何创建、启动、停止和管理Activity。

  • Service:Service是在后台运行的组件,通常用于执行长时间的任务或提供系统级别的服务。Service可以被其他组件(如Activity)调用,并且可以在前台或后台运行。开发者需要了解如何创建、启动、停止和管理Service。

  • BroadcastReceiver:BroadcastReceiver是一个组件,用于接收系统广播和自定义广播。当系统或应用程序发送广播时,BroadcastReceiver会收到通知并执行相应的操作。借助广播接收器组件,系统能够在常规用户流之外向应用传递事件,从而允许应用响应系统范围内的广播通知。许多广播均由操作系统发起。系统甚至可以向当前未运行的应用传递广播,类似于操作系统级别的EventBus。开发者需要了解如何注册、处理和取消BroadcastReceiver。

  • ContentProvider:ContentProvider是一个组件,用于在多个应用程序之间共享数据。ContentProvider提供了一个统一的数据模型,管理一组共享的应用数据,可以将这些数据存储在文件系统、SQLite 数据库、网络中或者的应用可访问的任何其他持久化存储位置,允许应用程序通过URI来访问和修改数据。开发者需要了解如何创建、实现和使用ContentProvider。

每种组件都有不同的用途和生命周期。Android 系统设计的独特之处在于:任何应用都可启动其他应用的组件,这些组件可以相互配合使用,形成复杂的应用程序结构。例如,某个活动上点击按钮之后,可以拉起文件管理器应用的文件选择活动,活动也可以启动服务来执行后台任务,服务可以通过广播接收器发送广播消息,内容提供器可以为活动和服务提供数据访问接口。了解和熟练使用这些组件是进行Android应用程序开发的基础。

活动Activity

从web开发者的角度来看,可以近似把活动理解为单个页面级别的路由组件

活动是用户界面的核心组件,通常代表应用程序中的一个屏幕。它提供了用户与应用程序进行交互的界面,例如按钮、文本框、图像等。活动可以接收用户输入、处理和显示数据,并与其他活动进行交互。每个活动都是一个单独的类,它继承自Android的Activity基类。活动通过Intent进行启动和销毁。

创建活动

实现活动类(类比web:页面组件)

java
// MyActivity.java

import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my); // 设置活动视图
    }
}

布局文件(类比web:页面组件中的template)

xml
<!-- activity_my.xml -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- 添加其他UI元素和布局 -->

</LinearLayout>

配置活动(类比web:将路由组件和url关联起来)

xml
<!-- AndroidManifest.xml -->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">

    <application
        android:allowBackup="true"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MyActivity"
            android:label="My Activity">
        </activity>

        <!-- 添加其他活动和声明 -->

        <activity
            android:name=".OtherActivity">
        </activity>

    </application>
</manifest>

活动间跳转

通过intent传递信息(类比web:页面跳转)

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    /** Called when the user taps the Send button */
    fun sendMessage(view: View) {
        val editText = findViewById<EditText>(R.id.editTextTextPersonName)
        val message = editText.text.toString()
        val intent = Intent(this, DisplayMessageActivity::class.java).apply {
            putExtra(EXTRA_MESSAGE, message)
        }
        startActivity(intent)
    }
}

下一个Activity接收到intent携带的数据

kotlin
class DisplayMessageActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_display_message)
        
        // Get the Intent that started this activity and extract the string
        val message = intent.getStringExtra(EXTRA_MESSAGE)

        // Capture the layout's TextView and set the string as its text
        val textView = findViewById<TextView>(R.id.textView).apply {
            text = message
        }
    }
}

服务Service

服务是在后台执行长时间运行任务的组件,它没有用户界面。服务通常用于执行一些耗时操作,如下载文件、播放音乐、处理网络请求等。服务可以在应用程序的后台持续运行,即使用户切换到其他应用程序,也能保持活动状态。服务通常是无界面的,但可以与其他组件进行通信。

比如要在后台定时打印一个日志

java
public class MyService extends Service {
    private Intent mIntent;
    private Timer mTimer;
    private boolean mIsRunning = false;
    
    @Override
    public void onCreate() {
        super.onCreate();
        mIntent = new Intent(this, MyService.class);
        mTimer = new Timer();
        mTimer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                // 在此处执行服务的任务
            }
        }, 0, 1000);
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        mTimer.cancel();
        mIsRunning = false;
    }
}

在某个活动中创建服务实例

java
// MyActivity.java

import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity {
    private MyService mMyService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my); // 设置活动视图
        mMyService = new MyService(this);  // 创建服务实例
    }

    // 在某些时机,比如点击按钮的时候启动服务
    private void startService() {
        mMyService.start();
    }
}

服务也需要在AndroidManifest.xml中进行配置

xml
<service android:name=".MyService" />

广播接收器Broadcast Receiver

广播接收器用于接收和响应系统广播消息或应用程序内部的自定义广播消息。广播是一种系统级的通信机制,它允许应用程序或系统向其他组件发送消息。广播接收器可以接收和处理特定的广播消息,并执行相应的操作。广播接收器可以在AndroidManifest.xml文件中进行声明,或者动态注册和注销。

广播需要先在配置文件AndroidManifest.xml中注册

xml
<receiver android:name=".BroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.MY_ACTION"/>
    </intent-filter>
</receiver>

然后在活动中创建广播实例并监听消息

java
// MyActivity.java

import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity {
    private BroadcastReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my); // 设置活动视图
        String action = "com.example.MY_ACTION";
        mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // 自定义广播名称
                if (intent.getAction().equals(action)) {
                }
            }
        };
        registerReceiver(mReceiver, new IntentFilter(action));
    }
}

其他活动(不限于你自己的应用)就可以通过sendBroadcast的方法发送消息了

java

Intent intent = new Intent();
intent.setAction("com.example.MY_ACTION");
sendBroadcast(intent);

BroadcastReceiver收到消息后,可以拿到携带的信息

java
@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals("com.example.MY_ACTION")) {
        String data = intent.getStringExtra("data");
        // 在此处处理接收到的广播数据
    }
}

这在封装应用级别的SDK很有用。

内容提供器Content Provider

内容提供器用于管理应用程序的数据共享,它允许应用程序共享数据给其他应用程序或访问其他应用程序共享的数据。内容提供器可以提供对结构化数据(如数据库)或文件(如图片、音频文件)的访问。通过内容提供器,应用程序可以进行数据的增删改查操作,并通过URI进行数据的访问和共享。

在项目的res目录下创建一个content provider目录,并在其中创建一个文件provider_meta.xml,该文件描述了你的内容提供器的内容类型和操作。例如:

xml
<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.myapp.provider.MyContentProvider">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths"/>
    <query
        android:name="get_all_data"
        android:columnNames="id"
        android:returningType="java.lang.String"
        android:maxResults="1000"/>
</provider>

其中,

  • android:name指定了你的内容提供器的名称,
  • android:authorities指定了你的内容提供器在系统中的应用名,
  • android:meta-data指定了你的内容提供器需要访问的文件路径,
  • android:query指定了你内容提供器中定义的操作。

然后在活动中添加对Content Provider的引用

java
// MyActivity.java

import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity {
    private MyContentProvider mContentProvider;
    private static final String TAG = "MyContentProvider";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mContentProvider = new MyContentProvider(this); // 注意要将this作为参数传入构造函数中

        // 调用获取所有数据的查询操作
        String[] data = mContentProvider.getAllData();
        if (data != null && data.length > 0) {
            // 处理获取到的数据
        } else {
            // 没有获取到数据
        }
    }
}

你要请我喝一杯奶茶?

版权声明:自由转载-非商用-保持署名和原文链接。

本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。