2015-08-23 91 views
1

我正在使用smack(XMPP庫)和Mosby'sMvpFagment來顯示列表視圖(他/她的連接)中的用戶名單。Android Smack與MVP片段

我得到了下面的代碼在不同片段的作品只是用改造圖書館進行網絡通話:

public void loadListData(final List<NeighbourListItemModel> itemsList) { 
    Log.e("list", itemsList.size() + ""); 
    listViewAdapter.clear(); 
    listViewAdapter.addThemAll(itemsList); 
    listViewAdapter.notifyDataSetChanged(); 
} 

它得到由RosterListener稱爲使用roster.addRosterListener(new RosterListener() { .. });

NeighbourListItemModel只是一個簡單的POJO類有一些getters和setts。

但是,這給出AbstractXMPPConnection﹕ Exception in async packet listener android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.錯誤,可能是因爲XMP連接在其自己的線程中運行。

現在,如果我的代碼更改爲以下:

@Override 
public void loadListData(final List<NeighbourListItemModel> itemsList) { 
    Log.e("list", itemsList.size() + ""); 
    getActivity().runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      listViewAdapter.clear(); 
      listViewAdapter.addThemAll(itemsList); 
      listViewAdapter.notifyDataSetChanged(); 
     } 
    }); 
} 

我得到一個java.lang.NullPointerException: Attempt to invoke virtual method 'int getLayout()' on a null object reference錯誤。凡getLayout中定義:

@Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 

     ViewHolderAbstractClass viewHolder; 
     if (null == convertView || null == convertView.getTag()) { 
      viewHolder = getItem(position).getDefaultViewHolder(mItemType); 
      convertView = LayoutInflater.from(getContext()).inflate(viewHolder.getLayout(), null); 
      viewHolder.findViewsById(convertView); 
      convertView.setTag(viewHolder); 
     } else { 
      viewHolder = (ViewHolderAbstractClass) convertView.getTag(); 
     } 

     BaseModel previousItem = position > 0 ? getItem(position - 1) : null; 
     viewHolder.setup(getItem(position), previousItem, mCaller.getContext(), position); 

     return convertView; 
    } 

的觀點持有者抽象類是沒有什麼特別的:

public abstract class ViewHolderAbstractClass { 

    abstract public int getLayout(); 

    abstract public void findViewsById(View view); 

    abstract public void initializeComponentBehavior(BaseModel item, Context context, int position); 

    public void setup(BaseModel item, BaseModel previous_item, Context context, int position) { 
     initializeComponentBehavior(item, context, position); 
    } 

} 

如此明顯的viewHolder變量是空的,但我不知道爲什麼。我的適配器被定義爲new BaseListAdapter(this, R.layout.neighbours_list_item, new ArrayList<ChatItemModel>(), Constants.DATA_TYPE.CHAT);

就像我說的,當我使用Retrofit進行調用時,前面的代碼正在工作,但我懷疑在自己的線程中運行的XMPP讓我頭疼。

+0

我從來沒有使用過MVP。但是我沒有看到抽象getLayout()的代碼。 –

+0

我想知道。你爲什麼要使用Mosby的MvpFagment?和任何圖書館一樣,保持與Android等框架的兼容性一直是個問題。 –

+0

@TheOriginalAndroid不幸的是,這不是我的決定,因爲我正在處理現有的代碼。我會以不同的方式做到這一點,但這意味着我必須拆開這個應用程序。到目前爲止,它給了我一些頭痛的問題。 getLayout函數只是回退R.id. ,就是這樣。 – Gooey

回答

1

問題是Constants.DATA_TYPE itemType指的是導致空返回的另一個模型,而不是NeighbourListItemModel。堆棧跟蹤沒有清楚地顯示出來,但至少現在已經解決了。

+0

btw。 Mosby認爲從Presenter到View的所有交互發生在主UI線程上。你應該考慮在主ui線程上調用'loadListData()',而不是在View中調用runOnUiThread() – sockeqwe

0

1)我認爲這個代碼viewHolder = getItem(position).getDefaultViewHolder(mItemType)是一個嫌疑犯。看起來代碼緩存了ViewHolder類,問題是您無法緩存或保存UI ID。我相信你會注意到其他開發者只需創建一個ViewHolder的實例。

除此之外,請發送代碼getDefaultViewHolder。

2)另外,我懷疑findViewsById()方法無法工作,因爲它似乎試圖緩存UI ID來查找正確的View對象。

**這個緩存UI ID的問題現在更加明顯(!),因爲您在單獨的線程上獲取ID。

然而,您可能會在單獨的UI線程上更新UI視圖。您可以在單獨的線程上獲取UI ID,但不要將其緩存,並立即使用它。