Android :第5章 广播机制

本文深入探讨了Android系统的广播机制,包括BroadcastReceiver的工作原理、注册方式、动态注册与静态注册的区别,以及如何创建和发送自定义广播。同时,还讨论了在Android O及以上版本中对广播的限制和替代方案。
摘要由CSDN通过智能技术生成
广播机制简介:
    -----广播接收器(Broadcast Receiver)
 
  1:广播的类型:
        1:标准广播    2:有序广播
 
     1: 标准广播(Normal broadcasts) 是一种完全异步执行的广播 ,在广播发出之后,所有的 广播接收器几乎都会在同一时刻接收到这条广播消息,因此它们之间没有任何先后顺序可 言。 这种广播的效率会比较高,但同时也意味着它是无法被截断的
 
     2: 有序广播(Ordered broadcasts) 则是一种同步执行的广播 ,在广播发出之后,同一时刻 只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广 播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先 收到广播消息, 并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器 就无法收到广播消息了。
2:广播的注册方式
       一般有两种在代码中注册和在功能清单文件 A ndroidManifest.xml中注册
        也就是 
     1:动态注册     2:静态注册
 1:动态注册
要extends BroadcastReceiver 并重写onReceiver 
               
package com.ys.broadcasttest;
/**
* 自定义广播类  继承 广播接收器
* 使用动态广播注册方式 动态自定义广播(标准广播)
*/
public class MyReceiver extends BroadcastReceiver {
    /**
     * 重写接收器
     * @param context
     * @param intent
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        //接收intent消息
       String key= intent.getExtras().getString("key");
        Toast.makeText(context,"自定义的动态广播开启----\n"+key,Toast.LENGTH_LONG).show();
    }
}

 

 
 
1:用意图过滤器( IntentFilter )添加"过滤的动作"
2:注册广播         registerReceiver(myReceiver, intentFilter); //注册广播
3:动态注册一定要重写 onDestroy 并取消广播         unregisterReceiver(myReceiver); //取消广播
4:如果是系统自带的广播 如网络变化等,不需要发送广播会自动地监听到并“接收”执行代码
5:不是系统自带地就要发送广播了 就要用意图来发送广播了   这里是动态地配合  意图过滤器  IntentFilter
 
 
package com.ys.broadcasttest;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button;
    private MyReceiver myReceiver;
    //DYNC_BROADCAST可以随意,但注册广播和发送广播时action应该保持一致
    private static final String DYNC_BROADCAST = "com.ys.broadcasttest.MyReceiver";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        button = (Button) findViewById(R.id.button);
        broadcastRegister(); //1注册广播
        button.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                sendBroadcastVoid(); //发送广播
                break;
        }
    }
    /**
     * 注册广播  核心代码
     */
    private void broadcastRegister() {
        myReceiver = new MyReceiver(); //1 实列化(自定义)广播类
        IntentFilter intentFilter = new IntentFilter(); //意图过滤器实例化 用来过滤"动作"
        intentFilter.addAction(DYNC_BROADCAST); //添加 广播的动作
        registerReceiver(myReceiver, intentFilter); //注册广播
    }


    /**
     * 取消广播 销毁广播 动态广播注册一定要在 重写onDestroy 并取消广播
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myReceiver); //取消广播
    }


    /**
     * 发送广播
      */
    private void sendBroadcastVoid() {
        Intent intent = new Intent();
        intent.setAction(DYNC_BROADCAST); //为意图添加广播动作
        intent.putExtra("key","广播通过intent可以携带的信息:赖建文---xxx");
        sendBroadcast(intent);
    }
}

 

 
 
2:静态广播
 
<
?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ys.broadcasttest">
    <!-- 开启访问系统网络状态地权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 监听开机需要地权限 -->
    <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/AppTheme">
<!--        静态注册广播-->
        <receiver
            android:name=".staticReceiverDIY"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.ys.broadcasttest.ys2019" />
            </intent-filter>
        </receiver>
        <activity android:name=".Main2Activity" />
        <receiver
            android:name=".staticSystemReceiver"
            android:enabled="true"
            android:exported="true">
            <!-- 意图过滤器 过滤动作  开机自启的广播动作  BOOT_COMPLETED 引导完成   配合 RECEIVE_BOOT_COMPLETED 权限一起使用 -->
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
            </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>
 
 
 
 
 
package com.ys.broadcasttest;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
//静态注册 的自定义广播
public class staticReceiverDIY extends BroadcastReceiver {


    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"静态注册 的自定义广播",Toast.LENGTH_LONG).show();
    }
}

 

有序广播也在下面
package com.ys.broadcasttest;


import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


import androidx.appcompat.app.AppCompatActivity;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private Button button,button2,button3,button4;
    private MyReceiver myReceiver;
    //DYNC_BROADCAST可以随意,但注册广播和发送广播时action应该保持一致
    private static final String DYNC_BROADCAST = "com.ys.broadcasttest.MyReceiver";


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


    private void initView() {
        button = (Button) findViewById(R.id.button);
        button2 = (Button) findViewById(R.id.button2);
        button3 = (Button) findViewById(R.id.button3);
        button4 = (Button) findViewById(R.id.button4);
        broadcastRegister(); //1注册广播
        button.setOnClickListener(this);
        button2.setOnClickListener(this);
        button3.setOnClickListener(this);
        button4.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                sendBroadcastVoid(); //发送广播
                break;
            case R.id.button2:


                break;
            case R.id.button3:
                sendBroadcastVoid3();
                break;
            case R.id.button4:
                sendBroadcastVoid4(); //发送广播
                break;
        }
    }


    /**
     * 注册广播  核心代码 动态自定义广播 (标准广播)
     */
    private void broadcastRegister() {
        myReceiver = new MyReceiver(); //1 实列化(自定义)广播类
        IntentFilter intentFilter = new IntentFilter(); //意图过滤器实例化 用来过滤"动作"
        intentFilter.addAction(DYNC_BROADCAST); //添加 广播的动作
        registerReceiver(myReceiver, intentFilter); //注册广播


    }




    /**
     * 发送广播 动态注册自定义广播(标准广播)  不是系统广播就要自己去发送
     */
    private void sendBroadcastVoid() {
        Intent intent = new Intent();
        intent.setAction(DYNC_BROADCAST); //为意图添加广播动作
        intent.putExtra("key","广播通过intent可以携带的信息:赖建文---xxx");
        sendBroadcast(intent);
    }
    private static final String DYNC_BROADCAST3 = "com.ys.broadcasttest.ys2019"; //随便叫什么
    /**
     * 静态注册自定义广播(标准广播)
     */
    private void sendBroadcastVoid3() {
        Intent intent = new Intent();
        intent.setAction(DYNC_BROADCAST3);
        //当自定义的静态注册广播接收不到 时 要指定包名 与 类名setComponent
        intent.setComponent(new ComponentName("com.ys.broadcasttest","com.ys.broadcasttest.staticReceiverDIY"));


        sendBroadcast(intent);


    }
    /**
     * 发送广播 动态注册自定义广播(有序广播)  不是系统广播就要自己去发送
     * 有序广播就时 使用 sendOrderedBroadcast(intent,null);发送
     *   如果在onReceiver 中调用了 abortBroadcast方法,表示截断该广播后序广播都接收不到了
     */
    private void sendBroadcastVoid4() {
        Intent intent = new Intent();
        intent.setAction(DYNC_BROADCAST); //为意图添加广播动作
        intent.putExtra("key","动态注册的自定义广播 !!!有序广播");
        // 发送有序广播   意图  接收的权限
        sendOrderedBroadcast(intent,null);


    }


    /**
     * 取消广播 销毁广播 动态广播注册一定要在 重写onDestroy 并取消广播
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myReceiver); //取消广播
    }


}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">




    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="动态注册自定义广播(标准广播)"
        tools:layout_editor_absoluteX="151dp"
        tools:layout_editor_absoluteY="295dp" />


    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="动态注册自定义广播(有序广播)" />


    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="静态注册系统广播 开机自启实现 不用点击" />


    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="静态注册自定义广播(标准广播)" />




</LinearLayout>

 

 
 
 
3:广播按范围划分可以划分为
1:系统全局广播   2:本地广播    
 1:前面介绍的就是系统的全局广播,会播整个手机的所有应用截取到,有些不安全
2:本地广播 只在app内部进行传递,并且也只接收来自app内部的发出的广播,这样安全性更高
    这样: 1 不用担心机密数据泄露  2不需要担心会有安全漏洞  3:本地广播比系统全局广播更加高效
    特殊性: 本地广播是无法通过静态注册的方式来接收的。只能动态注册
主要使用LocalBroadcastManger 来对广播进行管理 发送和注册
实列:
private IntentFilter filter;
    private LocalBroadcastManager localBroadcastManager;
    private LocalReceiver localReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(MainActivity.this); // 获取实例
        mButton = (Button) findViewById(R.id.send_broadcast_button);
        mButtonLocal = (Button) findViewById(R.id.send_localbroadcast_button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent();
                intent.setAction("static_broadcast");
                //sendBroadcast(intent);
                sendOrderedBroadcast(intent, null); // 发送有序广播
            }
        });
        mButtonLocal.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
        filter = new IntentFilter();
        filter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver, filter); // 注册本地广播监听器
    }
    class LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "成功接收本地广播!", Toast.LENGTH_LONG).show();
        }
    };
    @Override
    protected void onDestroy() {
        localBroadcastManager.unregisterReceiver(localReceiver);
        super.onDestroy();
    }

 

 
拓展:
註冊方式:
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,new IntentFilter(broadcast));
註銷方式:
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
傳送方式:
LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(intent);
完整程式碼: MainActivity.java
package com.example.cheng.broadcastreciver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
private static final String broadcast = "broadcast";
private Button btn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(broadcast);
intent.putExtra("str", "sendBroadcase");
LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(intent);
}
});
}

@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,new IntentFilter(broadcast));

}
private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,intent.getStringExtra("str"),Toast.LENGTH_SHORT).show();
}
};

@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
}
}

  

 

 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值