2015-08-23 50 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,但不要将其缓存,并立即使用它。