2

在下面的代码中,我有两个片段在它们各自的选项卡被选中时显示。这两个片段都运行异步任务,并且应该在执行此操作时显示进度对话框。第一个片段 (ndi) 显示其进度对话框,而片段 bnf 从未显示其进度对话框。为什么是这样?当我单击 switch 中的 case 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() 运行它的异步任务时,会显示这个。

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

    }

}
4

3 回答 3

1

调用parser.get()会强制您的代码等待RssNewsParser任务完成。通过这样做,您有效地暂停了应用程序的主线程,直到您的fetchStories操作长度。换句话说,您违背了使用AsyncTask.

作为建议,您可能应该使用Loaders而不是AsyncTasks将您的 RSS 信息返回到您的活动/片段。它们基本上做同样的事情,但加载器将帮助您在轮换之间保留 RSS 信息,并且更容易将结果返回到您的活动和视图中。

于 2013-04-11T17:18:25.917 回答
0

fetchStories() 正在主线程中执行,这导致了所有问题,挂起/进度对话框不可见。

于 2013-04-10T10:34:24.967 回答
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()”之后,在下一行手动获取数据是错误的。

于 2013-04-11T18:04:55.017 回答