Android组件化架构 - 2. 组件间通信机制(1)

498 阅读2分钟

本地广播LocalBroadcastManager

说到组件间通信第一个肯定想到广播BroadcastReceiver,但是这里要说的是一个更优的选择---本地广播LocalBroadcastManager;

  • 优点:只在app内传播, 信息不会泄露,也不会被别人的广播干扰, 且比全局广播更高效;

  • 缺点:但是本地广播传输消息时将一切都交给系统负责,无法干预传输中的步骤;

  • 使用观察者模式

使用demo:

class LocalBroadcastActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_local_broadcast)
        testLocalBroadcast()
    }

    private lateinit var broadcastReceiver: BroadcastReceiver
    private lateinit var lbm: LocalBroadcastManager
    private val localAction = "com.ljy.publicdemo.localAction"
    private fun testLocalBroadcast() {
        broadcastReceiver = object : BroadcastReceiver() {
            /**
             * 接收并出列广播
             */
            override fun onReceive(context: Context?, intent: Intent?) {
                if (localAction == intent!!.action) {
                    val value = intent.getStringExtra("key_001")
                    LogUtils.d("key_001=$value, do something... ")
                }
            }
        }
        //创建
        lbm = LocalBroadcastManager.getInstance(this)
        //注册
        lbm.registerReceiver(broadcastReceiver, IntentFilter(localAction))
    }

    private fun sendBroadcast() {
        //发送
        val intent = Intent(localAction)
        intent.putExtra("key_001", "value_001")
        lbm.sendBroadcast(intent)
    }
    
    fun onBtnClick(view: View) {
        when (view.id) {
            R.id.button_send_broadcast -> sendBroadcast()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        //解绑
        lbm.unregisterReceiver(broadcastReceiver)
    }
}

本质:看一下LocalBroadcastManager源码

//构造方法如下,其本质还是用handler通信
private LocalBroadcastManager(Context context) {
    mAppContext = context;
    mHandler = new Handler(context.getMainLooper()) {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_EXEC_PENDING_BROADCASTS:
                    executePendingBroadcasts();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    };
}

//内部类ReceiverRecord:将receiver和intentFilter封装成ReceiverRecord对象,
private static final class ReceiverRecord {
        final IntentFilter filter;
        final BroadcastReceiver receiver;
        boolean broadcasting;
        boolean dead;

        ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) {
            filter = _filter;
            receiver = _receiver;
        }
}

//内部类BroadcastRecord:将ReceiverRecord对象封装在BroadcastRecord对象中
private static final class BroadcastRecord {
    final Intent intent;
    final ArrayList<ReceiverRecord> receivers;

    BroadcastRecord(Intent _intent, ArrayList<ReceiverRecord> _receivers) {
        intent = _intent;
        receivers = _receivers;
    }
}

//有三个集合
//一个以receiver为key、以ReceiverRecord列表为value的map
private final HashMap<BroadcastReceiver, ArrayList<ReceiverRecord>> mReceivers= new HashMap<>();
//一个以action为key,以ReceiverRecord列表为value的map
private final HashMap<String, ArrayList<ReceiverRecord>> mActions = new HashMap<>();
//BroadcastRecord对象的集合
private final ArrayList<BroadcastRecord> mPendingBroadcasts = new ArrayList<>();

//注册和解绑的源码就不贴了
//registerReceiver()就是装填mReceivers,mActions这两个map
//unregisterReceiver()就是清除mReceivers,mActions

//发送广播源码
public boolean sendBroadcast(@NonNull Intent intent) {
    synchronized (mReceivers) {
        //。。。省略部分源码,主要就是对intent中的信息进行校验
        //最关键的是下面的装填mPendingBroadcasts,和发送handler消息
            if (receivers != null) {
                for (int i=0; i<receivers.size(); i++) {
                    receivers.get(i).broadcasting = false;
                }
                mPendingBroadcasts.add(new BroadcastRecord(intent, receivers));
                if (!mHandler.hasMessages(MSG_EXEC_PENDING_BROADCASTS)) {
                    mHandler.sendEmptyMessage(MSG_EXEC_PENDING_BROADCASTS);
                }
                return true;
            }
        }
    }
    return false;
}

//还有一个同步发送广播的方法
 public void sendBroadcastSync(@NonNull Intent intent) {
    if (sendBroadcast(intent)) {
        executePendingBroadcasts();
    }
}

//上面源码看出一个至关重要的方法executePendingBroadcasts,才是真正调用广播处理的回调
 void executePendingBroadcasts() {
    while (true) {
        final BroadcastRecord[] brs;
        synchronized (mReceivers) {
            final int N = mPendingBroadcasts.size();
            if (N <= 0) {
                return;
            }
            brs = new BroadcastRecord[N];
            mPendingBroadcasts.toArray(brs);
            mPendingBroadcasts.clear();
        }
        for (int i=0; i<brs.length; i++) {
            final BroadcastRecord br = brs[i];
            final int nbr = br.receivers.size();
            for (int j=0; j<nbr; j++) {
                final ReceiverRecord rec = br.receivers.get(j);
                if (!rec.dead) {
                    rec.receiver.onReceive(mAppContext, br.intent);
                }
            }
        }
    }
}
我是今阳,如果想要进阶和了解更多的干货,欢迎关注公众号”今阳说“接收我的最新文章