精华内容
参与话题
问答
  • Broadcast的简单使用

    2020-04-21 14:27:27
    对于广播发送者来说,广播发送不需要考虑接收者的状态,只负责把广播发送出去即可,而对于哪个应用或者哪个进程接收广播不做关心,可以为广播接收者设置接收的优先级。 对于广播接收者来说,会受到各式...

    Android 中的广播Broadcast和生活中的广播一样,有发广播和接收广播的,通过静态注册和动态注册两种方式可以对广播接收器进行注册,然后才能接收广播,一人发送广播,多人接收广播,也存在有序广播和无序广播
    对于广播发送者来说,广播发送不需要考虑接收者的状态,只负责把广播发送出去即可,而对于哪个应用或者哪个进程接收广播不做关心,可以为广播接收者设置接收的优先级。
    对于广播接收者来说,会受到各式各样的广播,所以广播接收者通过过滤机制来拿到自己想要的广播内容
    1、发送广播

    public class broadcastTest extends AppCompatActivity {
        
        public static final String COM_HUANGDADA_INDEX = "com.huangdada.cn";
        private MyBoradcastReciver myBoradcastReciver;
        public TextView textView;
        private EditText text;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.broadcast_reciver);
            textView = findViewById(R.id.resultTextView);
            text = findViewById(R.id.inputEditText);
            myBoradcastReciver = new MyBoradcastReciver(textView);
            //动态注册广播接收器
            //为广播接收器添加action
            IntentFilter intentFilter=new IntentFilter();
            //系统广播
            intentFilter.addAction(Intent.ACTION_INSTALL_PACKAGE);
            //自定义广播
            intentFilter.addAction(COM_HUANGDADA_INDEX);
            //注册接收器
            registerReceiver(myBoradcastReciver,intentFilter);
            //自定义广播
            findViewById(R.id.sendBroadcastButton).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(v.getId()==R.id.sendBroadcastButton){
                        //相当于广播号,通过这个来识别是哪一个广播
                        Intent intent=new Intent(COM_HUANGDADA_INDEX);
                        //给广播添加信息
                        intent.putExtra("msg", text.getText().toString());
                        //发送广播
                        sendBroadcast(intent);
                    }
                }
            });
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //取消广播接收器,否则会导致内存泄漏
            if(myBoradcastReciver!=null){
                unregisterReceiver(myBoradcastReciver);
            }
        }
    }
    
    

    2、接收广播

    public class MyBoradcastReciver extends BroadcastReceiver {
        TextView text;
        private static final String TAG = "MyBoradcastReciver";
        public MyBoradcastReciver(TextView textView) {
            text=textView;
        }
        @Override
        public void onReceive(Context context, Intent intent) {
            String action=intent.getAction();
            String content=intent.getStringExtra("msg");
            if(TextUtils.equals(action,"com.huangdada.cn")){
                text.setText("广播号:\n"+ action+"\n 广播内容:\n"+content);
            }
        }
    }
    
    展开全文
  • Broadcast详解

    千次阅读 2013-02-19 21:23:06
    Android 中的BroadCastReceiver 作者:阿福 BroadCastReceiver 简介 (末尾有源码) BroadCastReceiver 源码位于: framework/base/core/java/android.content.BroadcastReceiver.java ...

    Android 中的BroadCastReceiver

    作者:阿福

    BroadCastReceiver 简介 (末尾有源码)

    BroadCastReceiver 源码位于: framework/base/core/java/android.content.BroadcastReceiver.java

    广播接收者( BroadcastReceiver )用于接收广播 Intent ,广播 Intent 的发送是通过调用 Context.sendBroadcast() 、 Context.sendOrderedBroadcast() 来实现的。通常一个广播 Intent 可以被订阅了此 Intent 的多个广播接收者所接收。

    广播是一种广泛运用的在应用程序之间传输信息的机制 。而 BroadcastReceiver 是对发送出来的广播进行过滤接收并响应的一类组件;

    来自普通应用程序,如一个应用程序通知其他应用程序某些数据已经下载完毕。

    BroadcastReceiver 自身并不实现图形用户界面,但是当它收到某个通知后, BroadcastReceiver 可以启动 Activity 作为响应,或者通过 NotificationMananger 提醒用户,或者启动 Service 等等。

    BroadCastReceiver 的机制

    1. 机制

    在 Android 里面有各种各样的广播,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。如图:


    2. 实现

    用接收短信举例:

    第一种方式

    实现

    public class MyBroadcastReceiver extends BroadcastReceiver {

    // action 名称

    String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ;

    public void onReceive(Context context, Intent intent) {

    if (intent.getAction().equals( SMS_RECEIVED )) {

    // 相关处理 : 地域变换、电量不足、来电来信;

    }

    }

    }

    系统注册:在 AndroidManifest.xml 中注册

    < receiver android:name = ".MyBroadcastReceiver" >

    < intent-filter android:priority = "1000" >

    < action android:name = " android.provider.Telephony.SMS_RECEIVED" />

    </ intent-filter >

    </ receiver > 当然了需要权限

    < uses-permission android:name = "android.permission.RECEIVE_SMS" />

    < uses-permission android:name = "android.permission.SEND_SMS" />

    第二种方式:

    // 广播接收者 - 广播的接收

    private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {

    @Override

    public void onReceive(Context context, Intent intent) {

    // 相关处理,如收短信,监听电量变化信息

    }

    };

    代码中注册:

    IntentFilter intentFilter = new IntentFilter( "android.provider.Telephony.SMS_RECEIVED " );

    registerReceiver( mBatteryInfoReceiver , intentFilter);

    3. 生命周期

    描述了 Android 中广播的生命周期,其次它并不像 Activity 一样复杂,运行原理很简单如下图:


    生命周期只有十秒左右,如果在 onReceive() 内做超过十秒内的事情,就会报错

    每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 当 onReceive() 方法在 10 秒内没有执行完毕, Android 会认为该程序无响应 . 所以在

    BroadcastReceiver 里不能做一些比较耗时的操作 , 否侧会弹出 ANR(Application No

    Response) 的对话框 . 。(如图):

    怎么用好 BroadcastReceiver ?

    如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成 . 这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束

    BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的

    所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的 .

    广播类型及广播的收发

    广播类型

    普通广播 (Normal broadcasts)

    发送一个广播,所以监听该广播的广播接收者都可以监听到改广播。

    异步广播 , 当处理完之后的Intent ,依然存在,这时候registerReceiver(BroadcastReceiver, IntentFilter) 还能收到他的值,直到你把它去掉 , 不能将处理结果传给下一个接收者 , 无法终止广播 .

    有序广播 (Ordered broadcasts)

    按照接收者的优先级顺序接收广播 , 优先级别在 intent-filter 中的 priority 中声明 ,-1000 到

    1000 之间 , 值越大 , 优先级越高 . 可以终止广播意图的继续传播 . 接收者可以篡改内容 .

    广播的收发

    该组件接收被广播的 intent,Context 可以通过 sendBroadcast() 和 sendOrderedBroadcast()

    方法实现广播的发送 .

    首先在需要发送信息的地方 ,把要发送的信息和用于过滤的信息 ( 如 Action 、 Category) 装入一个 Intent 对象 ,然后通过调用 Context.sendBroadcast() 、 sendOrderBroadcast() 或 sendStickyBroadcast() 方法,把 Intent 对象以广播方式发送出去。

    使用 sendBroadcast() 或 sendStickyBroadcast() 方法发出去的 Intent ,所有满足条件的 BroadcastReceiver 都会随机地执行其 onReceive() 方法

    普通广播的发送和接收:

    sendBroadcast(intent);

    Intent intent = new Intent( "cn.lenovo.yangguangf " );

    sendBroadcast(intent);

    priority :这个是 AndroidManifest.xml 中 intent-filter 的参数。

    < receiver android:name = ".MyBroadcastReceiver" >

    < intent-filter android:priority = "1000" >

    < action android:name = "cn.lenovo.yangguangfu" />

    </ intent-filter >

    </ receiver >

    sendOrderedBroadcast(intent, receiverPermission);

    1 ,他决定该广播的级别,级别数值是在 -1000 到 1000 之间 , 值越大 , 优先级越高;

    2 ,同级别接收是先后是随机的;级别低的收到广播;

    3 ,在 android 系统中只要监听该广播的接收者,都能够收到 sendBroadcast(intent) 发出的广播 ;

    3 ,不能截断广播的继续传播,

    4 ,实验现象,在这个方法发来的广播中,代码注册方式中,收到的广播的先后和注明优先级最高的他们的先后是随机。如果都没有优先级,代码注册收到为最先。

    有序广播的发送和接收:

    sendOrderedBroadcast(intent, receiverPermission);

    sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

    scheduler, initialCode, initialData, initialExtras)

    意图,广播,所有匹配的这一意图将接收机接收广播。

    receiverPermission 这是权限,一个接收器必须持以接收您的广播。如果为 null ,不经许可的要求。
    resultReceiver 您自己 BroadcastReceiver 来当作最后的广播接收器。
    调度自定义处理程序,用以安排 resultReceiver 回调 ; 如果为 null 将语境中的主线程举行。
    initialCode 一种结果代码的初始值。通常为 Activity.RESULT_OK 。这个值是 -1 ;为其他 int 型 也可以,如 0,1,2 ;
    initialData 一种结果数据的初始值。通常情况下为空 , 是 String 类型 ;
    initialExtras 一种结果额外的初始值。通常情况下为空 , 是 Bundle;

    intent The Intent to broadcast; all receivers matching this Intent will receive the broadcast.

    receiverPermission String naming a permissions that a receiver must hold in order to receive your broadcast. If null, no permission is required.

    resultReceiver Your own BroadcastReceiver to treat as the final receiver of the broadcast.

    scheduler A custom Handler with which to schedule the resultReceiver callback; if null it will be scheduled in the Context's main thread.

    initialCode An initial value for the result code. Often Activity.RESULT_OK.

    initialData An initial value for the result data. Often null.

    initialExtras An initial value for the result extras. Often null.

    1, 该广播的级别有级别之分,级别数值是在 -1000 到 1000 之间 , 值越大 , 优先级越高;

    2, 同级别接收是先后是随机的,再到级别低的收到广播;

    3, 同级别接收是先后是随机的,如果先接收到的把广播截断了,同级别的例外的接收者是无法收到该广播的。( abortBroadcast() )

    4 ,能截断广播的继续传播,高级别的广播收到该广播后,可以决定把该钟广播是否截断掉。

    5 ,实验现象,在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先。

    异步广播的发送和接收:

    sendStickyBroadcast(intent);

    当处理完之后的Intent ,依然存在,直到你把它去掉。

    发这个广播需要权限<uses-permission android:name="android.permission.BROADCAST_STICKY" />

    去掉是用这个方法removeStickyBroadcast(intent); 但别忘了在执行这个方法的应用里面 AndroidManifest.xml 同样要加上面的权限;

    sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

    initialCode, initialData, initialExtras)

    这个方法具有有序广播的特性也有异步广播的特性;


    发送这个广播要: <uses-permission android:name="android.permission.BROADCAST_STICKY" /> 这个权限。才能使用这个方法。如果您并不拥有该权限,将抛出 SecurityException 的。

    实验现象( sendStickyOrderedBroadcast ()中),在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先。

    广播注册与注销

    代码中注册广播:

    注册广播方法一: registerReceiver(BroadcastReceiver receiver, IntentFilter filter) ,第一个参数是我们要处理广播的 BroadcastReceiver (广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器。

    注册广播方法二: registerReceiver(receiver, filter, broadcastPermission, scheduler) ,第一个参数是 BroadcastReceiver (广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器;第三个参数是广播权限;第四个参数是 Hander ;

    注意:权限重复现象,如果功能清单文件里注册了权限,在该方法再注册,则 receiver 无法收到广播,如果 功能清单文件里没有注册了权限,该方法注册也无法收到。当该方法没有注册权限,功能清单里注册的时候, receiver 能收到广播。

    总结:在 Activity 中代码注册广播建议在: onResume() 中注册;

    思维拓展: 1 ,如果在代码调用 registerReceiver(BroadcastReceiver receiver, IntentFilter filter) 十次( receiver , filter 的参数是同一参数),那么是否当该广播发送来的时候会收到十次呢?

    2 ,注销是否也要注销十次才能把广播全部注销呢?

    系统中注册广播:(在 AndroidManifest.xml 中 )

    < receiver android:name = ".MyBroadcastReceiver" >

    < intent-filter android:priority = "900" >

    < action android:name = "cn.lenovo.yangguangfu" />

    </ intent-filter >

    </ receiver >

    有时候还要根据发送广播是否指定权限,来决定是否要权限;

    广播注销

    // 代码中注销广播

    /unregisterReceiver(mBatteryInfoReceiver);

    在 Activity 中代码注销广播建议在: onPuase() 中注销;

    不要这这里面注销 Activity.onSaveInstanceState(), 因为这个方法是保存 Intent 状态的。

    BroadCastReceiver 的 API

    abortBroadcast ():

    这个方法可以截获由 sendOrderedBroadcast () 发送来的 广播,让其它广播接收者无法收到这个广播。

    clearAbortBroadcast ()

    这个方法是针对上面的 abortBroadcast() 方法的,用于取消截获广播。这样它的下一级广播接收者就能够收到该广播了。

    getAbortBroadcast ()

    这个方法作用是:判断是否调用了 abortBroadcast (),如果先调用 abortBroadcast (),接着再调用 getAbortBroadcast (),将返回 true; 如果在调用 abortBroadcast() 、 clearAbortBroadcast ()

    getAbortBroadcast (),将返回 false;

    public final boolean getDebugUnregister ()

    Since: API Level 1

    Return the last value given to setDebugUnregister(boolean) .

    getResultCode ()

    如果用下面四个方法发送得广播,返回码为: -1 ;

    // sendBroadcast(intent);

    // sendBroadcast(intent, receiverPermission);

    // sendOrderedBroadcast(intent, receiverPermission);

    // sendStickyBroadcast(intent);

    如果用下面两个方法发送得广播,返回码为:根据你设置 initialCode 的数字是多少就是多少;

    // sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

    // initialCode, initialData, initialExtras)

    // sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

    // scheduler, initialCode, initialData, initialExtras)

    getResultData ()

    得到发送广播时设置的 initialData 的数据;

    getResultExtras (boolean makeMap)

    If true then a new empty Map will be made for you if the current Map is null; if false you should be prepared to receive a null Map.

    得到由

    sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

    // initialCode, initialData, initialExtras) ;

    // sendOrderedBroadcast(intent, receiverPermission, resultReceiver,

    // scheduler, initialCode, initialData, initialExtras)

    中 initialExtras 传入的参数。

    实验:我用上面两个方法发了 initialExtras (这个一个 Bundle )传入的参数时,只要不为空,那么 makeMap 是否为 true 和 false 都能够得到数据。

    isInitialStickyBroadcast ()

    Returns true if the receiver is currently processing the initial value of a sticky broadcast -- that is, the value that was last broadcast and is currently held in the sticky cache, so this is not directly the result of a broadcast right now.

    如果广播接收者是目前处理的一个宿主的广播的初始值,将返回 true , - 也就是说,这个值是最后的广播出的值,目前正在举行的宿主缓存,所以这并不是直接导致了现在的广播。

    实验:在第三个应用中调用这个方法,无论你用哪种方式发送广播,这个方法得到的总是 false ;在发送广播 的 resultReceiver 广播接收者里面调用,得到的也是 false ;

    isOrderedBroadcast ()

    sendStickyOrderedBroadcast(intent, resultReceiver, scheduler,

    initialCode, initialData, initialExtras)

    上面这个方法发送时,得到的是 true;

    判断是否是有序广播;

    onReceive (Context context, Intent intent)

    public IBinder peekService (Context myContext, Intent service)

    Provide a binder to an already-running service. This method is synchronous and will not start the target service if it is not present, so it is safe to call from onReceive.

    Parameters:

    myContext The Context that had been passed to onReceive(Context, Intent)

    service The Intent indicating the service you wish to use. See Context.startService(Intent) for more information.

    setDebugUnregister (boolean debug)

    Control inclusion of debugging help for mismatched calls to {@ Context#registerReceiver(BroadcastReceiver, IntentFilter) Context.registerReceiver()}. If called with true, before given to registerReceiver(), then the callstack of the following Context.unregisterReceiver() call is retained, to be printed if a later incorrect unregister call is made. Note that doing this requires retaining information about the BroadcastReceiver for

    • 大小: 231.1 KB
    • 大小: 16.1 KB
    • 大小: 49.6 KB
    • 大小: 86 KB
    • 大小: 53.7 KB
    • 大小: 41.8 KB
    • 大小: 156.6 KB
    • 大小: 20.8 KB
    • 大小: 39.7 KB
    • 大小: 67.3 KB
    • 大小: 67.3 KB
    • 大小: 14.9 KB
    • 大小: 25.4 KB
    展开全文
  • Broadcast彻底解析

    千次阅读 2017-06-05 21:38:14
    一:Broadcast彻底解析1,Broadcast就是将数据从一个节点发送到其他的节点上;例如Driver上有一张表,而Executor中的每个并行的Task(100万个Task)都要查询这张表,那我们通过Broadcast方式就只需要往每个Executor...

    一:Broadcast彻底解析

    1,Broadcast就是将数据从一个节点发送到其他的节点上;例如Driver上有一张表,而Executor中的每个并行的Task(100万个Task)都要查询这张表,那我们通过Broadcast方式就只需要往每个Executor把这张表发送一次就行了,Executor中的每个Task查询这张唯一的表,而不是每次执行的时候都从Driver获得这张表!

    2,这就好像ServletContext的具体作用,只是Broadcast是分布式的共享数据,默认情况下只要程序在运行Broadcast变量就会存在,因为Broadcast子底层是通过BroadcastManager管理的!但是你可以手动指定或者配置具体周期来销毁Broadcast变量!

    3,Broadcast一般用于处理共享配置文件、通用的DataSet、常用的数据结构等等;但是不适合存放太大的数据在Broadcast,Broadcast不会内存溢出,因为其数据的保存的StoreLevel是MEMORY_AND_DISK的方式;虽然如此,我们也不可以放入太大的数据在Broadcast中,因为网络IO和可能的单点压力会非常大!

    4,Broadcast变量是只读变量,最为轻松保持了数据的一致性!

    5,Broadcast的使用:

    * {{{
    * scala> val broadcastVar = sc.broadcast(Array(1, 2, 3))
    * broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int]] = Broadcast(0)
    *
    * scala> broadcastVar.value
    * res0: Array[Int] = Array(1, 2, 3)
    * }}}

    6,HttpBroadcast方式的Broadcast,最开始的时候数据放在Driver的本地文件系统中,Driver在本地会创建一个文件夹来存放Broadcast中的data,然后启动HttpServer来访问文件夹中的数据,同时写入到BlockManager(StorageLevel是MEMORY_AND_DISK)中获得BlockId(BroadcastBlockId),当Executor中的Task要访问Broadcast变量的时候,会向Driver通过HttpServer来访问数据,然后会在Executor中的BlockManager中注册该Broadcast中的数据,这样后要的Task需要访问Broadcast的变量的时候会首先查询BlockManager中有没有该数据,如果有就直接使用;

    7,BroadcastManager是用来管理Broadcast,该实例对象是在SparkContext创建SparkEnv的时候创建的:

    // Called by SparkContext or Executor before using Broadcast
    private def initialize() {
      synchronized {
        if (!initialized) {
          val broadcastFactoryClass =
            conf.get("spark.broadcast.factory", "org.apache.spark.broadcast.TorrentBroadcastFactory")
    
          broadcastFactory =
            Utils.classForName(broadcastFactoryClass).newInstance.asInstanceOf[BroadcastFactory]
    
          // Initialize appropriate BroadcastFactory and BroadcastObject
          broadcastFactory.initialize(isDriver, conf, securityManager)
    
          initialized = true
        }
      }
    }

    在实例化BlockcastManager的时候会创建BlockcastFactory工厂来构建具体实际的Brockcast类型,默认情况下是TorrentBroadcastFactory;

    8,HttpBroadcast存在单点故障,和网络IO性能问题,所以默认使用TorrentBroadcast的方式,开始数据在Driver中,假设A节点用了数据,B访问的时候A节点就变成数据源,依次类推,都是数据源,当然是被BlockManger进行管理的,数据源越多,节点压力会大大降低;

    9,TorrentBroadcast按照BLOCK_SIZE(默认是4MB)将Broadcast中的数据划分成为不同的Block,然后将分块信息也就是meta信息存放到Driver的 BlockManager中,同时会告诉BlockManagerMaster说明Meta信息存放完毕。

    10,TorrentBroadcast存在慢启动和占内存!

    展开全文
  • Broadcast的种类和基本使用

    千次阅读 2018-05-11 20:55:58
    1.广播是什么1.1 定义  在Android中,它是一种广泛运用在应用程序之间传输信息的机制,Android中我们发送广播内容是一个Intent,这个Intent中可以携带我们要发送的数据。1.2 广播的使用场景  a....

    1.广播是什么

    1.1 定义

      在Android中,它是一种广泛运用在应用程序之间传输信息的机制,Android中我们发送广播内容是一个Intent,这个Intent中可以携带我们要发送的数据。

    1.2 广播的使用场景

      a.同一app内有多个进程的不同组件之间的消息通信。

      b.不同app之间的组件之间消息的通信。

    1.3 广播的种类

      标准广播:context.sendBroadcast(Intent)方法发送的广播,不可被拦截

      有序广播:context.sendOrderBroadcast(Intent)方法发送的广播,可被拦截

      本地广播:localBroadcastManager.sendBroadcast(Intent),只在app内传播

    2.广播接收器

      广播接收器是专门用来接收广播信息的,它可分为静态注册和动态注册:

      静态注册:注册完成一直在运行。

      首先你要创建一个广播接收器类,实例代码如下:

    public class BootCompleteReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

      代码非常简单,我们只是在onReceive()方法中使用Toast弹出一段信息提示信息。 
    另外,静态的广播接收器一定要在AndroidManifest.xml文件中注册才可以使用,AndroidManifest.xml文件中注册静态广播代码如下:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.example.broadcasttest"
           android:versionCode="1"
           android:versionName="1.0" >
           ……
          <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
          <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
          <application
               android:allowBackup="true"
               android:icon="@drawable/ic_launcher"
               android:label="@string/app_name"
               android:theme="@style/AppTheme" >
               ……
    
               <receiver 
                   android:name=".BootCompleteReceiver" >
                   <intent-filter>
                       <action android:name="android.intent.action.BOOT_COMPLETED" />
                   </intent-filter>
               </receiver>
          </application>
    </manifest>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

      可以看到,标签内出现了一个新的标签,所有静态的广播接收器都是在这里进行注册的。它的用法其实和标签非常相似,也是通过android:name来指定具体注册哪一个广播接收器,而enabled和exported属性则是根据我们刚才勾选的状态自动生成的,也可以自己添加,没有就自己添加嘛!

      动态注册:跟随Activity的生命周期。

      如何创建一个广播接收器呢?其实就需要新建一个类,让它继承自BroadcastReceiver,并重写父类的onReceive()方法就行了。这样有广播到来时,onReceive()方法就会得到执行,具体的逻辑就可以在这个方法中处理。来个简单的例子来理解以下,如何监听网络变化呢?其实就是新建一个广播接收器去接收来自系统网络变化的广播即可,代码如下所示:

    public class MainActivity extends AppCompatActivity{
    
        private IntentFilter intentFilter;
    
        private NetWorkChangeReceiver netWorkChangeReceiver;
    
        @Override
        protected void onCreate(Bundle savedInstanceState){
            super.Oncreata(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            intentFilter = new IntentFilter();
            intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
            networkChangeReceiver = new NetWorkChangeReceiver();
            registerReceiver(networkChangeReceiver, intentFilter);//注册广播接收器
    
        }
    
        @Overrid
        protected void onDestroy(){
            unregisterReceiver(networkChangeReceiver);//一定要记得取消广播接收器的注册
            super.onDestroy();
    
        }  
    
        class NetworkChangeReceiver extends BroadcastReceiver{//广播接收器类
    
            @Override
            public void onReceiver(Context context,Intent intent){
    
                //这里需要权限,需要在AndroidManifest.xml中进行网络访问权限申请:
                //<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
                ConnectivityManager connectionManager = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
    
                if (networkInfo != null && networkInfo.isAvailable()) {
    
                      //有网
                      Toast.makeText(context, "network is available",Toast.LENGTH_SHORT).show();
    
                } else {
    
                      //无网
                      Toast.makeText(context, "network is unavailable",
                      Toast.LENGTH_SHORT).show();
                }
            }
    
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

      动态注册广播接收器的优点以及缺点:动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大优势,但是它也存在着一个缺点,即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中的。那么有没有广播能在程序未启动的情况下就能接收到广播呢?静态注册的广播接收器就可以做到。

    3.广播内部实现机制

      a.自定义广播接收者BroadcastReceiver,并且重写onReceiver()方法。

      b.通过Binder机制向AMS(Activity Manager Service)进行注册。

      c.广播发送者通过Binder机制向AMS发送广播。

      d.AMS查找符合条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到相应的BroadcastReceiver(一般情况下是Activity)的消息队列中。

      e.消息循环执行拿到此广播,回调BroadcastReceiver中的onReceiver()方法。

    4.本地广播

      本地广播的发送和注册广播接收器都需要使用到LocalBroadcastManager类,如下所示为本地广播的发送和本地广播接收器注册的代码:

      本地广播的发送:

    public static void sendLocalBroadcast(Context context,String action){
    
        Intent intent = new Intent(action);
        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
        localBroadcastManager.sendBroadcast(intent);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

      本地广播的接收器的注册:

        IntentFilter intentFilter = new IntentFilter();
        LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
    
        intentFilter.addAction(new BroadcastUtil().action_next);
        nasbr = new NextAndStartBroadcastReceiver();
        localBroadcastManager.registerReceiver(nasbr, intentFilter);//注册本地广播接收器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

      相比于系统广播而言,本地广播更加安全,更加高效,以下是本地广播的特点以及内部的实现机制:

      特点:

      a.使用它发送的广播将只在自身app内传播,因此你不必担心泄漏隐私的数据。

      b.其他app无法对你的app发送该广播,因此你的app根本不可能收到非自身app发送的该广播,因此你不必担心有安全漏洞可以利用。

      c.比系统广播更加高效。

      内部实现机制:

      a.LocalBroadcast高效的原因:因为它内部是通过Handler实现的,它的sendBroadcast()方法含义并非和系统的sendBroadcast()一样,它的sendBroadcast()方法其实就是通过Handler发送了一个Message而已。

      b.LocalBroadcast安全的原因:既然它是通过Handler实现广播发送的,那么相比系统广播通过Binder机制实现那肯定更加高效,同时使用Handler来实现,别的app无法向我们应用发送该广播,而我们app内部发送的广播也不会离开我们的app。

      LocalBroadcast内部协作主要是靠两个Map集合:mReceivers和mActions,当然还有一个List集合mPendingBroadcasts,这个主要存储待接收的广播对象。

    展开全文
  • BroadCast的两种使用方法

    千次阅读 2018-10-14 10:20:36
    1、 简单的介绍一下BroadCast的使用,理论方法的比较欠缺,以下内容纯粹是自己的个人总结,不足之处,欢迎大家提出宝贵的意见,程序代码运行,真是有效,可以使用 2、BroadCast是安卓四大组件之一,和Service不一样...
  • Broadcast 使用详解

    2019-09-28 20:11:54
    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容: ...
  • Broadcast 广播

    2019-05-05 20:28:09
    种类:普通广播,系统广播,本地广播 ,粘性广播 。 正式因为静态注册耗电、占内存、不受程序生命周期影响,所以Google在Android 8.0上禁止大部分广播的静态注册——Android 8.0新...BroadcastRec...
  • Broadcast功能

    2018-09-11 10:38:22
    顾名思义,broadcast 就是将数据从一个节点发送到其他各个节点上去。这样的场景很多,比如 driver 上有一张表,其他节点上运行的 task 需要 lookup 这张表,那么 driver 可以先把这张表 copy 到这些节点,这样 task ...
  • broadcastreceiver全面详解

    千次阅读 2018-09-08 10:36:18
    目录     ...即 广播,是一个全局的监听器,属于Android四大组件之一 ...Android 广播分为两个角色:广播发送者、广播接收者 ...监听 / 接收 应用 App 发出的广播消息,并 做出响应 ...如:电话呼入时...
  • Broadcast功能

    千次阅读 2018-03-09 11:03:53
    顾名思义,broadcast 就是将数据从一个节点发送到其他各个节点上去。这样的场景很多,比如 driver 上有一张表,其他节点上运行的 task 需要 lookup 这张表,那么 driver 可以先把这张表 copy 到这些节点,这样 task ...
  • Broadcast学习笔记

    万次阅读 2014-09-04 21:54:27
    1、mIntentSenderRecords 是一个PendingIntentRecord哈希表。一个PendingIntentRecord对象对应的是应用层的一个PendingIntent对象(延迟性的intent),其中包含send系列方法,主要用于触发PendingIntent的Intent行为。...
  • Broadcast(广播接收者和发送者)

    千次阅读 2017-07-11 20:19:20
    1.BroadcastReceiver,顾名思义是:广播接受者。是四大组件之一,这种组件本质上是一种全局的监听器,用于监听系统全局的广播消息。可接受来自系统和应用系统和应用的的广播。 2.好处:  因BroadcastReceiver是一...
  • Spark的broadcast

    千次阅读 2018-06-30 09:32:23
    Spark的Broadcast 1. 概述 在实际场景中,当1个function传递到1个spark operation(例如:map、reduce)时,这个function是在远程的集群node上被执行的。这些变量会被复制到每一台机器,在远程机器上不会更新...
  • BroadCast

    2018-09-30 18:13:08
    使用打开关闭数据网络,触发BroadCast 1、新建BroadCastTest工程; 2、新建MyBroadCast  在OnReceive()增加一句显示代码 Toast.maketext().show(); 3、在MainActivity中定义两个变量;  private ...
  • Spark Broadcast

    2018-09-05 21:44:28
    顾名思义,broadcast 就是将数据从一个节点发送到其他各个节点上去。这样的场景很多,比如 driver 上有一张表,其他节点上运行的 task 需要 lookup 这张表,那么 driver 可以先把这张表 copy 到这些节点,这样 task ...
  • Broadcast发送流程分析

    千次阅读 2020-03-05 11:30:20
    Android Source Tools : androidxref....Original stack trace: android.app.RemoteServiceException : can’t deliver broadcast at android.app.ActivityThreadH.handleMessage(ActivityThread.java:2038)atandroi...
  • 第42课: Spark Broadcast内幕解密:Broadcast运行机制彻底解密、Broadcast源码解析、Broadcast最佳实践Broadcast在机器学习、图计算、构建日常的各种算法中到处可见。 Broadcast就是将数据从一个节点发送到其它的...
  • 先来看下log: 11-05 00:00:09.609 688 3933 W ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:966 ...
  • Spark SQL中的broadcast join分析

    万次阅读 2017-03-25 21:34:57
    本文分析Spark-1.6.2中大小表join时的broadcast机制。分析源码执行逻辑,并且对源码进行一定的调整。
  • Spark BroadCast 解析

    千次阅读 2018-01-28 14:17:39
    前言 在实际使用中对于一些许多rdd需要用到的大的只读数据集变量可以使用共享变量的方式来提高性能,例如查内存表,默认情况下会每个task都保存一份,这样太浪费...Broadcast代码还涉及到spark底层存储代码BlockMana

空空如也

1 2 3 4 5 ... 20
收藏数 187,133
精华内容 74,853
关键字:

broadcast