0

我使用IntentService从Web服务器接收一些数据,并使用此数据在Activity中更新我的列表视图。我在Activity中使用了静态ArrayList,当我从服务器获取更新时,我将项目添加到静态ArrayList并将广播通知发送到Activity。但它造成了IllegalStateException。我决定使用Parcelable类来更新列表。所以,我的对象的类看起来像这样:IllegalStateException listview从服务更新

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) 

请告诉我,我该如何避免这种情况?

+0

当你得到这个错误? –

+0

当我从服务器获取项目并使用它更新适配器时。我在我的IntentService中创建私有arraylist,并使其等于我放入适配器的arraylist。当我从服务器接收到新项目时,我将这个项目添加到我的私人数组列表中,并且使用putParcelableArrayListExtra方法将它意图发送给我的Activity with listView。在onReceive()方法中,我用新项目获得这个新的arrayList,将它等同于设置为适配器并使用notifyDataSetChanged()更新适配器的那些项目。 –

+0

我认为prob是onReceive方法,你可以在runonUIThread方法内移动你的代码后尝试吗? –

回答

0

我解决了这个问题,使用Handler将项目添加到我的listView,所以这个添加将在UI线程中执行。我使用相同的公共静态ArrayList,并使用Handler将其添加到它。为我工作...

private void addMethod(Order r) 
    { 
     mHandler.post(new sendUpdatings(r)); 
    } 

private class sendUpdatings implements Runnable { 
     Order r; 

     public sendUpdatings(Order r) { 
      this.r = r; 
     } 

     public void run(){ 
      DashboardActivityAlt.forPrint.add(0,r); 
     } 
    }