2013-04-02 2 views
2

В приведенном ниже коде у меня есть два фрагмента, которые отображаются, когда их соответствующие вкладки выбраны. Оба этих фрагмента запускают asynctasks и должны показывать диалоги прогресса, пока они это делают. Первый фрагмент (ndi) показывает диалог выполнения, а фрагмент bnf никогда не показывает диалог выполнения. Почему это? Когда я нажимаю вкладку, которая является регистром 1 в коммутаторе, переключение вкладок происходит очень медленно, когда мое соединение происходит медленно, и экран замерзает. Я думаю, что нить нити заперта где-то, но я не знаю, где. Дайте мне знать, если вам нужна дополнительная информация. Благодарю.Почему мой диалог прогресса не появляется?

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() запускает свою асинтезу.

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. Делая это, вы фактически приостанавливаете основной поток своего приложения на длину вашей операции fetchStories. Другими словами, вы побеждаете цель использования AsyncTask.

В качестве предложения вы должны, вероятно, использовать Loaders вместо AsyncTasks, чтобы вернуть информацию о своей деятельности/фрагменте. Они по сути делают то же самое, но Loaders помогут вам сохранить ваши данные 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() '. –

Смежные вопросы