Java Android BluetoothGattService-无法处理异常

Java Android BluetoothGattService-无法处理异常,java,android,android-intent,parcelable,Java,Android,Android Intent,Parcelable,我有以下问题 我的应用程序架构大致由3个主要部分组成: 设备视图(显示可用的可扩展设备) BLE服务(处理BLE连接和数据) 服务视图(显示特定设备的服务) 我的问题是第二次(第一次)将BluetoothGATTService传递给intent 或多或少的行动是这样的: 选择要显示其服务的设备 向BLEService发送包含要执行的设备和操作的意图 BLEService执行服务发现并将意图与服务一起发送回 BroadcastReceiver正确地接收到意图,并等待使用接收到的意图中的数据启

我有以下问题

我的应用程序架构大致由3个主要部分组成:

  • 设备视图(显示可用的可扩展设备)
  • BLE服务(处理BLE连接和数据)
  • 服务视图(显示特定设备的服务)
我的问题是第二次(第一次)将BluetoothGATTService传递给intent

或多或少的行动是这样的:

  • 选择要显示其服务的设备
  • 向BLEService发送包含要执行的设备和操作的意图
  • BLEService执行服务发现并将意图与服务一起发送回
  • BroadcastReceiver正确地接收到意图,并等待使用接收到的意图中的数据启动新活动
最后一步出现了一个问题,因为我无法将ArrayList放入intent/bundle,因为它会导致异常:

E/AndroidRuntime:致命异常:主 流程:com.projects.dawid.gattclient,PID:4133 java.lang.RuntimeException:包裹:无法封送值android.bluetooth。BluetoothGattService@ef62956 位于android.os.Parcel.writeValue(Parcel.java:1337) 位于android.os.Parcel.writeList(Parcel.java:711) 位于android.os.Parcel.writeValue(Parcel.java:1284) 位于android.os.Parcel.writeArrayMapInternal(Parcel.java:638) 位于android.os.BaseBundle.WriteToParceliner(BaseBundle.java:1313) 位于android.os.Bundle.writeToParcel(Bundle.java:1096) 位于android.os.Parcel.writeBundle(Parcel.java:663) 位于android.content.Intent.writeToParcel(Intent.java:7838) 在android.app.ActivityManagerProxy.startActivity上(ActivityManagerNative.java:2530)

对我来说,这非常奇怪,因为如果操作不受支持,那么我们将在从BLEService向BroadcastReceiver发送ArrayList服务时出现此异常,而不是现在

源代码:

BLEService到广播接收机代码
private void notifyServicesDiscovered(蓝牙gatt){
意图=新意图();
intent.setAction(BLEService.RESPONSE);
intent.putExtra(BLEService.RESPONSE,BLEService.Responses.SERVICES\u发现);
intent.putExtra(BLEService.Responses.DEVICE,gatt.getDevice());
intent.putParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST,getArrayListServices(gatt));
LocalBroadcastManager.getInstance(mServiceContext).sendBroadcast(intent);
}
@非空
私有ArrayList GetArrayList服务(蓝牙gatt){
ArrayList服务=新建ArrayList();
services.addAll(gatt.getServices());
返回服务;
}
这个很好用。现在

广播接收器至新活动代码 识别出处理此方法的正确意图后,将调用此方法

private void createViewWithServices(Intent intent) {
    Log.i(TAG, "creating new activity!");

    BluetoothDevice device = intent.getParcelableExtra(BLEService.Responses.DEVICE);
    ArrayList<BluetoothGattService> services =  intent.getParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST);

    Intent serviceShowIntent = new Intent(mActivityContext, ServiceShowActivity.class);
    serviceShowIntent.putExtra(BLEService.Responses.DEVICE, device);
    serviceShowIntent.putParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST, services); //this line causes error
    mActivityContext.startActivity(serviceShowIntent); // here exception is thrown
}
private void createViewWithServices(意图){
Log.i(标记“创建新活动!”);
BluetoothDevice=intent.getParcelableExtra(BLEService.Responses.device);
ArrayList services=intent.getParcelableArrayListExtra(BLEService.Responses.services\u LIST);
意向serviceShowIntent=新意向(mActivityContext,ServiceShowActivity.class);
serviceShowIntent.putExtra(BLEService.Responses.DEVICE,DEVICE);
serviceShowIntent.putParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST,SERVICES);//此行导致错误
mActivityContext.startActivity(serviceShowIntent);//此处引发异常
}
谁能解释一下这背后的迷雾?我就是不明白为什么第一个代码很好,而第二个代码异常失败

已经尝试过很多不同的方法,但都失败了。我甚至在意图之间交换捆绑包,因为它们的内容是相同的,但这也失败了,复制列表项没有任何区别

编辑


参考错误。区别在于,我使用的是android本身提供的类的对象,即BluetoothGATTService,它确实实现了parcelable接口,参考

,这里有两个问题:一个是使用本地广播时,会导致一切正常工作,另一个使
BluetoothGattService
的序列化失败


为了在两个进程之间传递数据,必须对数据进行序列化(写入
)。Bundle内容被延迟序列化/反序列化-只要
Bundle
对象不跨越进程边界或存储在磁盘上,所有包含的对象都将存储在内存中(在HashMap中),并且不会被序列化

本地广播从不跨越进程边界,因此不会序列化/反序列化意图附加。进程间通信(全局广播,要求ActivityManager启动活动)执行

为了在进程之间传递,Intent extras必须是可打包的或可序列化的,否则Android可能会在某些情况下将其视为不透明对象,并在运行时尝试确定其序列化方法(如可序列化/可打包/字符串等)(请参阅)-并失败


至于BluetoothGattService——在首次公开发布后,它显然没有实现Parcelable,而是在API 24中实现Parcelable。这意味着,在野外有一些设备,该类没有实现Parcelable(即使它在最新Android版本的源代码中实现)。就二进制兼容性而言,向继承链添加父类在技术上并不是一个突破性的改变——Java类加载器不会抱怨。但任何依赖于此类类的可封装性的代码,要么在字节码验证期间失败,要么在旧版本上导致ClassCastException/ArrayStoreException

Java泛型在编译为
private void createViewWithServices(Intent intent) {
    Log.i(TAG, "creating new activity!");

    BluetoothDevice device = intent.getParcelableExtra(BLEService.Responses.DEVICE);
    ArrayList<BluetoothGattService> services =  intent.getParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST);

    Intent serviceShowIntent = new Intent(mActivityContext, ServiceShowActivity.class);
    serviceShowIntent.putExtra(BLEService.Responses.DEVICE, device);
    serviceShowIntent.putParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST, services); //this line causes error
    mActivityContext.startActivity(serviceShowIntent); // here exception is thrown
}