繁体   English   中英

在onReceive()回调中的synchronized块

[英]synchronized block inside onReceive() callback

我正在阅读这个页面,关于如何编程Android与USB配件通信。 其中一个步骤涉及注册BroadcastReceiver以获取用户的许可:

IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);

其中mUsbReceiver定义为:

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if(accessory != null){
                        //call method to set up accessory communication
                    }
                }
                else {
                    Log.d(TAG, "permission denied for accessory " + accessory);
                }
            }
        }
    }
};

令我困惑的是为什么使用synchronized (this) 将在UI线程上调用onReceive() ,就是这样。 这段代码似乎没有触及其他线程可以访问的任何数据,除非对象accessory计数(并且页面上没有任何暗示它的内容)。

我在网上搜索过,似乎没有太多强调onReceive()线程安全性onReceive()毕竟它是由一个非常具体的线程调用的)。 我错过了什么吗?

更新:我想强调我知道synchronized (this)作用,因为下面的一些评论似乎暗示我没有。 我不明白为什么它被用在上面的代码片段中,这似乎是不必要的。

onReceive()不会总是在UI线程上调用。 如果使用registerReceiver()的重载来registerReceiver() BroadcastReceiver ,它接受Handler scheduler参数,则onReceive()将在一个线程上执行回调,该处理程序已附加到该线程。 来自docs

Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)

注册接收意图广播,在调度程序的上下文中运行。 scheduler是一个标识将接收Intent的线程的处理程序。 如果为null,则将使用该进程的主线程。

尽管如此,特别是在文档中概述的情况下,不需要将任何代码包装到synchronized块中,因为BroadcastReceiver是使用标准的registerReceiver(BroadcastReceiver, IntentFilter)重载registerReceiver(BroadcastReceiver, IntentFilter) ,这可以保证在UI线程上触发onReceive()回调。

我认为这只是一个展示代码,它演示了如何正确编写onReceive()实现,处理所有边缘情况。 如果该doc的作者没有编写synchronized块我就不知道了,可以使onReceive()在UI线程以外的线程上执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM