使用广播接收器

时间:2017-07-28 12:20:31

标签: java android

我试图通过广播接收器将一个实现“Serializable”的Object从一个应用程序发送到另一个应用程序。

我想发送一个类:

public class MyObject implements Serializable{
    //basic properties
}

在申请表A中,我这样做:

Intent i = new Intent("myApplication.string");
Bundle b = new Bundle();
b.putSerializable("myclass",obj);
i.putExtras(b);
sendBroadcast(i);

当我调试这个时,我可以验证对象是否正确存储在意图包中。

在申请B中,我这样做:

清单

 <receiver
        android:name="com.example.myapplication.myreceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="myApplication.string"/>
        </intent-filter>
    </receiver>

广播接收器

@Override
public void onReceive(Context context, Intent intent) {
    try{
        Bundle b = intent.getExtras();
        MyObject s = (MyObject)b.getSerializable("myclass");
    }catch (Exception e){
        Log.d(TAG,e.getMessage());
    }
}

在应用程序B中,intent不保存它在应用程序A中所做的数据。

当我尝试投射数据时,它会抛出:

Parcelable encountered ClassNotFoundException reading a Serializable object (name = com.example.myApplication.MyObject)

我已经在两个应用程序中复制了类实现,因此它们匹配。

enter image description here

在应用程序A中,所有数据都在Intent.extras的mMap属性中 - 但在应用程序B中它是空的。

任何人都可以帮我理解这个吗?

感谢。

2 个答案:

答案 0 :(得分:4)

  

我试图通过广播接收器将一个实现“Serializable”的Object从一个应用程序发送到另一个应用程序。

这不是一个好主意。它要求两个应用程序对该Java类具有相同的类定义,或者至少需要一个兼容的类。由于应用程序可能无法同时更新,因此您可以遇到发件人拥有Java类的新版本而不是收件人的情况,这可能会导致反序列化异常。

  

在申请表A中,我这样做:

这不是一个好主意。您没有将数据发送到其他应用程序。您正在将数据发送到任何关注此广播的应用,包括可能想要监视您的输出的任何应用。

  

在申请B中,我这样做:

这不是一个好主意。任何应用都可以向此应用发送广播,要么欺骗消息,要么尝试导致应用崩溃。在Android 8.0+上,无论如何都不会收到广播。

  

我已经在两个应用程序中复制了类实现,因此它们匹配。

也许您的工作方式存在问题,因为错误消息似乎不同意您的评估。

我首先要摆脱Serializable。只有将内容放入可以保证所有访问这些附加内容的各方正确识别的附加内容中。因此,使用简单的原语,Bundle或其他框架类,而不是自定义SerializableParcelable实现。然后,看看你的更多普通演员是否正在从应用程序到应用程序。

然后,更好地进行进程间通信:

  • 使用显式Intent(一个ComponentName),而不是隐式Intent(一个带有操作字符串),以便“广播”仅介于双方并围绕Android 8.0+隐式广播限制进行工作

  • 执行权限(例如android:permission上的<receiver>)或执行签名检查以确保双方都是您认为的人

答案 1 :(得分:0)

MyObject应该实现Parcelable,而不是Serializable ......