葡京娱乐注册Android组件连串—-布罗兹castReceiver广播接收器

【声明】 

在 Celery
中,除了远程序控制制之外,还有一个要素得以让大家对分布式中的职分的景况有所掌握控制,而且从实际意义上的话,这一个成分对
Celery 更为首要,这就是在本文军长要说到的 伊夫nt。

欢迎转发,但请保留小说原来出处→_→ 

在 Celery 中,注册了许多的 伊芙nt,那一个 伊芙nt 将会在 Task/Worker
的意况爆发变化的时候被发生,然后被绑定的 伊夫nt
消费者(Receiver)所承受,绑定的 伊夫nt
消费者能够是千家万户的回调函数,相信细心的校友在前方的源码解析进程中也有发现有个别有关
event 的马迹蛛丝,可是,作者都以忽视了先,上边就规范得给大家介绍 伊芙nt。

生命壹号:http://www.cnblogs.com/smyhvae/ 

伊夫nt 有哪些用

前面说了,Celery 在 Task/Worker 的景观爆发变化的时候就会时有发生伊夫nt,所以,二个很扎眼的利用就是监督检查 Event 的意况,例如 Celery
我们所熟习的基于 WebUI 的管理工科具 flower 就用到了
伊夫nt,但是,那也是3个相比显明的施用,除了这一个之外,我们还足以行使 伊芙nt
来给 Task 做快速照相,甚至实时对 Task
的事态转变做出响应,例如职责败北以后触发报告警方,任务成功今后执行被正视的任务等等,总括一下,其实便是:

  1. 对 Task 的景色做快速照相
  2. 对 Task 的处境抓实时处理
  3. 督查 Celery(Worker/Task) 的施市场价格况

作品来源:http://www.cnblogs.com/smyhvae/p/3960623.html

Event 的实现

刺探完 伊芙nt 的职能之后,大家那边一向跳过了 伊芙nt
的行使实例,因为这一个能够不用实例,而是大家依据前边的介绍,然后大家就领会了亟待领会一下:

  1. 伊芙nt 是什么发生的
  2. 伊夫nt 的传递机制是什么样落实的
  3. 伊芙nt 的拍卖机制怎么着

笔者也将遵从那多少个难题的逐一对 Celery 的实现举办贰个总计。

 

伊夫nt 是哪些发生的

当今大家早就知晓了 伊夫nt 是 Task/Worker
爆发的,所以出处必然在这几个达成中,那就毫无难度了。不妨,大家就从最简便易行的地点出发,看看
Worker 的 伊芙nt 是怎么样发生的,据小编所知,未来 Worker 拥有的 伊夫nt
有八个:

  • worker-online
  • worker-heartbeat
  • worker-offline

对于 worker-online 那么相应正是在 Worker
的起步进度中,所以大家如故回到第壹篇作品中的介绍,看看里面有何能够参见的。借使你回来看了的话,肯定会发现
Consumer 这个 Blueprint 里面有一个叫做 Event
Bootstep,那里很怀疑,不妨去探望:

葡京娱乐注册 1

well,那里看上去没啥有意思的,不过,看 Line 26 大家得以一定的一点是
伊芙nt 是还是不是可用还会在乎大家是否同意
gossip,那些是甚我们还不知情,不过无妨,先两次三番看下去,那里还有二个东西值得大家关切,那就是
event_dispatcher,不过那里还没啥可看的,终究是 None 嘛。

我们只是看到了冰山一角,继续看看 start 又在干嘛:

葡京娱乐注册 2

这边首先句上来就是 close,有点蒙蔽啊,啥都不通晓您就先上来 close
了,是否十分的低落,没涉及,笔者报告您那边是干啥的,那里正是消除 Celery
之前的 event_dispatcher,然后将事先的 event_dispatcher
重临回来,重临来干啥?在 Line 47 会根据在此之前的布局安装新的
event_dispatcher 啊,至于你先知道 event_dispatcher 是啥,看 Line
36
就知晓呀,能够看看那正是3个 Dispatcher
的靶子,所以大家须求关心一下以此目的了。

可是出于 Dispatcher
这一个类太复杂,笔者就不一一摊开讲了,不妨看看大家供给直面包车型地铁几个方法,第多个是
extend_buffer,看看:

葡京娱乐注册 3

这里的 _outbound_buffer 是一个 deque,所以大家得以清楚其实正是将旧的
event 继承过来,替旁人背一下锅。继续看看 flush 在干些吗:

葡京娱乐注册 4

嗬,那些有个别复杂点了,不过无妨,依旧要探望,Line 204
那里只是简单得将 deque 转换为 list,然后 Line 207 、208
那里有点看头啊,那里正是出殡和埋葬 伊芙nt
了!!!难道大家已经做到职务了?已经意识了什么样发生消息了?然而,立刻大家在后头又发现了还有一个groups 的事物,那里发送音信又不雷同?不管了,先来看望 _publish 干啥:

葡京娱乐注册 5

看一下 _publish 的代码,感觉没了意思,又是选取 AMQP,Celery 那是讲 MQ
贯彻到底啊!那宛如不可能了,那里正是完了,不过,我们的政工却还没完,因为此处都以针对的旧的职分,大家期望观察的
worker-online 还没见到吗,但是 Bootstep
的做事却是落成了,就像那里线索就断了。

然则,同样细心的同班只怕会记得,我们事先已经说过2个叫做 Heart
Bootstep,它的任务是干啥来着?借使忘记了,不妨回到第1篇回看一下,记得的话,大家进代码看看,哈哈哈

葡京娱乐注册 6

nice,你会发现,这几个 Bootstep 是注重于 Events 的,同时在 Line
29
中给您会发觉就用到了大家恰好起头化的 event_dispatcher,然后就调用
start 了,所以不妨一块儿看看:

葡京娱乐注册 7

哈哈,看到没,那里就是 worker-online
的发生地了,而且大家还附带捕捉到了 worker-heartbeat 这个 Event,so
lucky,然则有个地点我们不明的,这正是其一 _send
干了什么样,倘诺不出意料的话,应该是调用的
dispatcher._publish,走,看看去:

葡京娱乐注册 8

好,并不曾依据本身的覆辙来,调用的竟然是 event_dispatcher
send,那么它和 _publish 有怎么着分别呢?不妨一块儿看一看:

葡京娱乐注册 9

这里和 _publish 的唯一不相同的地点正是做了缓存处理,正是在 Line
185
那里,借使须要缓存,那么缓存一波,在 Line 192
这里要是缓存满了,那么就发送呗。有好几值得注意的正是在 Line
198
,那里调用的是 publish 而不是
_publish,搞那么多事,那么那里有有哪些不雷同?

葡京娱乐注册 10

好呗,从此处看犹如除了对 clock
进行三个操作之外,没有其余很是之处,那么那一个 clock
又是什么样,起到如何功用吗?略微查找就知晓了,那又是 Kombu
的事物,然后看表明就领会了那是一个 Counter,能够用来给 Consumer
判定是还是不是接受这么些 Event 用的,所以大家得以先
pass。所以,总得来说,我们能够发现,那里曾经对 伊夫nt
的产生有了必然了然了,那里能够生出的一个比较鲜明的标题点正是:Celery
中 Event 的 send、publish 和 _publish
的区分是什么?

【正文】

音讯的传递机制

在跟踪 伊夫nt 的发出的经过中大家早已有意无意将 伊芙nt 的发送给看了,其实仍然Kombu 的 AMQP 在效益,然后通过 Connection 发送到对应的 MQ 中,再前面就被
Consumer 接收,全链路正是如此:

Event<Producer> ------> MQ ---------> Event<Consumer>(Receiver)

前半有的我们已经知道了,可是后半局地还不知道,所以大家的最主要就是探望后半部分具体是如何做的。然而后半有些要从什么地方入手那是个难点,作者那边省去了探寻的经过,直接说一下入口吧,地点就在
celery/bin/events.py,对于任一一种 伊夫nts,大家必要关切的是
run_evtop 这几个函数,所以先来看望:

葡京娱乐注册 11

此地很简单,继续跟下去看看咯:

葡京娱乐注册 12

那里有点意思了,不过如故得以比较简单得看看 Line 529 是关键所在:

葡京娱乐注册 13

总的来看此间我们就该偷笑了,看到 while 1
就象征差不离到最终了,哈哈,Line 508 使用的是 read
Connection,然后 Line 512 创立了3个 Receiver,在 Line 515
进行 capture,所以大家可以看清,我们想找的就在那两句里面了,直接看
Line 515 吧:

葡京娱乐注册 14

此间有点意思的正是又是赶上 Kombu 的锅:

class kombu.mixins.ConsumerMixin[source]
Convenience mixin for implementing consumer programs.

It can be used outside of threads, with threads, or greenthreads
(eventlet/gevent) too.

The basic class would need a connection attribute which must be a
Connection instance, and define a get_consumers() method that returns
a list of kombu.Consumer instances to use. Supporting multiple
consumers is important so that multiple channels can be used for
different QoS requirements.

此地其实是有多个 伊夫ntReceiver 绑定了那几个 Connection,然后
ConsumerMixin 协理协调这一个 Receiver,各类 Receiver 都足以吸收接纳那个伊芙nt,可是能或不能够处理就看她们的 routing_key 设置得好倒霉了。

① 、广播的成效和天性

伊芙nt 的拍卖体制

看完 伊夫nt 的接受机制大家领悟了 伊芙nt 是以 AMQP
的款式收取的,那么毫不以为,处理逻辑应该在回调机制上回调的,所以主要照旧在于
Line 512 中的 handlers,大家来瞅着:

葡京娱乐注册 15

Receiver 中的 process 大家发现了他是那样用 handlers
的,那么没难点,state.event 才是终极的首要性,state
中间做了两层的包裹,到最后就成了
_create_dispatcher,可是同样得,那些函数也是比较复杂,所以自个儿那里对他进行切中要害一下,回顾起来是这样的:

  1. 先找 group
    handler,有的话就用这个了,不然看下边;这些私下认可是没东西的,所以能够先pass
  2. 如果是 worker 的 伊夫nt,就举办 worker 对应的拍卖
  3. 如果是 task 的 伊夫nt,就实施 task 的应和处理

OK,那基本上便是 伊芙nt 的情节啦,关于
伊夫nt,前面有更尽善尽美的应用会说到,不知道用 Celery
的同班日常对那天性子有没有应用的场所?

  • 广播的生命周期非常的短,经过调用对象–>实现onReceive–>甘休,整个进程就得了了。从完成的复杂度和代码量来看,广播无疑是最迷你的Android
    组件,实现多次只需几行代码。广播对象被组织出来后平日只进行BroadcastReceiver.onReceive方法,便结束了其生命周期。所以某个时候大家得以把它看做函数看也不至于不可。
  • 和兼具组件一样,广播对象也是在采用进度的主线程中被组织,所以广播对象的实施必须是要协同且神速的。也不推荐在内部开子线程,因为屡次线程还未完工,广播对象就已经举办完成被系统销毁。假诺急需形成一项相比较耗费时间的工作
    , 应该通过发送 Intent 给 Service, 由 Service 来达成。
  • 每一次广播到来时 , 会重新创制 布罗兹castReceiver 对象 , 并且调用
    onReceive() 方法 , 执行完今后 , 该对象即被灭绝 . 当 onReceive()
    方法在 10 秒内尚未履行达成, Android 会认为该程序无响应。

 

贰 、接收系统广播:

广播接收器可以肆意地对自个儿感兴趣的播报举行登记,那样当有相应的广播发出时,广播接收器就能接到该广播,并在内处相应的逻辑。注册广播的格局有两种,在代码中登记和在清单文件中登记,前者称为动态注册,后者称为静态注册。

壹 、动态注册监听网络转移:

新建筑工程程文件,首先在MainActivity中定义多个里面类netWorkChangeReceiver,天公地道写父类的onReceive()方法,那样每当网络状态爆发变化时,onReceive()方法就会获取实施,那里运用Toast提醒一段文本新闻,代码如下:

class netWorkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
        }        
    }

随着在onCreate方法中开始展览动态注册,然后在onDestroy方法中展开撤销注册:

 1     private IntentFilter intentFilter;
 2     private netWorkChangeReceiver netWorkChangeReceiver;
 3     
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.activity_main);
 8         
 9         //动态注册:创建一个IntentFilter的实例,添加网络变化的广播(功能是对组件进行过滤,只获取需要的消息)
10         intentFilter = new IntentFilter();
11         intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
12         //创建NetWorkChangeReceiver的实例,并调用registerReceiver()方法进行注册
13         netWorkChangeReceiver = new netWorkChangeReceiver();
14         registerReceiver(netWorkChangeReceiver, intentFilter);
15         
16     }
17 
18     //取消注册,一定要记得,不然系统会报错
19     @Override
20     protected void onDestroy() {
21         super.onDestroy();
22         unregisterReceiver(netWorkChangeReceiver);
23     }

上边代码解释如下:

11行:给意图过滤器intentFilter添加二个值为android.net.conn.CONNECTIVITY_CHANGE的action。因为每当互联网状态发生变化时,系统就会生出一条值为android.net.conn.CONNECTIVITY_CHANG的广播。

注:最终要记得,动态注册的播报接收器一定要撤废注册才行。

运作程序,就足以了。

然则只是提示互联网产生变化还不够人性化,为了能够精确的告知用户近来是有互联网大概尚未互连网,大家还亟需对上述代码进一步优化,修改netWorkChangeReceiver中的代码如下:

 1     class netWorkChangeReceiver extends BroadcastReceiver {
 2         
 3         @Override
 4         public void onReceive(Context context, Intent intent) {
 5             //通过getSystemService()方法得到connectionManager这个系统服务类,专门用于管理网络连接
 6             ConnectivityManager connectionManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
 7             NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
 8             if(networkInfo != null && networkInfo.isAvailable()){
 9                 Toast.makeText(context, "network is available",Toast.LENGTH_SHORT).show();
10             }else{
11                 Toast.makeText(context, "network is unavailable",Toast.LENGTH_SHORT).show();
12             }
13                 
14         }
15     }

下面代码解释:

06行:在onReceive()方法中,首先通过通过getSystemService()方法获得connectionManager那么些体系服务类,专门用于管理互联网连接。

07行:然后调用它的getActiveNetworkInfo()方法能够拿走NetworkInfo的实例,接着调用NetworkInfo的isAvailable()方法,就足以判定当前是不是有网络了,最终通过Toast提醒用户。

除此以外,查询系统的互连网状态是亟需表达权限的,打开清单文件,添加如下放权力限:

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

注:访问http://developer.android.com/reference/android/Manifest.permission.html能够查阅Android系统具备的可申明的权杖。

近日运作程序,就足以了。

上边程序完整版代码如下:

葡京娱乐注册 16葡京娱乐注册 17

 1 package com.example.m05_broadcastreceiver01;
 2 import android.app.Activity;
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 import android.content.IntentFilter;
 7 import android.net.ConnectivityManager;
 8 import android.net.NetworkInfo;
 9 import android.os.Bundle;
10 import android.widget.Toast;
11 public class MainActivity extends Activity {
12     private IntentFilter intentFilter;
13     private netWorkChangeReceiver netWorkChangeReceiver;
14     @Override
15     protected void onCreate(Bundle savedInstanceState) {
16         super.onCreate(savedInstanceState);
17         setContentView(R.layout.activity_main);
18         // 动态注册:创建一个IntentFilter的实例,添加网络变化的广播
19         intentFilter = new IntentFilter();
20         intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
21         // 创建NetWorkChangeReceiver的实例,并调用registerReceiver()方法进行注册
22         netWorkChangeReceiver = new netWorkChangeReceiver();
23         registerReceiver(netWorkChangeReceiver, intentFilter);
24     }
25     // 取消注册,一定要记得,不然系统会报错
26     @Override
27     protected void onDestroy() {
28         super.onDestroy();
29         unregisterReceiver(netWorkChangeReceiver);
30     }
31     class netWorkChangeReceiver extends BroadcastReceiver {
32         @Override
33         public void onReceive(Context context, Intent intent) {
34             //通过getSystemService()方法得到connectionManager这个系统服务类,专门用于管理网络连接
35             ConnectivityManager connectionManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
36             NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
37             if(networkInfo != null && networkInfo.isAvailable()){
38                 Toast.makeText(context, "network is available",Toast.LENGTH_SHORT).show();
39             }else{
40                 Toast.makeText(context, "network is unavailable",Toast.LENGTH_SHORT).show();
41             }
42                 
43         }
44     }
45 }

View Code 

 

二 、静态注册达成开机运维:

动态注册的法子比较灵敏,但缺点是:必须在程序运转现在才能收到到广播,因为注册的逻辑是写在onCreate()方法中的。为了让程序在未运维的意况下就能接收到广播,那里就须求动用到静态注册。

此处大家准备让程序接收一条开机广播,当接到那条广播时,就足以在onReceive()方法中推行相应的逻辑,从而实现开机运转的职能。

新建多个类:BootCompleteReceiver,让她接二连三布罗兹castReceiver,在onReceive()方法中总结地Toast一下,代码如下:

public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();
    }
}

能够看看,那里不再选取当中类的主意来定义广播接收器,因为稍后我们必要在清单文件AndroidManifest.xml元帅以此广播接收器的类名注册进去。

接下来修改清单文件AndroidManifest.xml,代码如下:

 1 <uses-sdk
 2         android:minSdkVersion="8"
 3         android:targetSdkVersion="16" />
 4     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 5     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
 6 
 7     <application
 8         android:allowBackup="true"
 9         android:icon="@drawable/ic_launcher"
10         android:label="@string/app_name"
11         android:theme="@style/AppTheme" >
12         <activity
13             android:name="com.example.m05_broadcastreceiver01.MainActivity"
14             android:label="@string/app_name" >
15             <intent-filter>
16                 <action android:name="android.intent.action.MAIN" />
17 
18                 <category android:name="android.intent.category.LAUNCHER" />
19             </intent-filter>
20         </activity>
21         
22         <receiver android:name=".BootCompleteReceiver">
23             <intent-filter >
24                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
25             </intent-filter>
26         </receiver>
27     </application>

代码解释如下:

毕竟,<application>标签内多了个子标签<receiver>,全数的静态注册的播报接收器都是在那边实行登记的。

22行:name中为广播接收器的名字

24行:想要接收的播放。Android系统运转完毕后,会生出那条名为android.intent.action.BOOT_COMPLETED的广播。

05行:监听系统开机广播须要表明权限。

运营程序后,将手提式有线电话机关机重启,就能收到那条广播了。

 

叁 、发送自定义广播

① 、发送正式广播  

新建筑工程程文件。在发广播此前,我们先定义一个广播接收器来选用此广播才行。由此,新建贰个类:My布罗兹castReceiver,让她继续BroadcastReceiver,代码如下:

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
    }
}

此处,当My布RhodescastReceiver
收到自定义的播音时,就会履行onReceive()方法中的逻辑,弹出3个Toast。

随之,要在清单文件AndroidManifest.xml中对这么些广播接收器进行挂号:

 1     <application
 2         android:allowBackup="true"
 3         android:icon="@drawable/ic_launcher"
 4         android:label="@string/app_name"
 5         android:theme="@style/AppTheme" >
 6         <activity
 7             android:name="com.example.m05_broadcastreceiver02.MainActivity"
 8             android:label="@string/app_name" >
 9             <intent-filter>
10                 <action android:name="android.intent.action.MAIN" />
11 
12                 <category android:name="android.intent.category.LAUNCHER" />
13             </intent-filter>
14         </activity>
15         
16         <receiver android:name=".MyBroadcastReceiver">
17             <intent-filter >
18                 <action android:name="com.example.m05_broadcastreceiver02.MY_BROADCAST"/>
19             </intent-filter>
20         </receiver>
21     </application>

代码解释:

18行:让MyBroadcastReceiver接收一条值为om.example.m05_broadcastreceiver02.MY_BROADCAST的播报,由此待会儿在出殡和埋葬广播的时候,我们就供给发出如此的一条广播。

继而,修改activity.xml中的代码,添加八个按钮Button。

下一场,修改MainActivity.java中的代码,添加Button的监听事件:点击按钮时,发送广播

 

        Button button1=(Button)findViewById(R.id.button1);
        button1.setOnClickListener(new OnClickListener() {            
            @Override
            public void onClick(View v) {
                Intent intent =new Intent("com.example.m05_broadcastreceiver02.MY_BROADCAST");
                sendBroadcast(intent);
            }
        });

小结:能够看看,点击按钮时,发送com.example.m05_broadcastreceiver02.MY_BROADCAST那条广播,那样,全体能够监听com.example.m05_broadcastreceiver02.MY_BROADCAST这条广播的播报接收器就都会同时吸收接纳音信,此时发出去的就是一条标准广播,即冬季广播。所以接下去就须求讲到有序广播。

 

二 、发送有序广播:

播音是一种可以跨进度的通讯格局,其余应用程序是足以接收的。现在大家来发一条有序广播。

不变广播不仅有先后顺序,而且后面包车型地铁广播仍可以够将后面包车型客车广播截断。

在3.1的代码基础之上,将按钮的监听事件修改如下:

1         Button button1=(Button)findViewById(R.id.button1);
2         button1.setOnClickListener(new OnClickListener() {            
3             @Override
4             public void onClick(View v) {
5                 Intent intent =new Intent("com.example.m05_broadcastreceiver02.MY_BROADCAST");
6                 sendOrderedBroadcast(intent, null);
7             }
8         });

即将06行代码修改一下,将send布罗兹cast()方法改为sendOrderedBroadcast()方法,sendOrderedBroadcast()方法接收七个参数,第①个参数是八个与权力相关的字符串,那里传出null即可。

随后,修改清单文件AndroidManifest.xml中对广播接收器的登记,设置优先级:

1         <receiver android:name=".MyBroadcastReceiver">
2             <intent-filter android:priority="100">
3                 <action android:name="com.example.m05_broadcastreceiver02.MY_BROADCAST"/>
4             </intent-filter>
5         </receiver>

即添加第02行代码。能够见到,通过android:priority属性给广播接收器设置了事先级。这些特性的范围在-1000到一千,数值越大,优先级越高。

接下去,假设想要拦截这些广播,幸免让前面包车型地铁播音接收器也吸收到了那一个广播。能够修改My布罗兹castReceiver中的代码:

1 public class MyBroadcastReceiver extends BroadcastReceiver {
2 
3     @Override
4     public void onReceive(Context context, Intent intent) {
5         Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
6         abortBroadcast();//拦截广播,防止后面的接收到
7     }
8 }

即添加第06行代码。假如在onReceive()方法中调用了abort布Rhodescast()方法,就表示是将那条广播拦截,前面包车型地铁播音接收器将不能再接过到。

尤其关怀:

  • 广播接收器的生命周期:关键在于布RhodescastReceiver中的onReceive()方法,从onReceive()里的首先行代码起头,onReceive()里的尾声一行代码截止。
  • 一个广播到来的时候,用如何方法提示用户是最温馨的呢?第3种艺术是吐司,第二种艺术是通报。注:不要使用对话框,以防中断了用户正在开展的操作。

 

④ 、使用当地广播:

以前大家发送和吸收的播放全体都以属于全局广播,即发出去的播报能够被其它任何应用程序接收到,并且大家也得以接受来自于任何任何应用程序的播音。这样一来,必然会促成安全题材。于是便有了本土广播:即只可以在本应用程序中发送和接受播放。那即将动用到了Local布罗兹castManager这几个类来对播音进行政管理理。

我们修改2.第11中学动态注册广播接收器的代码,即修改MainActivity.java中的代码如下:

package com.example.broadcasttest;

import android.app.Activity;
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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {
    private IntentFilter intentFilter;

    private LocalReceiver localReceiver;

    private LocalBroadcastManager localBroadcastManager;

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

        //通过LocalBroadcastManager的getInstance()方法得到它的一个实例
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(
                        "com.example.broadcasttest.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);//调用sendBroadcast()方法发送广播
            }
        });
        //动态注册本地的广播接收器
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    class LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "received local broadcast",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

注:本地广播是力不从心透过静态注册的章程来接受的。其实也截然能够领略,因为静态注册主要就是为了让程序在未运维的景观下也能接到广播。而发送本地广播时,大家的次第2定是早已起步了,没有须要运用到静态注册的功力。

 

五 、各样种种的播报: 

在android中有好多系统自带的intent.action,通过监听这么些事件大家得以做到很多效益。

  1. 开机:
    String BOOT_COMPLETED_ACTION
    广播:在系统运营后。那一个动作被广播三次(唯有3遍)。监听:
    “android.intent.action.BOOT_COMPLETED”
  2. 话机拨入:
    String ANSWER_ACTION 动作:处理拨入的对讲机。监听:
    “android.intent.action.ANSWE奥迪Q5”
  3. 电量变化:
    String BATTERY_CHANGED_ACTION
    广播:充电状态,也许电池的电量发生变化。监听:
    “android.intent.action.BATTE智跑Y_CHANGED”
  4. 日子变动:
    String DATE_CHANGED_ACTION 广播:日期被更改。
    监听:“android.intent.action.DATE_CHANGED”
  5. 注销更新下载:
    String FOTA_CANCEL_ACTION 广播:撤废全体被挂起的 (pending)
    更新下载。 监听:“android.server.checkin.FOTA_CANCEL”
  6. 履新开端设置:
    String FOTA_READY_ACTION 广播:更新已经被下载 能够起头安装。监听
    “android.server.checkin.FOTA_READY”
  7. 主屏幕:
    String HOME_CATEGO纳瓦拉Y 种类:主屏幕(activity)。设备运维后显得的率先个 activity。
    监听:”android.intent.category.HOME”
  8. 新应用:
    String PACKAGE_ADDED_ACTION
    广播:设备上新安装了一个使用程序包。监听:
    “android.intent.action.PACKAGE_ADDED”
  9. 去除应用:
    String PACKAGE_REMOVED_ACTION
    广播:设备上删除了多个运用程序包。监听:
    “android.intent.action.PACKAGE_REMOVED”
  10. 显示屏关闭:
    String SCREEN_OFF_ACTION 广播:显示屏被关门。监听:
    “android.intent.action.SCREEN_OFF”
  11. 显示屏开启:
    葡京娱乐注册,String SCREEN_ON_ACTION 广播:显示屏已经被打开。
    监听:“android.intent.action.SCREEN_ON”
  12. 时区改变:
    String TIMEZONE_CHANGED_ACTION 广播:时区已经变更。监听:
    “android.intent.action.TIMEZONE_CHANGED”
  13. 岁月转移:
    String TIME_CHANGED_ACTION 广播:时间已经转移(重新安装)。
    “android.intent.action.TIME_SET”
  14. 时光流逝:
    String TIME_TICK_ACTION 广播:当前时刻已经成形(寻常的时间流逝)。
    “android.intent.action.TIME_TICK”
  15. 进去大容积存储方式:
    String UMS_CONNECTED_ACTION 广播:设备进入 USB 大体量存款和储蓄形式。
    “android.intent.action.UMS_CONNECTED”
  16. 脱离大容积存款和储蓄形式:
    String UMS_DISCONNECTED_ACTION 广播:设备从 USB
    大体积存款和储蓄情势剥离。 “android.intent.action.UMS_DISCONNECTED”
  17. 壁纸改变:
    String WALLPAPER_CHANGED_ACTION 广播:系统的墙纸已经济体改成。
    “android.intent.action.WALLPAPE奥迪Q3_CHANGED”
  18. web搜索:
    String WEB_SEARCH_ACTION 动作:执行 web 搜索。
    “android.intent.action.WEB_SEARCH”
  19. 互联网生成:
    String CONNECTIVITY_CHANGE_ACTION
    动作:互连网转移。“android.intent.action.CONNECTIVITY_CHANGE_ACTION”

 

六、实例:利用动态注册,监听手提式有线电话机的电量变化。

一体化版代码如下:

(1)activity_main.xml代码如下:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:paddingBottom="@dimen/activity_vertical_margin"
 6     android:paddingLeft="@dimen/activity_horizontal_margin"
 7     android:paddingRight="@dimen/activity_horizontal_margin"
 8     android:paddingTop="@dimen/activity_vertical_margin"
 9     tools:context=".MainActivity" >
10 
11     <TextView
12         android:id="@+id/textView1"
13         android:layout_width="match_parent"
14         android:layout_height="wrap_content"
15         android:textSize="30dp"
16         android:gravity="center"/>
17 
18 </LinearLayout> 

(2)MainActivity.java的代码如下:

 1 package com.example.m05_broadcastreceiver02;
 2 
 3 import android.app.Activity;
 4 import android.content.BroadcastReceiver;
 5 import android.content.Context;
 6 import android.content.Intent;
 7 import android.content.IntentFilter;
 8 import android.os.Bundle;
 9 import android.widget.TextView;
10 
11 public class MainActivity extends Activity {
12 
13     
14     private BatteryBroadcastReceiver batteryBroadcastReceiver;
15     private TextView textView;
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.activity_main);
20         textView=(TextView)findViewById(R.id.textView1);
21         
22         //动态注册监听电量的广播接收器
23         IntentFilter intentFilter = new IntentFilter();
24         intentFilter.addAction("android.intent.action.BATTERY_CHANGED");
25         batteryBroadcastReceiver = new BatteryBroadcastReceiver();
26         registerReceiver(batteryBroadcastReceiver, intentFilter);       
27     }
28     
29     //取消注册监听电量的广播接收器
30     @Override
31     protected void onDestroy() {
32         super.onDestroy();
33         unregisterReceiver(batteryBroadcastReceiver);
34     }
35 
36     //新建一个广播接收器,监听电量的变化
37     public class BatteryBroadcastReceiver extends BroadcastReceiver {
38         @Override
39         public void onReceive(Context context, Intent intent) {
40             if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
41                 //获取当前电量
42                 int level = intent.getIntExtra("level", 0);
43                 //电量的总刻度
44                 int scale = intent.getIntExtra("scale", 100);
45                 textView.setText("电池电量为"+((level*100) / scale)+"%");
46                 
47                 //当电量低时,可以进行一些操作,例如弹出通知等
48 /*                if(level<15){
49                     do something
50                 }*/
51             }
52         }
53         
54     }
55     
56 }

继之,在清单文件中进行权力证明:

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

MainActivity.java的代码解释如下:

40至45行:固定代码,用于获取当前电量

48至50行:当电量低时,能够拓展部分操作,例如弹出布告等

运作后,界面如下:

葡京娱乐注册 18