I'm coding and android app which have 2 process, One is obviously the main process which handle all the UI things and other stuffs and the other process hosts a service that handles network(socket) listening and other things.
To communicate across the two process, I use the Messenger approach, and works great until I need to send custom java objects. This java class implements the Parcelable interface, which allows Messenger to send java object across process boundaries.
Here is an exmple of my java class I want to send.
package com.locator.carlocator.models;
import android.os.Parcel;
import android.os.Parcelable;
public class Phone implements Parcelable {
public String number;
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.number);
dest.writeString(this.name);
}
public Phone() {
}
private Phone(Parcel in) {
this.number = in.readString();
this.name = in.readString();
}
public static final Parcelable.Creator<Phone> CREATOR = new Parcelable.Creator<Phone>() {
@Override
public Phone createFromParcel(Parcel source) {
return new Phone(source);
}
@Override
public Phone[] newArray(int size) {
return new Phone[size];
}
};
}
And this is how I crate the object instance I want to send, this is triggered by a message received and then send to the main process. The next block of code runs on a service which runs on a different process and communicates using Messenger IPC built in API.
Phone phone = new Phone();
phone.setNumber("6000-0006");
phone.setName("Alex Sanchez");
data = new Bundle();
data.setClassLoader(Phone.class.getClassLoader());
data.putParcelable("key-phone", phone);
Message msg = Message.obtain(null, MSG_A_REQUEST);
msg.setData(data);
notifySubscribers(msg); // this method perform the send message.
how is implemented the sender method?
private void notifySubscribers(Message msg) {
for(Messenger subscriber : serviceSubscribers) {
try {
subscriber.send(msg);
} catch (RemoteException e) {
Log.e(TAG, "Subscriber not available");
e.printStackTrace();
}
}
}
And here is part of the stack trace:
00:53:05.382 21542-21542 E/Parcel: Class not found when unmarshalling: com.locator.carlocator.models.Phone
java.lang.ClassNotFoundException: com.locator.carlocator.models.Phone
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:309)
at java.lang.Class.forName(Class.java:273)
at android.os.Parcel.readParcelableCreator(Parcel.java:2281)
at android.os.Parcel.readParcelable(Parcel.java:2245)
at android.os.Parcel.readValue(Parcel.java:2152)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2485)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.Bundle.getParcelable(Bundle.java:755)
at com.locator.carlocator.MainActivity$IncomingHandler.handleMessage(MainActivity.java:2255)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:702)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.locator.carlocator.models.Phone" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]