2013-10-30 59 views
0

我在从AsynTask更新TextView时遇到了一个奇怪的问题。 在我的适配器的getView函数中,我启动了一个AsyncTask以计算一个数字并将其显示在屏幕上。从适配器启动的AsyncTask更新TextView(getView)

问题是getView函数被多次调用一个单独的项目,因此计算了几次我想要显示的数字,什么不是很有效率。

我一直在研究,并意识到,每当我试图限制数量OS调用到的AsyncTask,是不是在屏幕上显示的号码(没有错误消息或异常)

public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View rowView = inflater.inflate(R.layout.category_item, null); 
    TextView tvCategory = (TextView) rowView.findViewById(R.id.tvCategory); 
    TextView tvUnreadNews = (TextView) rowView.findViewById(R.id.tvUnreadNews); 

    Category cat = mCategoriesList.get(position); 
    tvCategory.setText(cat.getName()); 
    if(!cat.isInitialized()) //<-- If I delete this line it works, but inefficienly, as the AsyncTask is launched many times repeatedly 
    { 
      cat.setIsInitialized(true) 
     new GetNewsForCategoryTask(cat, tvUnreadNews, mContext).execute(cat.getId()); 
    } 
    return rowView; 
} 

这是的AsyncTask。正确更新的TextView时一边喊,但类别只调用一次时不更新值:

public class GetNewsForCategoryTask extends AsyncTask<String, Integer, JSONArray>{ 

private Context mContext; 
private String mCategoryId; 
private TextView mTvUnread; 
private Category mCategory; 

public GetNewsForCategoryTask(Category cat, TextView tvUnread, Context context) { 
    mTvUnread = tvUnread; 
    mCategory = cat; 
    mContext = context; 
} 

@Override 
protected JSONArray doInBackground(String... params) { 
    mCategoryId = params[0]; 

    ... 

} 

@Override 
protected void onProgressUpdate(Integer... values) { 
    mTvUnread.setText(Integer.toString(values[0])); 
} 

@Override 
protected void onPostExecute(JSONArray result) { 
    if(result != null && mThrown == null) 
    { 
     publishProgress(mCategory.getUnreadNewsSet().size()); 
    } 
} 

}

有谁有什么可能是这种怪异的行为的原因是什么?我检查了只在启动它们的类别时正确调用了AsyncTask,但只是不更新​​布局。为什么要推出几次类别作品?

更新: 我一直在测试,看起来问题是与getView()函数。如果我检查变量是否已经初始化,那么只有ListView的第一个元素会改变...以及ListView中其他项的所有值!

所以看起来像TextView试图设置的值始终是第一个(ListView的第一个元素)。

任何想法???

+0

是异步任务的'mTvUnread'专用字段? –

+0

是的,它是AsyncTask的私人领域。我在构造函数中初始化它。 –

+0

我在你的代码中看不到它?你可以发布完整的适配器和异步任务,所以我可以运行它.. –

回答

0

看看这个:

Category cat = mCategoriesList.get(position); 
tvCategory.setText(cat.getName()); 
if(!cat.isInitialized()) //<-- If I delete this line it works, but inefficienly, as the AsyncTask is launched many times repeatedly 
{ 
    cat.setIsInitialized(true) 
    new GetNewsForCategoryTask(cat, tvUnreadNews, mContext).execute(cat.getId()); 
} 

我认为你必须调用setIsInitialized(true)mCategoriesList.get(position),而不是cat,因为当getView()被再次调用,mCategoriesList.get(position)总是返回未初始化的一个,因为你cat打电话setIsInitialized(true),不在mCategoriesList

+1

嗯。 mCategoriesList是一个列表,我的意思是,一个对象,而不是一个主要类型。所以我希望当我将一个对象(列表)分配给另一个对象时,不会创建对象的副本,而是传递对象的引用,并且如果稍后修改引用,则应修改原始对象。我对吗? –

+0

哦,你是对的,我的坏。但是,也许我知道问题在哪里。 – traninho

+0

每当在滚动时可见新行时调用getView()。但是当调用getView()时,mTvUnread(你在onProgressUpdate中更新)总是一个新的实例。所以我的猜测是,当你更新mTvUnread时,它不再可用(可能泄漏,因为你在AsyncTask中持有引用作为成员)? – traninho

相关问题