2013-04-02 65 views
2

在下面的代碼中,我有兩個片段,當它們各自的選項卡被選中時顯示。這兩個片段都運行asynctasks,並且應該在進行這些操作時顯示進度對話框。第一個片段(ndi)顯示其進度對話框,而片段bnf從不顯示其進度對話框。爲什麼是這樣?當我點擊交換機中情況1的標籤時,當我的連接速度很慢並且屏幕凍結時,標籤的切換非常緩慢。我認爲UI線程被鎖定在某個地方,但我不知道在哪裏。讓我知道你是否需要更多信息。謝謝。爲什麼我的進度對話框不顯示?

public class NasaAppActivity extends Activity implements ActionBar.TabListener{ 

    private Bundle savedInstanceState; 
    private static View mainView; 
    private FragmentTransaction ft; 
    BreakingNewsFragment bnf; 
    NasaDailyImage ndi; 

    @Override 

    @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(); 

      getFragmentManager().executePendingTransactions(); 
      ndi.onRefresh(); 

      ft=getFragmentManager().beginTransaction(); 
      ft.add(R.id.focused_view_container,bnf).commit(); 
       getFragmentManager().executePendingTransactions(); 

     } 
    } 

public void onTabSelected(Tab tab, FragmentTransaction f) { 

    switch(tab.getPosition()){ 
    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(); 
      getFragmentManager().executePendingTransactions(); 
     break; 
    } 

} 

這是進度對話框不工作,並呼籲bnf.fetchStories()

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

    RssNewsParser(Activity mainActivity,BreakingNewsFragment bnf){ 
     this.mainActivity=mainActivity; 
     this.bnf=bnf; 
    } 
    @Override 
    protected void onPostExecute(ArrayList<Story> result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
     for(Story story:stories){ 
      storyTitles.add(story.getTitle()); 
     } 

     bnf.setListAdapter(new ArrayAdapter<String>(mainActivity, 
       android.R.layout.simple_list_item_1,storyTitles)); 
     dialog.hide(); 
    } 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     dialog=ProgressDialog.show(mainActivity, "Loading", "loading news"); 
    } 

這是做工作的對話框後應該顯示出來,我感到困惑,因爲他們是以相同的方式使用。這個會在ndi.onRefresh()運行它的asynctask時得到顯示。

public class RssParseSync extends AsyncTask<String,String,Bitmap>{ 
     private Context parent; 
     private ProgressDialog dialog; 
     private static Bitmap final_image; //must be static because a new instance is required to access getFinalImage(); 
     private String imageURL=""; 
     private static String imageName; 
     private long totalTime; 
     private long startTime; 
     private static View v; 
     private Activity mainActivity; 


     public RssParseSync(View v,Activity mainActivity){ 

      this.v=v; 
      this.mainActivity=mainActivity; 

      String result=mainActivity.toString(); 
     } 
    protected void onPostExecute(Bitmap image){ 

        ImageView imageView=(ImageView) v.findViewById(R.id.imageDisplay); 
        imageView.setImageBitmap(image); 
        dialog.dismiss(); 
        //this.cancel(true); 
       } 

protected void onPreExecute(){ 
        if(final_image!=null){ 
         final_image.recycle(); 
        } 

        nullAllViews(); 
        dialog=ProgressDialog.show(mainActivity, "Loading", "Loading the image of the day"); 
       } 



private void nullAllViews(){ 
       TextView titleView; 
       titleView=(TextView) v.findViewById(R.id.imageTitle); 
       titleView.setText(null); 

       TextView dateView=(TextView) v.findViewById(R.id.imageDate); 
       dateView.setText(null); 

       TextView descriptionView=(TextView) v.findViewById(R.id.imageDescription); 
       descriptionView.setText(null); 

       ImageView imageView=(ImageView) v.findViewById(R.id.imageDisplay); 
       imageView.setImageBitmap(null); 

      } 


package com.wajumbie.nasadailyimage; 

import java.util.ArrayList; 
import java.util.concurrent.ExecutionException; 

import android.annotation.SuppressLint; 
import android.app.Activity; 
import android.app.Fragment; 
import android.net.Uri; 
import android.os.Bundle; 
import android.app.ListFragment; 
import android.content.Intent; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 


@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); 
     setRetainInstance(true); 


    } 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     // TODO Auto-generated method stub 
     super.onListItemClick(l, v, position, id); 

     String url = stories.get(position).getURL(); 
     Intent i = new Intent(Intent.ACTION_VIEW); 
     i.setData(Uri.parse(url)); 
     startActivity(i); 
    } 
    public void fetchStories(){ 

     RssNewsParser parser=new RssNewsParser(mainActivity,this); 
     if(stories.isEmpty()){ 
     parser.execute(); 

       try { 
        stories=parser.get(); 

       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (ExecutionException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
     } 
      //stories=parser.getStories(); 


    } 
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 void onRefresh() { 
     fetchStories(); 

    } 

} 
+0

什麼在你的'nullAllViews()'? – minhaz

+0

把它加在 –

+0

以上我猜問題在於'BreakingNewsFragment'。你可以發佈代碼,特別是創建和恢復片段時會調用的任何代碼。 –

回答

1

調用parser.get()強制您的代碼等待RssNewsParser任務完成。通過這樣做,您可以有效地暫停應用程序的主線程,從而實現您的操作長度。換句話說,你打敗了使用AsyncTask的目的。

作爲建議,您應該使用Loaders而不是AsyncTasks將您的RSS信息返回到您的活動/片段。他們基本上做同樣的事情,但裝載機將幫助您保持旋轉的RSS信息,並將結果更容易地返回到您的活動和視圖。

0

fetchStories()在主線程中執行,導致所有問題,掛起/進度對話框不可見。

+0

你能給我更多的細節嗎?爲什麼我的其他任務運行良好?我只是以錯誤的方式調用任務嗎? –

0

錯誤的使用方式AsyncTask。爲什麼你一直在調用'executePendingTransaction()'?什麼是快點?無論如何,經過分析你的代碼,我建議刪除以下代碼:

try { 
       stories=parser.get(); 

      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

請了解'AsyncTask'的工作。您必須等待它完成並在onPostExecute()中執行任何您想要的操作。在調用'execute()'之後,它會在下一行手動提取數據。

+1

這與已發佈的內容有何不同? – dymmeh

+0

get()等待線程結果 –

+0

@dymmeh上面的答案建議從'AsyncTask'移動到'Loaders',而我建議正確使用'AsyncTask',要求他等到'onPostExecute()'被調用。 –