2012-03-26 81 views
0

我正在研究新聞閱讀器,並且我有兩個主要活動,主要和故事。主要調用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

+0

發佈您的AsyncTask.doInBackground()方法將有所幫助。 – yorkw 2012-03-26 21:38:14

回答

1

使用:

@Override 
    protected Void doInBackground(String... arg0) { 
     // TODO Auto-generated method stub 

    } 

原因這有UI的存取權限。 並且對於ListView使用listview.notifyDataSetChanged();

希望這有助於

+0

試試這個[link](http://www.ibm。com/developerworks/xml/library/x-dataAndroid /)和[鏈接](http://www.helloandroid.com/tutorials/newsdroid-rss-reader) – 2012-03-26 13:56:47

相關問題