2013-03-08 15 views
0

每當我正常運行我的應用程序時得到更新,該listfragment始終是空白的BNF片段。但是,如果我在獲取故事方法之前設置斷點,並逐行逐行執行代碼,則listfragment會被更新!我粘貼的最後一個類是一個AsycnTask,它獲取所有用來更新列表視圖的數據。我在想,我以某種方式做了線程錯誤的處理,但我不確定發生了什麼。對於它的價值,第一個被添加的片段也是一個asynctask,它工作正常。我的列表視圖只有使用調試器

public class NasaAppActivity extends Activity implements ActionBar.TabListener{ 

private Bundle savedInstanceState; 
private static View mainView; 
private FragmentTransaction ft; 
BreakingNewsFragment bnf; //a list fragment 
NasaDailyImage ndi; //another fragment 

@Override 
public void onStart(){ 
    super.onStart(); 
    if(savedInstanceState==null){ 
     ndi=new NasaDailyImage(this); 
     bnf=new BreakingNewsFragment(this);  
     ft=getFragmentManager().beginTransaction(); 
     ft.add(R.id.focused_view_container,ndi).commit(); 
     ft=getFragmentManager().beginTransaction(); 
     ft.add(R.id.focused_view_container,bnf).commit(); 
    } 

public void onTabSelected(Tab tab, FragmentTransaction f) { 

    switch(tab.getPosition()){ //switches which fragment is visible 
    case 0: 
     ft=getFragmentManager().beginTransaction(); 


      ft.hide(bnf); 
      ft.show(ndi); 
      ft.commit(); 

      getFragmentManager().executePendingTransactions(); 


     break; 
    case 1: 
      ft=getFragmentManager().beginTransaction(); 
      ft.hide(ndi); 
      ft.show(bnf); 

      ft.commit(); 
      bnf.fetchStories(); 
      bnf.updateList(); //updates the list fragment 
      getFragmentManager().executePendingTransactions(); 

     break; 
    } 

} 

}


@SuppressLint("ValidFragment") 
public class BreakingNewsFragment extends ListFragment { 
    private static Activity mainActivity; 
    private static ArrayList<Story> stories=new ArrayList<Story>(); 
    private static ArrayList<String> storyTitles=new ArrayList<String>(); 

    public BreakingNewsFragment(){ 

    } 
    public BreakingNewsFragment(Activity mainActivity){ 
     this.mainActivity=mainActivity; 
    } 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 

     return super.onCreateView(inflater, container, savedInstanceState); 
    } 

    @Override 
    public void onHiddenChanged(boolean hidden) { 
     // TODO Auto-generated method stub 
     super.onHiddenChanged(hidden); 

    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 



    } 
    public void fetchStories(){ 
     RssNewsParser parser=new RssNewsParser(mainActivity); 
     parser.execute(""); 
     stories=parser.getStories(); 
     for(Story story:stories){ 
      storyTitles.add(story.getTitle()); 
     } 
     String result; 
     result = storyTitles.toString(); 
    } 
public void updateList(){ 
    String result; 
    result = storyTitles.toString(); 
    setListAdapter(new ArrayAdapter<String>(mainActivity,android.R.layout.simple_list_item_1,storyTitles)); 
} 
    @Override 
    public void onStart() { 
     // TODO Auto-generated method stub 
     super.onStart(); 




    } 

} 

public class RssNewsParser extends AsyncTask<ArrayList<Story>,String,ArrayList<Story>>{ 
    private ProgressDialog dialog; 
    URL newsURL; 
    ArrayList<Story> stories=new ArrayList<Story>(); 
    int eventType; 
    int storyCount= -1; 
    private Activity mainActivity; 

    RssNewsParser(Activity mainActivity){ 
     this.mainActivity=mainActivity; 
    } 
    public ArrayList<Story> getStories(){ 
     return stories; 
    } 





     @Override 
     protected void onPostExecute(ArrayList<Story> result) { 
      // TODO Auto-generated method stub 
      super.onPostExecute(result); 
      dialog.hide(); 
     //this.cancel(true); 
    } 
    @Override 
    protected void onPreExecute() { 
     // TODO Auto-generated method stub 
     super.onPreExecute(); 

     dialog=ProgressDialog.show(mainActivity, "Loading", "loading news"); 
    } 
    @Override 
    protected ArrayList<Story> doInBackground(ArrayList<Story>... params) { 
     try{ 

     newsURL = new URL("http://www.nasa.gov/rss/breaking_news.rss");//set URl       
     BufferedReader in = new BufferedReader(new InputStreamReader(newsURL.openStream()));//get rss 
     XmlPullParserFactory factory; 
     factory = XmlPullParserFactory.newInstance();//new factory 
     factory.setNamespaceAware(true); 
     XmlPullParser xpp; 
     xpp = factory.newPullParser(); 
     xpp.setInput(in); 
     eventType = xpp.getEventType();//returns an int which mean different things (START_DOCUMENT,START_TAG,etc) 



    while(eventType!=XmlPullParser.END_DOCUMENT){//while the document has words 

    switch(eventType){ 

     case XmlPullParser.START_DOCUMENT://beginning of xml 
      break; 
     case XmlPullParser.START_TAG://case : at beginning of new tag 
      String tagName=xpp.getName(); 

      if(tagName.equals("item")){ 
       Story story=new Story(); 
       stories.add(story); 
       storyCount++; 
       xpp.getDepth(); 
      } 
      if(tagName.equals("title")&& !stories.isEmpty()){ 
       xpp.getDepth(); 
       stories.get(storyCount).setTitle(xpp.nextText()); 
      } 
      if(tagName.equals("link") && !stories.isEmpty()){ 
       stories.get(storyCount).setURL(xpp.nextText()); 
       xpp.getDepth(); 
      } 
      if(tagName.equals("description")&& !stories.isEmpty()){ 
       stories.get(storyCount).setDescription(xpp.nextText()); 
       xpp.getDepth(); 
      } 

      break; 

     } 
     eventType=xpp.next(); 
    }//switch 
     in.close();//close BufferedReader 
    } catch (MalformedURLException e){ 
     e.printStackTrace(); 
    }catch(XmlPullParserException e1){ 
     e1.printStackTrace(); 
    }catch(IOException e2){ 
     e2.printStackTrace(); 
    }  
     return stories; 
    } 

} 

回答

1

我的列表視圖使用調試器時只得到更新

她Ë

parser.execute(""); 
    stories=parser.getStories(); //<<<<<<< here 

你想只是執行AsyncTask後得到AsyncTask結果返回。或者使用AsyncTask.get()方法得到的結果返回並等待,直到doInBackground執行不徹底或使用onPostExecute與來自doInBackground返回新的數據更新ListView。將您的onPostExecute更改爲:

@Override 
protected void onPostExecute(ArrayList<Story> result) { 
    // TODO Auto-generated method stub 
    super.onPostExecute(result); 
    // get data here 
    stories=getStories(); 
    BreakingNewsFragment.this.setListAdapter(new ArrayAdapter<String>(mainActivity, 
         android.R.layout.simple_list_item_1,stories)); 
    dialog.hide(); 

    } 
+0

謝謝你,所以它試圖結束任務之前得到結果呢? – 2013-03-08 06:53:36

+0

@TylerPfaff:是的,你目前正在嘗試在完成AsyncTask執行之前得到結果,這是因爲doInBackground方法總是在與主UI線程分開的線程中執行。這就是爲什麼主線程執行不是阻塞的原因。你得到空的名單 – 2013-03-08 06:58:02

1

您正在將fetchStories方法視爲阻塞調用。這意味着,您期待您的代碼等到該方法完成後再調用調用updateStories方法的下一行。但是,由於fetchStories異步工作,因此在調用updateStories時尚未完成。

解決這個問題的方法是從你的AsyncTask的onPostExecute方法調用updateStories。這種方法的目的是讓你到啓動您的AsyncTask線程上執行代碼(通常是UI線程,所以你可以做更新)任務完成其主要工作(你把doInBackground東西)

調試時它的工作原因是因爲在調用updateStories之前,您的代碼執行速度已經變慢,足以讓fetchStories完成。在設備上,情況並非如此。

簡短的回答,更新從onPostExecute列表。

相關問題