Android APP完整基础教程(07)四大组件之BroadcastReceiver

Android APP完整基础教程(07)四大组件之BroadcastReceiver,第1张

Android APP完整基础教程(07)四大组件之BroadcastReceiver 1 BroadcastReceiver简介

BroadcastReceiver本质上是一个全局监听器,用于监听系统全局的广播消息(在android O系统之后进行了改动,启动BroadcastReceiver的Intent必须是显式Intent,就像启动service的intent一样。要么直接设置BroadcastReceiver类名,要么通过action和package来设置显式Intent)。

对比监听器onXXXlistener 和 BroadcastReceiver:

onXXXlistener监听器是程序级的,程序退出,监听器即关闭。BroadcastReceiver是系统级的,有自己的进程。只要匹配的Intent被广播出来,就会被触发。

注意:因为每次Broadcast事件发生后,系统会自动创建BroadcastReceiver实例并触发onRecevice方法,执行结束后销毁BroadcastReceiver实例。所以如果需要BroadcastReceiver实现一个耗时的工作最好考虑使用IntentService来完成,而不是开一个线程,因为BroadcastReceiver的生命周期很短,可能线程未执行完毕BroadcastReceiver就退出了,如果此时系统内存紧张可能优先结束掉该线程。

2 BroadcastReceiver配置/注册

广播注册的方式分为两种:静态注册、动态注册。两者差异如下:

动态注册:是当用来注册的Activity关掉后,广播也就失效了。静态注册:无需担忧广播接收器是否被关闭,只要设备开启,广播接收器就有效。 2.1 静态注册

指的是在AndroidManifest.xml里声明,如下所示:


    
        
    

常见属性一般有name、exported(是否允许被其他应用调用),permission(启动service需要的权限)、process(该service所在进程,默认是在APP进程中,但可以指定其他进程),这里针对2个关键参数进行说明:

android:enabled属性:此broadcastReceiver能否接收其他App的发出的广播,默认值由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则为false。intent-filter中的android:priority属性:取值范围1000~-1000,数值越大,优先级别就越高。 2.2 动态注册

不在xml文件中配置,而是在代码中进行注册和注销。在activity中动态注册关键流程如下所示:

public class MainActivity extends AppCompatActivity {
    private static String TAG = "MainActivity";
	//1 定义receiver和filter
    MyReceiver myReceiver = new MyReceiver();
    IntentFilter filter = new IntentFilter();

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

    @Override
    protected void onResume() {
        super.onResume();
		//2 添加action
        filter.addAction("com.ags.myreceiver");
		//3 注册receiver
        registerReceiver(myReceiver,filter);
		Log.d(TAG, "onResume: registerReceiver");
    }

    @Override
    protected void onPause() {
        super.onPause();
		//4 注销receiver
        unregisterReceiver(myReceiver);
		Log.d(TAG, "onPause: unregisterReceiver");
    }
}

注意:注销 *** 作unregisterReceiver不要再onStop和onDestroy *** 作中进行,因为如果应用在后台运行,此时内存不足进行回收时,可能导致不回执行onStop和onDestroy *** 作,进而导致内存泄露。

3 BroadcastReceiver关键方法

BroadcastReceiver广播涉及2个角色:广播发送者 和  广播接收者。

3.1 广播发送者

广播分为普通广播和有序广播

普通广播:异步执行的广播,所有广播几乎会在同一时刻接收到该通知。有序广播:同步执行的广播,多个广播接收器可以设置不同的优先级,同一时间只有一个广播接收器会收到通知。一个广播接收者处理完给到下一个广播接收器,以此类推。

发送正常广播用 sendBroadcast;有序广播用 sendOrderedBroadcast。均属于Context类的方法。其方式如下:

//1 普通广播,异步,receiver1 receiver2 receiver3 几乎同时收到
sendBroadcast(new Intent("com.ags.myreceiver"));

//2 有序广播,同步,receiver1 receiver2 receiver3 依次收到
sendOrderedBroadcast(new Intent("com.ags.myreceiver"));
3.2  广播接收者

onReceive函数实现,代码如下所示:

public class MyReceiver extends BroadcastReceiver {
    private static String TAG = "MyReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        //接收广播并进行处理,可以接收intent消息,也可以做其他各种处理
        //注意:不要做耗时任务处理。如果有需要启动一个service来做
        String content = intent.getStringExtra("msg");
        Log.d(TAG, "onReceive content: "+content);
    }
}
4 LocalBroadcastManager本地广播

@1 LocalBroadcastManager是一种局部广播,广播的发送者和接收者都同属于一个App。

@2 LocalBroadcastManager的优劣势说明:

LocalBroadcastManager优势:广播是消耗资源较多的方式,若只在自己app内进行广播,可以采用本地广播。发送广播是在APP内,不会泄漏到别的APP中,且比BroadcastReceiver更高效。同时对于单个应用程序使用BroadcastReceiver存在安全风险。LocalBroadcastManager劣势:只能一个app内广播,不能跨进程通信。

@3 对比LocalBroadcastManager与BroadcastReceiver :

BroadcastReceiver底层是Binder机制,因此可以实现跨进程通信。LocalBroadcastManager底层是Handler机制,handleMessage中对广播进行处理。 4.1 LocalBroadcastManager发送端

public class MainActivity extends AppCompatActivity {
    private static String TAG = "MainActivity";
    private Button btn_start;

    private MyReceiver myReceiver = new MyReceiver();
    private IntentFilter filter = new IntentFilter();
    private LocalBroadcastManager localBroadcastManager = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1 本地广播管理者获取
        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        btn_start = findViewById(R.id.btn_start);
        btn_start.setonClickListener(new View.onClickListener() {
            @Override
            public void onClick(View v) {
				//Intent对象构建
                Intent intent  = new Intent();
                intent.setAction("com.ags.myreceiver");
                intent.setPackage("com.ags.myapplication");
                intent.putExtra("msg","receivertest");
				//4 本地广播发送
                localBroadcastManager.sendBroadcast(intent);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: registerReceiver");
        filter.addAction("com.ags.myreceiver");
		//2 本地广播注册
        localBroadcastManager.registerReceiver(myReceiver,filter);
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause: unregisterReceiver");
        super.onPause();
		//3 本地广播注销
        localBroadcastManager.unregisterReceiver(myReceiver);
    }
}

看代码我们会发现本地广播采用动态注册的方式,这里只不过不使用Context的注册/注销方式和发送广播的方式,而是 LocalBroadcastManager的注册/注销方式和发送广播的方式。

4.2 LocalBroadcastManager接收端

同上3.2,receiver部分并无差别,onReceive函数实现,代码依然如下所示:

public class MyReceiver extends BroadcastReceiver {
    private static String TAG = "MyReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        //接收广播并进行处理,可以接收intent消息,也可以做其他各种处理
        //注意:不要做耗时任务处理。如果有需要启动一个service来做
        String content = intent.getStringExtra("msg");
        Log.d(TAG, "onReceive content: "+content);
    }
}
5 接收系统广播消息

所谓系统广播,即系统完成某项任务后执行sendBroadcast或sendOrderedBroadcast相关 *** 作。对于APP本身而言只需要 静态/动态 注册广播监听器和配置好相应的权限,实现监听器中onReceive函数即可。

Android系统中内置很多系统广播,涉及到手机的基本 *** 作如:开机、网络状态变化、拍照等等,都会发出相应的广播。更多系统广播关注文档:Android 系统Broadcast Intents (API Level 30)总结

6 粘性广播(Sticky Broadcast)

粘性广播(Sticky Broadcast)在 android 5.0 就已经不再推荐使用,相应的还有粘性有序广播。

7官方文档索引

关于Broadcast更多内容查看文档:Android 组件之broadcast组件

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5708847.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存