我正在研究新聞閱讀器,並且我有兩個主要活動,主要和故事。主要調用asynctask並獲取所有rss提要,然後在完成時顯示標題。故事顯示來自特定供稿的文章。有一個主要的導航欄可以調用故事。在多個活動中使用單個陣列適配器的多個實例
我下載和解析的文章位於提要的數組列表的散列表中。我只有一個適配器類,即arrayAdapter。一切工作正常,每創建一個新的列表視圖,我創建arrayAdapter的單獨實例,但問題是,當我從故事回到主要,並單擊列表中的任何東西,特別是當故事中的項目較少,然後頭條新聞主要崩潰了:
java.lang.IllegalStateException:適配器的內容已更改,但ListView未收到通知。確保適配器的內容不會從後臺線程修改,而只能從UI線程修改。 [ListView中(2131099654,類android.widget.ListView)與適配器(類package.package.ArticleListAdapter)
我覺得我的錯誤是由不像個單獨的實例適配器來了,儘管我我認爲我已經把它們分開了。我四處尋找幫助,但我看到的大部分內容都是關於人們從後臺線程更改數據,而不是在單獨的活動中。
不幸的是,這段代碼被意譯,部分用於可讀性強,部分原因是因爲我在寫這別人的,封閉源代碼腳本非常重要......
class main{
public HashMap<Integer, ArrayList<ArticleHolder>> allArticles;
public ArticleListAdapter ArtListAdapter;
public void onCreate(Bundle savedInstanceState) {
allArticles = new HashMap<Integer, ArrayList<ArticleHolder>>();
myApp appstate = (myApp)getApplicationContext();
appState.setParsedArticles(allArticles); //Added this for universal availability of the articles
//download things
//background.execute();
//...
}
private class downloader extends Asynctask ...{
...
onPostExecute(){
ArticleListAdapter = new ArticleListAdapter(context c, list_item L, allArticles.get(1));
listView1 = (ListView)findViewById(R.id.listView1);
listView1.setAdapter(ArtListAdapter);
}
}
class stories{
public HashMap<Integer, ArrayList<ArticleHolder>> allArticles;
public ArticleListAdapter ArtListAdapter;
public void onCreate(Bundle savedInstanceState) {
myApp appstate = (myApp)getApplicationContext();
allArticles = appState.getParsedArticles();
//set layout
//get article to display from Bundle extras
ListView LV = (ListView) findViewById(R.id.listView1);
ArtListAdapter = new ArticleListAdapter(StoriesScreenActivity.this, R.layout.article_list_item, allCleanArticles.get(buttonFeedNum));
LV = (ListView)findViewById(R.id.listView1);
LV.setAdapter(ArtListAdapter);
}
}
代碼適配器如下,爲準確:
public class ArticleListAdapter extends ArrayAdapter<ArticleHolder>{
private static ArrayList<ArticleHolder> ArticleList;
private Context context;
private LayoutInflater mInflater;
public ArticleListAdapter(Context pcontext, int layoutResourceId, ArrayList<ArticleHolder> results) {
super(pcontext, layoutResourceId, results);
context = pcontext;
ArticleList = results;
mInflater = LayoutInflater.from(context);
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.article_list_item, null);
holder = new ViewHolder();
holder.txtMain = (TextView) convertView.findViewById(R.id.textView1);
holder.txtblurb = (TextView) convertView.findViewById(R.id.textView2);
holder.pic_view = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtMain.setText(ArticleList.get(position).getTitle());
holder.txtblurb.setText(ArticleList.get(position).getMainText());
holder.pic_view.setContentDescription(context.getString(R.string.GenImgDesc));
UrlImageViewHelper.setUrlDrawable(holder.pic_view, ArticleList.get(position).getPicName(),R.drawable.ic_placeholder);
return convertView;
}
public int getCount() {
return ArticleList.size();
}
public ArticleHolder getItem(int position) {
return ArticleList.get(position);
}
public long getItemId(int position) {
return position;
}
static class ViewHolder {
TextView txtMain;
TextView txtblurb;
ImageView pic_view;
}
}
感謝您的幫助,我真的被卡住了。
此外,很多感謝和支持Github上的koush和Jwsonic在UrlImageViewer上的工作。這很棒。
編輯: 這是我的AsyncTask.doInBackground()。對不起,我花了這麼長時間,沒有我的電腦,我離開了城市一段時間。再次感謝你的幫助。
protected Boolean doInBackground(String... params) {
boolean succeeded = false;
String downloadPath = null;
for(Integer num: feedArray){
downloadPath = "example.com/rss/"+Integer.toString(num);
doSax(downloadPath, num);
}
for(Integer num: feedArray){
currentDirtyFeedArticles = allDirtyArticles.get(num);
for(ArticleHolder dirtyArticle: currentDirtyFeedArticles){
dirtyArticle.setTitle(textCleaner(dirtyArticle.getTitle()));
//some text cleaning to make it look pretty
}
}
succeeded = true;
return succeeded;
}
好了,所以我把Jedi_warriors的意見,並試圖添加notifyDataSetChanged(),但我無法弄清楚它是如何得到它與我的自定義適配器網。儘管如此,它讓我走上了正確的道路,因爲我意識到主屏幕上的列表視圖在我返回時並未得到更新。這導致我研究了一個onResume方法,經過一些試驗和錯誤之後,我最終調用了代碼將視圖與適配器關聯到onResume。這裏的訣竅是應用程序在打開時崩潰,因爲該代碼沒有準備好,所以我阻止了onResume中的代碼運行,直到應用程序準備就緒。據我所知,這似乎解決了這個問題。感謝你的幫助!在的AsyncTask
發佈您的AsyncTask.doInBackground()方法將有所幫助。 – yorkw 2012-03-26 21:38:14