Android 发送广播及监听接收

需求:

写一个Demo,监听开机广播事件

需要创建一个继承自 BroadcastReceiver 的类,用于处理开机广播

public class BootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Log.d("BootReceiver~1", "Device has booted");
            
            // 这里可以启动服务或执行其他操作

        }
    }
}

1.MainActivity类实现功能

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

	// 断言方法,出现异常报错
    public static void assertTrue(String message, boolean condition) {
        if (!condition) {
            throw new AssertionError(message);
        }
    }

    public void testBootComplated_A() {

       
        ConditionVariable getBook2 = new ConditionVariable();

        BootReceiver receiver = new BootReceiver();
        
        // 主动发一个ACTION_BOOT_COMPLETED广播
        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
        
        receiver.onReceive(getApplicationContext(), intent);

        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Log.d("BootReceiver~2", "Device has booted");
            // 这里可以启动服务或执行其他操作

            getBook2.open(); // 更新状态
        }

		// 这里,如果getBook2.block(10000)函数返回false,就会抛出异常
        assertTrue("值不匹配1", getBook2.block(10000));


    }




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

		// 测试这个方法
        testBootComplated_A();
       
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 取消注册
        // unregisterReceiver(bootReceiver);
    }

2.在 AndroidManifest.xml 中注册 Receiver

接下来,在 AndroidManifest.xml 中注册这个 BroadcastReceiver 并请求相关权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.demo0923">

    <!-- 声明使用该广播的权限 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Demo0923">

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

        </receiver>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

3.ConditionVariable

ConditionVariable 是 Android 提供的一个用于线程间协调的类。open 方法用于将条件状态设置为已打开,并通知等待线程。以下是该方法的基本用法和上下文。

// 创建 ConditionVariable 实例:


ConditionVariable condition = new ConditionVariable();

//等待条件:
new Thread(() -> {
    
    condition.block(); // 阻塞直到条件被打开
    
    // 条件满足后执行的代码
}).start();

// 调用 open 方法:
// 在某些条件下
condition.open(); // 解除等待状态

说明

  • block():用于等待条件,线程会在此方法中阻塞,直到 open 被调用。

  • 线程协调open 方法使得其他等待的线程可以继续执行,通常用于在某个条件满足时的线程同步。

这种机制常用于处理需要等待特定条件的多线程场景。

如果有两个 ConditionVariable 实例,你可以用它们分别控制不同的线程或不同的条件。具体使用时,你可以在一个线程中等待一个条件,在另一个线程中打开对应的条件。以下是一个简单的示例:

示例代码
import android.os.ConditionVariable;

public class TwoConditionVariablesExample {
    
    public static void main(String[] args) {
        
        ConditionVariable condition1 = new ConditionVariable();
        ConditionVariable condition2 = new ConditionVariable();

        // 第一个线程等待 condition1
        new Thread(() -> {
            System.out.println("线程1开始等待...");
            condition1.block();
            System.out.println("线程1继续执行!");
        }).start();

        // 第二个线程等待 condition2
        new Thread(() -> {
            System.out.println("线程2开始等待...");
            condition2.block();
            System.out.println("线程2继续执行!");
        }).start();

        // 模拟一些操作后打开 condition1
        new Thread(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("准备打开条件1...");
                condition1.open();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        // 模拟一些操作后打开 condition2
        new Thread(() -> {
            try {
                Thread.sleep(4000);
                System.out.println("准备打开条件2...");
                condition2.open();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
  1. 线程1等待 condition1

  2. 线程2等待 condition2

  3. 分别在不同的线程中打开这两个条件,线程1将在2秒后继续,线程2将在4秒后继续。

4.输出结果

如果启动该应用没有监听到系统开机广播,则这个testBootComplated_A 的 断言 assertTrue("值不匹配1", getBook2.block(10000));

2024-09-28 14:46:54.098 7583-7583/com.example.demo0923 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.demo0923, PID: 7583
    java.lang.AssertionError: 值不匹配1
        at com.example.demo0923.MainActivity.assertTrue(MainActivity.java:21)
        at com.example.demo0923.MainActivity.testBootComplated_A(MainActivity.java:59)
        at com.example.demo0923.MainActivity.onCreate(MainActivity.java:78)
        at android.app.Activity.performCreate(Activity.java:8000)
        at android.app.Activity.performCreate(Activity.java:7984)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2024-09-28 14:46:54.170 7583-7583/com.example.demo0923 I/Process: Sending signal. PID: 7583 SIG: 9

综上,如果应用没有接收到ACTION_BOOT_COMPLETED这个广播,就会报断言异常错误, 程序挂掉;如果接收到ACTION_BOOT_COMPLETED广播,程序正常执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值