Android 显示片段时启动asynctask

Android 显示片段时启动asynctask,android,sqlite,android-fragments,android-asynctask,Android,Sqlite,Android Fragments,Android Asynctask,我有3个碎片 在每个片段的onActivityCreated()中,我执行一个异步任务 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mTaskGetPoints = new AsyncTaskGetFavouritePoints(); mTaskGetPoints.execute(); }

我有3个碎片

在每个片段的onActivityCreated()中,我执行一个异步任务

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    mTaskGetPoints = new AsyncTaskGetFavouritePoints();
    mTaskGetPoints.execute();
}
doInBackground中的异步任务从SQLite数据库获取数据,并创建对象的ArrayList。在onPostExecute中,我调用一个方法在listView上显示数据

每个片段都有自己的异步任务

当我“启动”FragmentActivity时,将显示片段1并执行其asynctask。但是它最近的片段(片段2,中间片段)也启动了它的异步任务

public interface OnFragmentShownListener {
    void onFragmentShown();
}
我想知道是否只有当用户看到片段时才可以启动异步任务。 我想如果可能的话,因为我想显示一个进度对话框(获取数据…)。 现在我从数据库中获得的数据很少,但如果我有很多数据,我希望显示一个进度对话框。现在,如果我在每个asynctask的onPreExecute中显示ProgressDialog,如果从片段1更改为片段2,我会在片段2上看到片段3的ProgressDialog:/

也许我错了,异步任务的使用不好

编辑1: 碎片活动

public class FragmentActivityInterestPoints extends FragmentActivity implements
        ActionBar.TabListener { 
    PagerAdapterInterestPoints mInterestPointsPagerAdapter;
    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.pager_adapter_fragment);
        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the app.
        mInterestPointsPagerAdapter = new PagerAdapterInterestPoints(
                getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mInterestPointsPagerAdapter);

        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager
                .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        actionBar.setSelectedNavigationItem(position);
                    }
                });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mInterestPointsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by
            // the adapter. Also specify this Activity object, which implements
            // the TabListener interface, as the callback (listener) for when
            // this tab is selected.
            actionBar.addTab(actionBar.newTab()
                    .setText(mInterestPointsPagerAdapter.getPageTitle(i))
                    .setTabListener(this));
        }

    }


    @Override
    public void onTabSelected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
    }

}


public class PagerAdapterInterestPoints extends FragmentPagerAdapter {

    private static final int PAGES = 3;

    private ArrayList<Fragment> pages = new ArrayList<Fragment>(PAGES);

    public PagerAdapterInterestPoints(FragmentManager fm) {
        super(fm);

        pages.add(new FragmentShowPoints());
        pages.add(new FragmentCategoryPoints());
        pages.add(new FragmentFavouritePoints());
    }

    @Override
    public int getCount() {
        // Show total pages.
        return PAGES;
    }

    @Override
    public Fragment getItem(int position) {
        return pages.get(position);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
        case 0:
            return "Fragment 1";
        case 1:
            return "Fragment 2";
        case 2:
            return "Fragment 3";
        default:
            return "Undefined";
        }
    }

}


public class FragmentShowPoints extends ListFragment {
    private MyDatabase myDB;

    private ArrayList<PointInterest> listPoints = null;
    // UI
    private ListView lv;
    View rootView;
    ListAdapterShowPoints adapter;

    AsyncTaskGetPoints mTaskGetPoints;
    ProgressDialog progressDialog;
    private Activity act;

    public FragmentShowPoints() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.activity_show_points, container,
                false);

        this.act = getActivity();

        return rootView;
    }

    @Override
    public void onResume() {
        super.onResume();

        // Load UI
        lv = getListView();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mTaskGetPoints = new AsyncTaskGetPoints();
        mTaskGetPoints.execute();
    }

    @Override
    public void onPause() {
        if (mTaskGetPoints != null) {
            mTaskGetPoints.cancel(true);
        }
        super.onPause();
    }

    @Override
    public void onDestroy() {
        if (mTaskGetPoints != null) {
            mTaskGetPoints.cancel(true);
        }
        super.onDestroy();
    }


    @Override
    public void onStop() {
        super.onStop();
    }

    private void showPoints() { 
            adapter = new ListAdapterShowPoints(act, listPoints, act);
            setListAdapter(adapter);
        }
    }

    private class AsyncTaskGetPoints extends
            AsyncTask<Void, Void, ArrayList<PointInterest>> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            progressDialog = new ProgressDialog(act);
            progressDialog.setMessage("Loading...");
            progressDialog.show();
        }

        @Override
        protected ArrayList<PointInterest> doInBackground(Void... params) {
            myDB = new MyDatabase(act);
            Cursor c = myDB.getPoints();
            //loop with data
            c.close();
            myDB.close();
            return listPoints;
        }

        @Override
        protected void onPostExecute(ArrayList<PointInterest> result) {
            progressDialog.dismiss();
            showPoints();
        }

    }
}



<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/pager"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity" >
</android.support.v4.view.ViewPager>
但只有我在onPostExecute()中有问题。当一个片段被恢复,但您没有看到它时,它工作正常,我不知道确切的原因,因为在onPreExecute中应该崩溃


编辑3:我也应该使用加载程序而不是异步任务进行测试。

问题在于,根据您用来更改片段的内容(从您所说的内容来看,我认为您使用的是
ViewPager
,不是吗?),它会在向用户显示片段之前缓存片段,以便加载UI的时间不会太长

我建议您最好在片段更改时使用调用的回调启动
AsyncTask
。您可以有一个接口,由您的片段实现,并在从一个片段更改为新片段时调用

编辑:来自代码的更多信息

首先,创建一个由片段实现的简单回调接口,该接口将启动异步任务

public interface OnFragmentShownListener {
    void onFragmentShown();
}
然后,在您的
SimpleOnPageChangeListener#onPageSelected
上,调用您的
MinterestPointsPageAdapter.getItem(position)
,以检索显示的片段

然后,仍然在您的onPageSelected中调用您的
((OnFragmentShownListener)片段).onFragmentShowed()
,它应该启动您的异步任务

public interface OnFragmentShownListener {
    void onFragmentShown();
}

希望这有帮助:)

如果用户没有看到您的片段,为什么还要附加这些片段?你的碎片是如何构造的?是寻呼机吗?标签?如何在它们之间添加/切换?我建议在片段中使用加载视图,而不是DialogFragment;还可以使用加载程序而不是异步任务来加载数据。(这将正确处理方向更改)@kcopock我已使用代码编辑。谢谢你的加载器,我不知道。我已经用我的代码更新了。是的,我用的是可视寻呼机。我在其他应用程序中使用过回调和接口,但这并不能解决我的问题,不是吗?问题是在显示片段时启动异步任务,而不是在加载片段时启动,而是在“隐藏”片段时启动。谢谢你的帮助time@Adrian更新了代码中的答案。我没有试过,但我认为这应该行得通。我只有一个问题。我不知道为什么在onPostExecute中我必须使用runOnUiThread来避免应用程序崩溃,但在onPreExecute中却不行。谢谢