Broadcast使用分析

Broadcast(广播)是Android系统四大组件之一,Broadcast的主要作用是接收系统或者自定义的广播,并进行相关的处理工作。在广播中的操作时间不能太长,超过5s将被系统回收,造成ANR;如果需要在onReceive方法中做复杂的业务处理,最好的方法是开启一个线程来处理。

用法一:接收系统广播并进行相应的处理

接收广播的方式有两种:一是通过代码注册接收广播;二是通过xml配置的方式接收广播。

两种注册广播功能的区别:

代码注册的方式必须是该应用的进程已经启动,并且注册该广播的Activity或者Service等已经被实例化,才能接收该注册的广播;

xml配置注册广播则不需要以上的各种限制,只要系统发送了广播,就能接收到注册的广播。

在实际应用中,如果想要监听系统发出的广播,在接收到广播后做出相应的逻辑操作。如果选择代码方式注册广播,就会导致一系列问题,因为可能在系统发出广播的时候,该应用的进程并没有启动,导致应用接收不到广播,逻辑操作不能执行的问题。因此建议选择xml的方式注册广播。同时,如果大量使用XML注册广播,会降低系统性能,所以在选择广播注册方式时,应该根据具体业务需求,选择最适合的注册方式。

 

一、代码方式注册广播

(1)设置广播过滤器——需要接收的广播

//系统发出Intent.ACTION_MEDIA_MOUNTED的时候注册了scheme
//因此在注册监听广播的时候IntentFilter必须添加相应的Scheme才能接收相应的广播 
// 接收SDCard mount(安装)广播
IntentFilter mMountFilter= new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
//需要添加Scheme
mMountFilter.addDataScheme("file");

(2)声明广播接收器——注册广播信息

// 注册广播监听
registerReceiver(mReceiver, mMountFilter);

监听SDcard安装(Mounted)广播的具体代码如下(MainActivity.java):

package com.jony.broadcast;

import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {
    private IntentFilter mMountFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
    
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // do your logic
            System.out.println("SDcard is mounted");
            Toast.makeText(MainActivity.this, "SDcard have mounted", Toast.LENGTH_LONG).show();
        }
    };

    protected void onStart() {
        super.onStart();
        //系统发出Intent.ACTION_MEDIA_MOUNTED的时候注册了scheme
        //因此在注册监听广播的时候IntentFilter必须添加相应的Scheme才能接收相应的广播 
        mMountFilter.addDataScheme("file");
        registerReceiver(mReceiver, mMountFilter);//注册广播监听
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(mReceiver);// 取消广播监听
    }
}

Manifest.xml文件比较简单,在此不再给出源码

二、XML方式注册广播

 继承BroadcastReceiver类,实现onReceive方法——该方法中实现相应的业务逻辑即可

MyBroadcasrReceiver代码如下(MyBroadcasrReceiver.java)

package com.jony.broadcast.broadcast_sticky_test;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyBroadcasrReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        // do your logic
        System.out.println("BroadcasrReceiver is starting");
        Toast.makeText(context, "BroadcasrReceiver is starting", Toast.LENGTH_LONG).show();
    }

}

在XML中配置自定义BroadcastReceiver的action以及相应的data,在Mainfest中进行如下定义:

<receiver android:name=".MyBroadcasrReceiver" android:label="@string/receiver">
            <intent-filter>
                <action android:name="com.jony.normalbroadcast"/>
                <data android:scheme="file"/>
            </intent-filter>
            <intent-filter>
                <action android:name="com.jony.stickybroadcast"/>
            </intent-filter>
</receiver>

小节:以上两种接收广播的方式各有优点,具体选择哪种方式监听广播,需要更具业务需求,做出相应的选择。

用法二:接收自定义广播

首先通过继承BroadcastReceiver类,实现onReceive方法——该方法中实现相应的业务逻辑即可

MyBroadcasrReceiver代码如下(MyBroadcasrReceiver.java)

package com.jony.broadcast.broadcast_sticky_test;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyBroadcasrReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        // do your logic
        System.out.println("BroadcasrReceiver is starting");
        Toast.makeText(context, "BroadcasrReceiver is starting", Toast.LENGTH_LONG).show();
    }

}

在XML中配置自定义BroadcastReceiver的action以及相应的data,在Mainfest中进行如下定义:

<receiver android:name=".MyBroadcasrReceiver" android:label="@string/receiver">
            <intent-filter>
                <action android:name="com.jony.normalbroadcast"/>
                <data android:scheme="file"/>
            </intent-filter>
            <intent-filter>
                <action android:name="com.jony.stickybroadcast"/>
            </intent-filter>
</receiver>

实现BroadcasrReceiver的子类并在Mainfest中进行了以上配置之后,接下来就是见证奇迹的时候了,看看我们怎样启动我们自定义的Broadcast吧……

启动广播的步骤大致可以分为两步:

第一步注册我们自定义的广播;

第二部发送相应的Action——即我们在Mainfest中配置<receiver>时设置的相应action

代码如下所示(MainActivity.java):

package com.jony.broadcast.broadcast_sticky_test;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;

public class MainActivity extends Activity {
    private IntentFilter mFilter;
    private MyBroadcasrReceiver mReceiver = new MyBroadcasrReceiver();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mFilter = new IntentFilter();
        mFilter.addAction("com.jony.normalbroadcast");
        // 注册广播
         registerReceiver(mReceiver, mFilter);// 在XML中进行广播注册
        Intent intent = new Intent("com.jony.stickybroadcast");
        sendBroadcast(intent);// 发送广播
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);
    }
}
用法三:Normal Broadcast和Sticky Broadcast的区别用法

StickyBroadcast一般很少用到,但是千万不要忘记小人物也有大用处,所以请尊重身边的每一个人。闲话少说,直接切入正题,在使用代码注册广播(广播被嵌入到Activity中或者是Service中)时,当发送一个广播时,被嵌入的Activity或者Service还没有被启动时,发送的normal广播是接收不到的,这时只有发送sticky广播,在应用程序启动被嵌入广播的Activity或者Service时,会接收到stick广播,因此在这样的业务中stick广播就派上了用处。

举例说明:

在使用sticky广播时,需要在AndroidManifest.xml中赋予发送sticky广播的权限

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

首先在被嵌入的Activity中注册广播,具体代码如下(SecondActivity.java):

package com.jony.broadcast.broadcast_sticky_test;

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.widget.Toast;

public class SecondActivity extends Activity{
    private IntentFilter filter;
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, intent.getAction(), Toast.LENGTH_LONG).show();
        }
    };
    protected void onResume() {
        super.onResume();
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
        filter = new IntentFilter();
        filter.addAction("com.jony.normalbroadcast");
        filter.addAction("com.jony.stickybroadcast");
        registerReceiver(mReceiver, filter);
    }
    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);
    }
}

在MainActivity中发送广播,代码如下所示(MainActivity.java):

package com.jony.broadcast.broadcast_sticky_test;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
    private Button normal_button,sticky_button,launch_button;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init_data();
        }

    private void init_data() {
        normal_button = (Button) findViewById(R.id.send_normal_broadcast);
        sticky_button = (Button) findViewById(R.id.send_sticky_broadcast);
        launch_button = (Button) findViewById(R.id.receive_broadcast);

        normal_button.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.jony.normalbroadcast");
                sendBroadcast(intent);
            }
        });
        sticky_button.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction("com.jony.stickybroadcast");
                sendStickyBroadcast(intent);
            }
        });
        launch_button.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    protected void onPause() {
        super.onPause();
    }
}

布局文件和Manifest配置文件都比较简单,在此不再给出。
最后,见证奇迹的时刻就交给大家了……

 

 

 

 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值