如何在单独的进程中将 ArrayList 从主 activity 传递到后台服务 运行?
How can I pass an ArrayList from a main activity to a background service running in a separate process?
我尝试在不同的进程中将 "Set" 的值从主 activity 传递到后台服务 运行(反之亦然)。由于我没有找到任何 "Bundle" 或 "Message.Obj" 方法处理 "Sets",我将 "Set" 转换为 "ArrayList"。使用此源 "ArrayList" 发送消息似乎没有错误,因为服务收到了消息。但是,当我尝试从 "Message" 中检索 "ArrayList" 时,出现错误。
这里是"Parcelable"class的源代码:
public class SavedCell implements Parcelable {
public String cssId;
public boolean isFinalized;
public boolean isInduced;
public Set<Integer> potential;
public SavedCell(Cell c) {
this.cssId = c.cssId;
this.isFinalized = c.isFinalized;
this.isInduced = c.isInduced;
this.potential = new HashSet(c.potential);
}
public SavedCell(String id, boolean f, boolean i, Set<Integer> p) {
this.cssId = id;
this.isFinalized = f;
this.isInduced = i;
this.potential = new HashSet(p);
}
public SavedCell(Parcel p) {
this.cssId = p.readString();
this.isFinalized = (p.readByte() != 0);
this.isInduced = (p.readByte() != 0);
int[] potentialArray = p.createIntArray();
this.potential = new HashSet();
for (int i : potentialArray) {
this.potential.add(i);
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.cssId);
dest.writeByte((byte) (this.isFinalized ? 1 : 0));
dest.writeByte((byte) (this.isInduced ? 1 : 0));
int[] potentialArray = new int[this.potential.size()];
int idx = 0;
for (Iterator it=this.potential.iterator(); it.hasNext();) {
potentialArray[idx++] = (int) it.next();
}
dest.writeIntArray(potentialArray);
}
public static final Creator<SavedCell> CREATOR = new Creator<SavedCell>() {
@Override
public SavedCell createFromParcel(Parcel in) {
return new SavedCell(in);
}
@Override
public SavedCell[] newArray(int size) {
return new SavedCell[size];
}
};
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SavedCell other = (SavedCell) obj;
return this.cssId.equalsIgnoreCase(other.cssId);
}
}
这是处理主程序中数据发送的代码 Activity:
public void createInitialSnapshot(Set<SavedCell> sgc, boolean initialisePuzzle) {
ArrayList<SavedCell> bundledPuzzle = new ArrayList<>(sgc);
if (isSolveServiceBound) {
try {
Bundle b = new Bundle();
b.putParcelableArrayList("bundledPuzzle", bundledPuzzle);
Message msg = Message.obtain(null, MSG_SAVE_INITIAL_SNAPSHOT, (initialisePuzzle) ? 1 : 0, 0, null);
msg.setData(b);
msg.replyTo = messengerSolveClient;
messengerSolveService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
最后,尝试在后台服务进程中检索数据的代码:
private void saveInitialSnapShot(Message msg) {
Bundle b = msg.getData();
if (b == null) {
...
} else {
...
ArrayList<SavedCell> bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");
Set<SavedCell> sgc = new HashSet(bundledPuzzle);
...
}
围绕 "ArrayList bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");" try-catch 块中的语句,报告的异常是 "android.os.BadParcelableException: ClassNotFoundException when unmarshalling: be.ema.sc.SavedCell".
感谢这两个链接: and ,我在 ArrayList<SavedCell> bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");
语句之前添加了 b.setClassLoader(getClass().getClassLoader());
语句,这解决了问题。从 Bundle 中检索数据的代码现在如下所示:
private void saveInitialSnapShot(Message msg) {
Bundle b = msg.getData();
if (b == null) {
...
} else {
...
b.setClassLoader(getClass().getClassLoader());
ArrayList<SavedCell> bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");
Set<SavedCell> sgc = new HashSet(bundledPuzzle);
...
}
}
我尝试在不同的进程中将 "Set" 的值从主 activity 传递到后台服务 运行(反之亦然)。由于我没有找到任何 "Bundle" 或 "Message.Obj" 方法处理 "Sets",我将 "Set" 转换为 "ArrayList"。使用此源 "ArrayList" 发送消息似乎没有错误,因为服务收到了消息。但是,当我尝试从 "Message" 中检索 "ArrayList" 时,出现错误。
这里是"Parcelable"class的源代码:
public class SavedCell implements Parcelable {
public String cssId;
public boolean isFinalized;
public boolean isInduced;
public Set<Integer> potential;
public SavedCell(Cell c) {
this.cssId = c.cssId;
this.isFinalized = c.isFinalized;
this.isInduced = c.isInduced;
this.potential = new HashSet(c.potential);
}
public SavedCell(String id, boolean f, boolean i, Set<Integer> p) {
this.cssId = id;
this.isFinalized = f;
this.isInduced = i;
this.potential = new HashSet(p);
}
public SavedCell(Parcel p) {
this.cssId = p.readString();
this.isFinalized = (p.readByte() != 0);
this.isInduced = (p.readByte() != 0);
int[] potentialArray = p.createIntArray();
this.potential = new HashSet();
for (int i : potentialArray) {
this.potential.add(i);
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.cssId);
dest.writeByte((byte) (this.isFinalized ? 1 : 0));
dest.writeByte((byte) (this.isInduced ? 1 : 0));
int[] potentialArray = new int[this.potential.size()];
int idx = 0;
for (Iterator it=this.potential.iterator(); it.hasNext();) {
potentialArray[idx++] = (int) it.next();
}
dest.writeIntArray(potentialArray);
}
public static final Creator<SavedCell> CREATOR = new Creator<SavedCell>() {
@Override
public SavedCell createFromParcel(Parcel in) {
return new SavedCell(in);
}
@Override
public SavedCell[] newArray(int size) {
return new SavedCell[size];
}
};
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SavedCell other = (SavedCell) obj;
return this.cssId.equalsIgnoreCase(other.cssId);
}
}
这是处理主程序中数据发送的代码 Activity:
public void createInitialSnapshot(Set<SavedCell> sgc, boolean initialisePuzzle) {
ArrayList<SavedCell> bundledPuzzle = new ArrayList<>(sgc);
if (isSolveServiceBound) {
try {
Bundle b = new Bundle();
b.putParcelableArrayList("bundledPuzzle", bundledPuzzle);
Message msg = Message.obtain(null, MSG_SAVE_INITIAL_SNAPSHOT, (initialisePuzzle) ? 1 : 0, 0, null);
msg.setData(b);
msg.replyTo = messengerSolveClient;
messengerSolveService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
最后,尝试在后台服务进程中检索数据的代码:
private void saveInitialSnapShot(Message msg) {
Bundle b = msg.getData();
if (b == null) {
...
} else {
...
ArrayList<SavedCell> bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");
Set<SavedCell> sgc = new HashSet(bundledPuzzle);
...
}
围绕 "ArrayList bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");" try-catch 块中的语句,报告的异常是 "android.os.BadParcelableException: ClassNotFoundException when unmarshalling: be.ema.sc.SavedCell".
感谢这两个链接: and ,我在 ArrayList<SavedCell> bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");
语句之前添加了 b.setClassLoader(getClass().getClassLoader());
语句,这解决了问题。从 Bundle 中检索数据的代码现在如下所示:
private void saveInitialSnapShot(Message msg) {
Bundle b = msg.getData();
if (b == null) {
...
} else {
...
b.setClassLoader(getClass().getClassLoader());
ArrayList<SavedCell> bundledPuzzle = b.getParcelableArrayList("bundledPuzzle");
Set<SavedCell> sgc = new HashSet(bundledPuzzle);
...
}
}