Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/179.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android BadParcelableException:解包时ClassNotFoundException_Android_Exception_Service_Badparcelableexception - Fatal编程技术网

Android BadParcelableException:解包时ClassNotFoundException

Android BadParcelableException:解包时ClassNotFoundException,android,exception,service,badparcelableexception,Android,Exception,Service,Badparcelableexception,我不太熟悉可序列化和可打包。我很难将此对象的实例从应用程序传递到远程服务: public class Event implements Parcelable, Cloneable { /** Defines under what Bundle's key architecture events are stored */ public static final String BUNDLE_KEY = "ZKEvent"; /** Defines which mess

我不太熟悉可序列化和可打包。我很难将此对象的实例从应用程序传递到远程服务:

public class Event implements Parcelable, Cloneable {

    /** Defines under what Bundle's key architecture events are stored */ 
    public static final String BUNDLE_KEY = "ZKEvent";

    /** Defines which messages are architecture's events */
    public static final int MSG_WHAT = 0xDEFECABE;

    /** Defines a key to store map under a Bundle to put into a Parcel (oh yeah!) */
    private static final String MAP_KEY = "MAP";

    /** Indicates this event ID. This ID should be the same in the event answer if any */
    private int idEvent = 0;

    /** Indicates this event priority */
    private int priority = EventPriority.EVENT_PRIORITY_LOW;

    /** ID for this event's sender */
    private int idSource = 0;

    /** ID for this event's destination */
    private int idDestination = 0;

    /** Action to be performed */
    private int action = EventAction.DEFAULT;

    public static final Parcelable.Creator<Event> CREATOR =
        new Parcelable.Creator<Event>() {
            public Event createFromParcel(Parcel in) {
            return new Event(in);
        }

        public Event[] newArray(int size) {
            return new Event[size];
        }
    };

    /** 
     * Event's data
     * Represented as 
     *      key -> parameter;
     *      value -> data 
     */
    private Map<String, Object> data = new HashMap<String, Object>();

    /** Default constructor */
    public Event() {};

    /** Contructor with ID of the event */
    public Event(int id) {
        idEvent = id;
    }

    /** Constructor for Parcelable */
    public Event(Parcel in) {
        readFromParcel(in);
    }

    /** Gets event's priority */
    public int getPriority() {
        return priority;
    }

    /** Sets this event's priority */
    public void setPriority(int priority) {
        this.priority = priority;
    }

    /** Gets the ID of this event's sender */   
    public int getIdSource() {
        return idSource;
    }

    /** Sets the ID of this event's sender */
    public void setIdSource(int idSource) {
        this.idSource = idSource;
    }

    /** Gets the ID of this event's destination */
    public Integer getIdDestination() {
        return idDestination;
    }

    /** Sets the ID of this event's destination */
    public void setIdDestination(Integer idDestination) {
        this.idDestination = idDestination;
    }

    /** Gets the action of this event */
    public int getAction() {
        return action;
    }

    /** Sets the action of this event */
    public void setAction(int action) {
        this.action = action;
    }

    /** Gets the data of this event */
    public Object getData(String key) {
        return data.get(key);
    }

    /** Sets the data of this event  */
    public void addData(String key, Object data) {
        this.data.put(key, data);
    }

    /** Gets the ID of this event */
    public int getIdEvent() {
        return idEvent;
    }

    /** Sets the ID of this event */
    public void setIdEvent(int idEvent) {
        this.idEvent = idEvent;
    }

    @Override
    public Object clone() {

        Event clone = new Event();

        clone.action = this.action;
        clone.idDestination = this.idDestination;
        clone.idEvent = this.idEvent;
        clone.idSource = this.idSource;
        clone.priority = this.priority;

        for(Entry<String,Object> entry: this.data.entrySet()) {
            clone.data.put(entry.getKey(), entry.getValue());
        }

        return clone;
    }

    @Override
    public int describeContents() {
        // TODO Nothing here
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {

        out.writeInt(idEvent);
        out.writeInt(priority);
        out.writeInt(idSource);
        out.writeInt(idDestination);
        out.writeInt(action);

        Bundle mapBundle = new Bundle();
        mapBundle.putSerializable(MAP_KEY, (Serializable) data);
    out.writeBundle(mapBundle);
    }

    /** Restoring this object from a Parcel */
    public void readFromParcel(Parcel in) {

        idEvent = in.readInt();
        priority = in.readInt();
        idSource = in.readInt();
        idDestination = in.readInt();
        action = in.readInt();

        Bundle mapBundle = in.readBundle();
        data = (Map<String, Object>) mapBundle.getSerializable(MAP_KEY);
    }
}
这里是远程服务中引发异常的位置:

    public void handleMessage(Message msg) {
        if (msg.what == Event.MSG_WHAT) {
            // Get the data bundle
            Bundle bundle = msg.getData();
            // Extract the event from the message
            Event event = (Event) bundle.get(Event.BUNDLE_KEY); // Exception thrown here
            sendEvent(event);
        } else {
            Log.i(TAG, "Received non architecture message, dropping...");
        }
    }
以及stacktrace:

07-09 12:38:10.947: E/AndroidRuntime(2234): FATAL EXCEPTION: main
07-09 12:38:10.947: E/AndroidRuntime(2234): android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.blabla.android.core.event.Event
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.os.Parcel.readParcelable(Parcel.java:1958)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.os.Parcel.readValue(Parcel.java:1846)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.os.Parcel.readMapInternal(Parcel.java:2083)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.os.Bundle.unparcel(Bundle.java:208)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.os.Bundle.get(Bundle.java:260)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at com.blabla.android.core.event.EventManager$EventHandler.handleMessage(EventManager.java:44)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.os.Looper.loop(Looper.java:123)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at android.app.ActivityThread.main(ActivityThread.java:3683)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at java.lang.reflect.Method.invokeNative(Native Method)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at java.lang.reflect.Method.invoke(Method.java:507)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-09 12:38:10.947: E/AndroidRuntime(2234):     at dalvik.system.NativeStart.main(Native Method)

非常感谢您的帮助,谢谢

在这种方法中,您永远不会将包写入地块:

public void writeToParcel(Parcel out, int flags) {

    out.writeInt(idEvent);
    out.writeInt(priority);
    out.writeInt(idSource);
    out.writeInt(idDestination);
    out.writeInt(action);

    Bundle mapBundle = new Bundle();
    mapBundle.putSerializable(MAP_KEY, (Serializable) data);
   // You need to actually write the Bundle to the Parcel here...
}
EDIT为类加载器问题添加了额外的解决方案:

在远程服务的
handleMessage()
中设置类加载器,如下所示:

/** Register with service */
private void registerWithService() {
    Event registerEvent = EventFactory.getEvent();
    registerEvent.setAction(EventAction.REGISTER);
    registerEvent.setIdSource(1);

    Bundle data = new Bundle();
    data.putParcelable(Event.BUNDLE_KEY, registerEvent);

    Message msg = new Message();
    msg.setData(data); // Exception thrown here in the Service
    msg.what = Event.MSG_WHAT;
    try {
        outMessenger.send(msg);
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
Bundle bundle = msg.getData();
bundle.setClassLoader(Event.class.getClassLoader());
Event event = (Event) bundle.get(Event.BUNDLE_KEY);

您的服务是否与您发送给它的捆绑包的创建者在同一个进程中运行,或者这是一个进程间请求?@Akki:我读了答案,但我不知道以后如何处理该
类加载器
。。。另外,如果两个应用程序中都包含一个类,为什么我需要一个单独的类加载器呢@朱尔斯:这是一个远程服务,所以它是一个IPC。可能是@Flow的重复。你的意思是另一个问题是这个问题的重复…我已经将它添加到包裹中,仍然是相同的例外。编辑问题。尝试以下操作:在远程服务中的
handleMessage()
中设置类加载器,如下所示:
Bundle=msg.getData();bundle.setClassLoader(Event.class.getClassLoader());Event Event=(Event)bundle.get(Event.bundle\u KEY)好的,我真的不知道为什么在这种情况下需要设置类加载器。显然,设置为默认值的类无法查看您的类(它可能是系统类加载器,因此只能查看标准的Android内容)。我会做更多的研究,看看能不能想出点什么。有趣的问题…请投票给
getClassLoader()
。它通过更改以下内容帮助我解决了
BadParcelableException
parcel.readSparseArray(null)到此:
packet.readSparseArray(MyClass.class.getClassLoader())@Roel你没有抓住要点。在整个讨论中,没有关于使用
Serializable
而不是
Parcelable
的内容。如果你真的看了原始文章,你会发现OP使用的是
Parcelable
,并且由于一些愚蠢的错误和类加载器的问题,在使用它时遇到了问题。