android – 如何在intent中广播一个parcelable对象?

android – 如何在intent中广播一个parcelable对象?,第1张

概述我是 Java / Android的新手,并尝试开发一个与USB CAN总线适配器通信的adroid应用程序.我通过我的CANBusController类从字符串接收来自适配器的消息,并且我已经构建了一个parcelable类,CANMessage,它将接收的字符串转换为我可以使用的形式(int Id,int Length,byte [] data).现在我正在尝试显示我收到的消息.我有一个片段, 我是 Java / Android的新手,并尝试开发一个与USB CAN总线适配器通信的adroID应用程序.我通过我的CANBusController类从字符串接收来自适配器的消息,并且我已经构建了一个parcelable类,CANMessage,它将接收的字符串转换为我可以使用的形式(int ID,int Length,byte [] data).现在我正在尝试显示我收到的消息.我有一个片段,CANBusControlFragment,它声明了一个broadcastReceiver.当收到消息时,我构建我的CANMessage,将它和它的字符串放入一个包中,将包放入一个Intent,然后使用sendbroadcast(intent):

CANBusController{    public voID handleMessage(Message msg)    {        Bundle bundle = msg.getData();        CANMessage canMsg = bundle.getParcelable("CAN_MESSAGE");        if (canMsg != null)        {            Intent intent = new Intent();            intent.setAction(broadcastActions.CAN_MESSAGE_RECEIVED);            //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            intent.putExtra("CAN_MESSAGE",canMsg);            intent.putExtra("STRING_MESSAGE",canMsg.toString());            parentContext.sendbroadcast(intent);        }    }}CANBusControlFragment extends Fragment{    private final broadcastReceiver canMsgReceiver = new broadcastReceiver()    {        @OverrIDe        public voID onReceive(Context context,Intent intent)        {            String action = intent.getAction();            Bundle bundle = intent.getExtras();            try            {                if (broadcastActions.CAN_MESSAGE_RECEIVED.equals(action))                {                    synchronized(this)                    {                        String str = bundle.getString("STRING_MESSAGE"); // <-- Crash                        CANMessage canMsg = bundle.getParcelable("CAN_MESSAGE"); //                         Append(str);                        Append(canMsg.toString();                    }                }            }            catch (Exception ex)                print exception        }    }}

如果我将CANMessage添加到bundle中,当我尝试使用getString或getParcelable时,我的应用程序将在broadcastReceiver的onReceived方法中崩溃并出现Null Pointer Exception.如果我不包含CANMessage,那么应用程序将正常工作.我相信CANMessage正确地实现了Parcelable,因为我通过执行所有相同的步骤来测试它,除了广播消息:在Bundle中构建CANMessage,putParcelable,在Bundnt中放入Bundle,从Intent中获取Bundle,从中获取getParcelable束.

我感谢任何帮助.谢谢 :)

编辑 – LogCat信息:
看来错误出现在我的宗地方法中.试图readByteArray(byte [])崩溃应用程序.

11-12 09:17:44.568: E/AndroIDRuntime(3087): FATAL EXCEPTION: main11-12 09:17:44.568: E/AndroIDRuntime(3087): java.lang.RuntimeException: Error receiving broadcast Intent { act=com.sb2tablet.CAN_MESSAGE_RECEIVED flg=0x10000010 (has extras) } in com.sb2tablet.CANBusControlFragment@9e8f6e0011-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.app.LoadedApk$Receiverdispatcher$Args.run(LoadedApk.java:768)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Handler.handleCallback(Handler.java:725)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Handler.dispatchMessage(Handler.java:92)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Looper.loop(Looper.java:137)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.app.ActivityThread.main(ActivityThread.java:5041)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at java.lang.reflect.Method.invokeNative(Native Method)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at java.lang.reflect.Method.invoke(Method.java:511)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at com.androID.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at com.androID.internal.os.ZygoteInit.main(ZygoteInit.java:560)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at dalvik.system.NativeStart.main(Native Method)11-12 09:17:44.568: E/AndroIDRuntime(3087): Caused by: java.lang.NullPointerException11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Parcel.readByteArray(Parcel.java:1594)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at com.sb2tablet.models.CANMessage.<init>(CANMessage.java:93)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at com.sb2tablet.models.CANMessage.createFromParcel(CANMessage.java:18)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at com.sb2tablet.models.CANMessage.createFromParcel(CANMessage.java:1)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Parcel.readParcelable(Parcel.java:2103)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Parcel.readValue(Parcel.java:1965)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Parcel.readMAPInternal(Parcel.java:2226)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Bundle.unparcel(Bundle.java:223)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.os.Bundle.containsKey(Bundle.java:271)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.content.Intent.hasExtra(Intent.java:4121)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at com.sb2tablet.CANBusControlFragment.onReceive(CANBusControlFragment.java:51)11-12 09:17:44.568: E/AndroIDRuntime(3087):     at androID.app.LoadedApk$Receiverdispatcher$Args.run(LoadedApk.java:758)

编辑 – writetoParcel和Parcel in:

public voID writetoParcel(Parcel out,int flags){    out.writeValue(ID);    // int    out.writeValue(len);   // int    out.writevalue(data);  // byteArray,the value is not null here    //out.writeByArray(data);}public CANMessage(Parcel in){    ID = in.readInt();    len = in.readInt();    in.readByteArray(data); // Actual crash is here}

编辑 – 测试案例1 – 似乎额外的数据被添加到我的包裹,我不知道如何.

public voID writetoParcel(Parcel out,int flags){    out.writeValue(ID);    // int = 256    out.writeValue(len);   // int = 2,length of byte array    out.writevalue(data);  // byte array = { 17,51 }}public CANMessage(Parcel in){    len = in.readInt();        // 1    ID = in.readInt();         // 256    len = in.readInt();        // 1    len = in.readInt();        // 2    int i = in.readInt();      // 13    if (data == null) data = new byte[len];    in.readByteArray(data);    // data = { 17,51 }}

编辑 – 测试案例2

public voID writetoParcel(Parcel out,int flags){    out.writeValue(ID);       // int = 256    out.writeValue(len);      // int = 2,length of byte array    out.writeByteArray(data); // byte array = { 17,51 }}public CANMessage(Parcel in){    len = in.readInt();        // 1    ID = in.readInt();         // 256    len = in.readInt();        // 1    len = in.readInt();        // 2    len = in.readInt();        // 2    if (data == null) data = new byte[len];    // in.readByteArray(data); // Crashes    int i = in.readInt();      // 13073 = 0x3311 = byte[] { 17,51 }}
解决方法 当您读取字节数组时,您需要先分配一个(至少)正确大小的字节数组.像这样:

byte[] blah = new byte[100];in.readByteArray(blah);

此外,您不希望使用writeValue()将基元写入包.使用适当的方法.例:

out.writeInt(ID);    // int = 256out.writeInt(len);   // int = 2,length of byte arrayout.writeByteArray(data);  // byte array = { 17,51 }

必须始终将write()方法与parcel上相同类型的read()方法配对.例如,如果使用writeValue()将某些内容写入Parcel,则必须使用readValue()读取它.如果您知道变量是int,那么您应该使用writeInt()编写它并使用readInt()读取它.如果使用writeValue()编写它,则对象的“类型”也会写入Parcel,以便readValue()知道它是什么类型的对象.这就是您在包中看到额外数据的原因.

总结

以上是内存溢出为你收集整理的android – 如何在intent中广播一个parcelable对象?全部内容,希望文章能够帮你解决android – 如何在intent中广播一个parcelable对象?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1127491.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-30
下一篇2022-05-30

发表评论

登录后才能评论

评论列表(0条)

    保存