Broadcast

作者: 瑟闻风倾 | 来源:发表于2019-11-05 17:56 被阅读0次

1. Broadcast定义、应用场景及种类

(1) 定义: 广播是一种应用程序间传输信息的机制(类似于Java中的观察者模式)。广播内容是一个intent,携带需要传输的数据。
观察者模式:被观察者发生变化时,通知观察者做相应的数据处理。
(2) 应用场景:

  • 实现不同应用程序间的数据传输和共享(不同app的组件间的消息通信)
    注意:和发送广播的activity具有相同action接收者都可以接受该广播。
  • 通知作用( 同一app的不同进程的组件间的消息通信):service通过broadcast向activity发送消息来更新UI

(3) 种类

  • 普通广播
  • 有序广播(属于系统广播)
  • 本地广播:只在app内传播

2. 实现广播(BroadcastReceiver)的两种方式

(1) 静态注册:在manifest.xml中注册广播接收者BroadcastReceiver。广播不会随它所依赖的activity的销毁而销毁,进程杀死也仍能接收广播。
(2) 动态注册:在代码中使用registReveiver()来注册BroadcastReceiver。广播的销毁会跟随activity的生命周期。、
注意:需在activity的onDistory()方法中调用unregistReveiver()来销毁广播接收者,否则容易引起内存泄漏。

3. 广播内部实现原理(实质是Binder机制)

广播内部实现原理.png

(1) 广播接收方注册BroadcastReceiver并重写onReceive()方法
(2) 广播接收方通过Binder机制向AMS(Activity Manage Service)进行注册
(3) 广播发送方通过Binder机制向AMS发送广播
(4) AMS查找符合条件(IntentFilter的action标识不同广播)的BroadcastReceiver,并将广播发送到BroadcastReceiver对应的消息队列中
(5) BroadcastReceiver在消息队列中获取此广播,并回调BroadcastReceiver的onReceive()方法,根据action来标识不同的广播并进行处理

本地广播egservice通过broadcastactivity发送消息来更新UI;activity也可通过broadcast调用service中的方法
(1) BroadcastTestActivity.java(作为接收方)

package comi.example.liy.mytestdemo;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;


/**
 * Created by liy on 2019-11-05 16:27
 */
public class BroadcastTestActivity extends FragmentActivity {

    /*********************服务****************************/
    private NotificationService notificationService;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            notificationService = ((NotificationService.MyBinder) service).getService();// 服务已连接
            System.out.println("Service连接成功");
            //执行服务内部的方法
            myService.excute();
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            notificationService = null;// 未连接为空
        }
    };

    /*********************本地广播****************************/
    private MessageReciver mReciver;
    private IntentFilter mIntentFilter;
    private LocalBroadcastManager mLocalBroadcastManager;//本地广播管理器
    // 自定义广播接收者并重写onReceive()方法
    class MessageReciver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
           if (action.equals(NotificationService.MESSAGE_ACTION)) {
                String message = intent.getStringExtra("content");
                Log.v("通知内容", message);
            } else {
                Log.v("notification_else", "未知的广播消息");
            }
        }
    }


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

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

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

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

        unbindService(conn);// 注销服务
        mLocalBroadcastManager.unregisterReceiver(mReciver);// 注销广播:最好在onPause()中注销
    }

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

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

    private void initData() {
        Intent serviceIntent = new Intent(this, NotificationService.class);
        bindService(serviceIntent, conn, BIND_AUTO_CREATE);//绑定服务

        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);//获取本地广播管理器实例
        mReciver = new MessageReciver();//获取广播接收者
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(NotificationService.MESSAGE_ACTION);//添加广播标识
        mLocalBroadcastManager.registerReceiver(mReciver, mIntentFilter);//注册本地广播接收器

    }

}

(2) NotificationService.java(作为发送方)

package comi.example.liy.mytestdemo;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;

/**
 * Created by liy on 2019-11-05 16:36
 * Activity调用bindService (Intent service, ServiceConnection conn, int flags)方法,得到Service对象的一个引用,这样Activity可以直接调用到Service中的方法,如果要主动通知Activity,我们可以利用回调方法
 *   Service向Activity发送消息,可以使用广播,当然Activity要注册相应的接收器。比如Service要向多个Activity发送同样的消息的话,用这种方法就更好。
 *   Activity中创建广播接收器:Activity中新建内部类继承BroadcastReceiver并重写onReceive()方法,当有广播到来时onReceive()方法就会得到执行。
 */
public class NotificationService extends Service {
    private final IBinder binder = new MyBinder();

    /**消息通知标识**/
    public static final String MESSAGE_ACTION="message_ACTION";
    /**本地广播**/
    private LocalBroadcastManager mLocalBroadcastManager;

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        new NotificationThread().start();//service每隔一段时间发送一条消息,通过broadcast发送给activity来更新UI
        mLocalBroadcastManager=LocalBroadcastManager.getInstance(this);
    }

    class NotificationThread extends Thread {
        @Override
        public void run() {
            super.run();
            while (true){
                try{
                    sleep(5000);
                }catch (Exception e){
                    e.printStackTrace();
                }
                Intent intent=new Intent(MESSAGE_ACTION);
                intent.putExtra("content","新的通知");
                mLocalBroadcastManager.sendBroadcast(intent);
            }

        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public class MyBinder extends Binder {
        NotificationService getService() {
            return NotificationService.this;//获取MyService的引用,从而可以引用其内部的方法和变量
        }
    }

    public void excute() {
        System.out.println("通过Binder得到Service的引用来调用Service内部的方法");
    }

}

(3)注意:别忘记在manifest.xml中注册Activity和Broadcast

<activity android:name=".BroadcastTestActivity"/>
 <service android:name=".NotificationService"/>

(4) 拓展:若要发送多个广播,添加对应代码即可,如

发送方-定义广播标识.png
发送方-发送广播.png
接收方-添加标识.png
接收方-接收.png

相关文章

网友评论

    本文标题:Broadcast

    本文链接:https://www.haomeiwen.com/subject/meosbctx.html