码农进阶之旅Android开发经验谈Android开发

Android《第四章:Broadcast》

2017-09-25  本文已影响39人  泅渡者

Broadcast(广播)

Broadcast是一种广泛应用的、在应用之间传输信息的机制,Android中的广播与传统意义上的广播电台类似,一个广播可以有任意个接收者。广播机制是一个单行的发布——订阅模式,也就是现在常说的观察者模式。它的最大特点是发送方并不关心接收方是否收到数据,也不关心如何处理数据,通过这样的方式使得发送、接收达到完全解耦和。

普通广播

普通广播完全是异步的,通过Context的sendBroadcast()函数来发送。


/**
 * Created by 泅渡者
 * Created on 2017/9/26.
 */

public class CommonBroadcast extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String str = intent.getStringExtra("data");
        KLog.d(str);
    }
}

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent("com.bsoft.broadcasttest.CLOCK");
        intent.putExtra("data", "Ding Ding 起床了!!!!");
        sendBroadcast(intent);
    }
}

注册

        <receiver android:name=".CommonBroadcast">
            <intent-filter>
                <action android:name="com.bsoft.broadcasttest.CLOCK"/>
            </intent-filter>
        </receiver>

运行结果如下

D/CommonBroadcast.java: [ (CommonBroadcast.java:19)#onReceive ] Ding Ding 起床了!!!!

有序广播

/**
 * Created by 泅渡者
 * Created on 2017/9/26.
 */

public class OrderOBroadcast1 extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle=getResultExtras(true);
        KLog.d("我收到消息"+bundle.get("data")+"&&"+bundle.get("warning"));

    }
}

OrderOBroadcast2.class


/**
 * Created by 泅渡者
 * Created on 2017/9/26.
 */

public class OrderOBroadcast2 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        Bundle bundle=intent.getExtras();
        KLog.d("我收到消息"+bundle.get("data"));
        bundle.putString("warning", "姐姐快起床");
        setResultExtras(bundle);
        //切断广播
//      abortBroadcast();
    }
}

注册

 <!--有序广播 优先级范围(-1000~1000)-->
        <receiver android:name=".OrderOBroadcast1">
            <intent-filter android:priority="100">
                <action android:name="com.bsoft.broadcasttest.ACTION"/>
            </intent-filter>
        </receiver>
        <receiver android:name=".OrderOBroadcast2">
            <intent-filter android:priority="200">
                <action android:name="com.bsoft.broadcasttest.ACTION"/>
            </intent-filter>
        </receiver>

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    TextView tv_one;
    TextView tv_two;
    Intent intent;

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

        tv_one = (TextView) findViewById(R.id.tv_one);
        tv_two = (TextView) findViewById(R.id.tv_two);
        tv_one.setOnClickListener(this);
        tv_two.setOnClickListener(this);


    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_one:
                intent = new Intent("com.bsoft.broadcasttest.CLOCK");
                intent.putExtra("data", "Ding Ding 起床了!!!!");
                sendBroadcast(intent);
                break;
            case R.id.tv_two:
                intent = new Intent("com.bsoft.broadcasttest.ACTION");
                Bundle bundle=new Bundle();
                bundle.putString("data", "孩子们快起床");
                intent.putExtras(bundle);
                //有序广播
                sendOrderedBroadcast(intent, null);
                break;
        }
    }
}

代码简单相信都能看得懂,我们直接看运行结果:

/CommonBroadcast.java: [ (CommonBroadcast.java:19)#onReceive ] Ding Ding 起床了!!!!
D/OrderOBroadcast2.java: [ (OrderOBroadcast2.java:20)#onReceive ] 我收到消息孩子们快起床
D/OrderOBroadcast1.java: [ (OrderOBroadcast1.java:19)#onReceive ] 我收到消息孩子们快起床&&姐姐快起床

在这里我们看到事OrderOBroadcast2最先接收到广播的,这就是我们在注册时进行的设置。接着再来看看OrderOBroadcast1打印了两条数据,第一条是广播发出的消息,而第二条是OrderOBroadcast2发送来的。

本地广播

只在程序内部进行传递的广播,发送和接收都只在本程序有效。
本地广播是无法通过静态注册来实现的。因为静态注册是为了让程序未启动也能接收广播。本地广播是在本程序内进行传递,肯定是已经启动了,因此也完全不需要静态注册。
代码如下:


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    TextView tv_one;
    TextView tv_two;
    TextView tv_three;
    Intent intent;

    //本地广播
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;

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

        tv_one = (TextView) findViewById(R.id.tv_one);
        tv_two = (TextView) findViewById(R.id.tv_two);
        tv_three = (TextView) findViewById(R.id.tv_three);
        tv_one.setOnClickListener(this);
        tv_two.setOnClickListener(this);
        tv_three.setOnClickListener(this);

        localBroadcastManager=LocalBroadcastManager.getInstance(this);
        //新建intentFilter并给其action标签赋值。
        intentFilter=new IntentFilter();
        intentFilter.addAction("com.bsoft.broadcasttest.LOCAL_BROADCAST");

        //创建广播接收器实例,并注册。将其接收器与action标签进行绑定。
        localReceiver=new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tv_one:
                intent = new Intent("com.bsoft.broadcasttest.CLOCK");
                intent.putExtra("data", "Ding Ding 起床了!!!!");
                sendBroadcast(intent);
                break;
            case R.id.tv_two:
                intent = new Intent("com.bsoft.broadcasttest.ACTION");
                Bundle bundle=new Bundle();
                bundle.putString("data", "孩子们快起床");
                intent.putExtras(bundle);
                //有序广播
                sendOrderedBroadcast(intent, null);
                break;
            case R.id.tv_three:
                intent=new Intent("com.bsoft.broadcasttest.LOCAL_BROADCAST");
                //发送本地广播。
                localBroadcastManager.sendBroadcast(intent);
                break;
        }
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        //取消注册调用的是unregisterReceiver()方法,并传入接收器实例。
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    class  LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent){
            Toast.makeText(context,"这是本地广播接收器",Toast.LENGTH_SHORT).show();
        }
    }
}

至此本地广播已经可以应用了。

Sticky广播

sticky广播通过Context.sendStickyBroadcast()函数来发送,用此函数发送的广播会一直滞留,当有匹配此广播的广播接收器被注册后,该广播接收器就会收到此条信息。使用此函数需要发送广播时,需要获得BROADCAST_STICKY权限

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

sendStickyBroadcast只保留最后一条广播,并且一直保留下去,这样即使已经有广播接收器处理了该广播,当再有匹配的广播接收器被注册时,此广播仍会被接收。如果你只想处理一遍该广播,可以通过removeStickyBroadcast()函数来实现。这里创建广播的过程和普通广播是一样的过程,这里就不过多介绍了
主要原因是在 android 5.0/api 21中deprecated,不再推荐使用,相应的还有粘性有序广播,同样已经deprecated

两种注册广播方式

<!--广播注册、name里面填写广播类的路径-->
<receiver android:name=".SmsBroadCastReceiver">
     <intent-filter android:priority="20">
          <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
     </intent-filter>
</receiver>
//定义广播
class SmsReceiver extends BroadcastReceiver{

  @Override
  public void onReceive(Context context, Intent intent) {
  //doSomething
  }
}

//注册广播
private SmsReceiver smsReceiver;
smsReceiver=new SmsReceiver();
IntentFilter intentFilter=new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsReceiver,intentFilter);

//发送广播
Intent intent=new Intent();
intent.setAction("android.provider.Telephony.SMS_RECEIVED");
sendBroadcast(intent);

以上就是对于广播的理解和应用了。

上一篇下一篇

猜你喜欢

热点阅读