我使用 IntentService 从 Web 服务器接收一些数据,并用这些数据更新我在 Activity 中的列表视图。我在 Activity 中使用了静态 ArrayList,当我从服务器获得更新时,我将项目添加到静态 ArrayList 并向 Activity 发送广播通知。却造成了IllegalStateException
。我决定使用 Parcelable 类来更新我的列表。所以我的对象的类看起来像这样:
public class Order implements Parcelable{
// ....fields initialazion
public Order()
{}
public Order(List<File> files, boolean customer_deadline_sent,
boolean payed, boolean payment_failed, boolean not_payed_sent,
String info, int id, Category category, String timezone,
String title, Level level, DateTime updated_at, float price,
DateTime checkpoint_deadline, boolean h_notified, float refund,
String special_info, boolean checkpoint_deadline_sent,
ProcessStatus process_status, DateTime created_at,
CustomerThread cus_thread, boolean den, DateTime deadline , boolean is_active,
Product product, Subject subject) {
this.files = files;
this.customer_deadline_sent = customer_deadline_sent;
this.payed = payed;
this.payment_failed = payment_failed;
this.not_payed_sent = not_payed_sent;
this.info = info;
this.id = id;
this.category = category;
this.timezone = timezone;
this.title = title;
this.level = level;
this.updated_at = updated_at;
this.price = price;
this.checkpoint_deadline = checkpoint_deadline;
this.h_notified = h_notified;
this.refund = refund;
this.special_info = special_info;
this.checkpoint_deadline_sent = checkpoint_deadline_sent;
this.process_status = process_status;
this.created_at = created_at;
this.cus_thread = cus_thread;
this.den = den;
this.deadline = deadline;
this.is_active = is_active;
this.product = product;
this.subject = subject;
}
//...getters and setters
private void readFromParcel(Parcel in) {
boolean[] myBooleanArr = new boolean[6];
files = in.readArrayList(File.class.getClassLoader());
checkpoint_deadline_sent = myBooleanArr[0];
customer_deadline_sent = myBooleanArr[1];
payed = myBooleanArr[2];
payment_failed = myBooleanArr[3];
not_payed_sent = myBooleanArr[4];
den = myBooleanArr[5];
h_notified = myBooleanArr[6];
in.readBooleanArray(myBooleanArr);
special_info = in.readString();
title = in.readString();
timezone = in.readString();
info = in.readString();
id = in.readInt();
category = in.readParcelable(Category.class.getClassLoader());
level = in.readParcelable(Level.class.getClassLoader());
updated_at = in.readParcelable(DateTime.class.getClassLoader());
deadline = in.readParcelable(DateTime.class.getClassLoader());
checkpoint_deadline = in.readParcelable(DateTime.class.getClassLoader());
created_at = in.readParcelable(DateTime.class.getClassLoader());
process_status = in.readParcelable(ProcessStatus.class.getClassLoader());
cus_thread = in.readParcelable(CustomerThread.class.getClassLoader());
price = in.readFloat();
refund = in.readFloat();
}
public void writeToParcel(Parcel par, int arg1) {
par.writeList(files);
par.writeBooleanArray(new boolean[] {checkpoint_deadline_sent});
par.writeBooleanArray(new boolean[] {customer_deadline_sent});
par.writeBooleanArray(new boolean[] {payed});
par.writeBooleanArray(new boolean[] {payment_failed});
par.writeBooleanArray(new boolean[] {not_payed_sent});
par.writeBooleanArray(new boolean[] {den});
par.writeBooleanArray(new boolean[] {h_notified});
par.writeString(special_info);
par.writeString(info);
par.writeString(timezone);
par.writeString(title);
par.writeInt(id);
par.writeParcelable(category, arg1);
par.writeParcelable(level, arg1);
par.writeParcelable(checkpoint_deadline, arg1);
par.writeParcelable(created_at, arg1);
par.writeParcelable(deadline, arg1);
par.writeParcelable(updated_at, arg1);
par.writeParcelable(cus_thread, arg1);
par.writeParcelable(process_status, arg1);
par.writeFloat(price);
par.writeFloat(refund);
}
public static final Parcelable.Creator<Order> CREATOR =
new Parcelable.Creator<Order>() {
public Order createFromParcel(Parcel in) {
return new Order(in);
}
public Order[] newArray(int size) {
//throw new UnsupportedOperationException();
return new Order[size];
}
};
}
这就是我在 IntentService 中添加项目的方式:
@Override
protected void onHandleIntent(Intent intent) {
// getting existing static ArrayList from the Activity
public ArrayList<Order> serviceOrders = DashboardActivityAlt.forPrint;
// getting Order object from the web server and...
serviceOrders.add(0,orderObj);
// and finally sending it to the Activity:
intent = new Intent(ORDERS_IMPORT);
intent.putParcelableArrayListExtra("orders", serviceOrders);
sendBroadcast(intent);
}
这就是我参加活动的方式:
@Override
public void onReceive(Context context, Intent intent) {
Log.i("Dashboard onreceive", "I've got receiving");
updateUI(intent);
}
};
private void updateUI(Intent intent) {
try
{
DashboardActivityAlt.this.runOnUiThread(new Runnable (){
public void run() {
adapter.notifyDataSetChanged();
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
但尽管如此,我也有同样的情况IllegalStateException
。
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131296256, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1558)
at android.widget.AbsListView.onLayout(AbsListView.java:1366)
at android.view.View.layout(View.java:7175)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:912)
at android.view.View.layout(View.java:7175)
at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
at android.view.View.layout(View.java:7175)
at android.widget.FrameLayout.onLayout(FrameLayout.java:338)
at android.view.View.layout(View.java:7175)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1146)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1866)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)
请告诉我,我怎样才能避免这种情况?