当前位置: 首页 > 知识库问答 >
问题:

显示片段时启动asynctask

丁经国
2023-03-14

我有3个碎片。

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

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

每个片段都有自己的AsyncTask。

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

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

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>

在每个片段的布局中,我添加了另一个布局,里面有一个进度条和一个文本视图。在onResume中,我隐藏了listView,并用进度条和文本视图显示了布局。另外,我在asynctask的onPreexecute中也做了同样的工作(我认为只有在这一点上应该可以,因为在onResume中我启动了asynctask(但我只是在测试哈哈))。在postExecute中,如果我有数据要显示,我会隐藏进度条和textview,并显示列表视图。一个重要的事情是在UI线程上这样做,如果不是,我会得到下一个错误:“只有创建视图层次结构的原始线程可以接触它的视图。”

getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // lv.setVisibility(View.VISIBLE);
                    if (listPointsSearch == null) {
                        adapter = new ListAdapterShowPoints(act, listPoints,
                                act);
                    } else {
                        adapter = new ListAdapterShowPoints(act,
                                listPointsSearch, act);
                    }
                    adapter.setActivity(act);

                    setListAdapter(adapter);

                    lv.setVisibility(View.VISIBLE);
                    pRelativeLayout.setVisibility(View.GONE);
                }
            });

但是只有我在onPostExecute()中有这个问题。当一个片段被恢复但你没有看到它时,它工作正常,我不知道为什么,因为在onPreExecute中应该崩溃。

编辑3:我也应该用加载器来测试,而不是AsyncTasks。

共有1个答案

东方辉
2023-03-14

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

我想说,您最好使用在片段更改时调用的回调函数来启动AsyncTask。您可以有一个接口,由您的片段实现,并在从一个片段更改到新片段时调用。

编辑:代码中的更多信息

public interface OnFragmentShownListener {
    void onFragmentShown();
}

然后,仍然在onPageSelected中调用((OnFragmentShownListener)片段).onfragmentShow(),这将启动AsyncTask。

希望这有所帮助:)

 类似资料:
  • $ gdb GNU gdb (GDB) 7.7.50.20140228-cvs Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are f

  • 我有方法: 将图像添加到我的recyclerview。如果它在活动中,我会在OnCreate中调用initImageBitmaps()。不幸的是,我必须在片段中使用它,问题是:如何将这些方法实现到扩展片段的类?当然,所有内容都将显示在RecyclerView中,并带有xml中的recycler\u视图id。 编辑:我的适配器: 它仅在注释mContext=context时编译 在适配器中。那么错误

  • 我在xml文件中有一个主容器,我将根据按钮点击替换其中的片段。 当活动打开时,我正在使用以下代码将碎片1添加到主容器 在HomeMainFragment中,单击一个按钮,执行以下操作。 在Fragment2中,单击另一个按钮,使用以下代码移动到Fragment3。 现在,当我单击后退时,我的UI应该显示HomeFragment,而不是显示home以及合并在一起的fragment3。 只是想明确我的

  • 那么DialogFragments有什么特别之处呢?为什么在显示对话框时没有暂停调用片段?又如何实现呢? 我在文档中没有发现任何关于这种行为的引用,所以引用是一个加号。

  • 在我的舱单中: 主要活动

  • 启动时,控制台显示没有错误: 自动打开的页面显示如下: 我还尝试了,显示了相同的输出。 而且很有效。