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); 
     } 
    }