我有3个片段。
在每个片段的onActivityCreated()中,我执行异步任务。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mTaskGetPoints = new AsyncTaskGetFavouritePoints();
mTaskGetPoints.execute();
}
doInBackground中的异步任务从SQLite DB获取数据并创建对象的ArrayList。在onPostExecute中,我调用一个方法在listView上显示数据。
每个片段都有自己的asynctask。
当我"启动" FragmentActivity显示片段1并执行其asynctask。但它最近的片段(片段2,中间片段)也会启动其AsyncTask。
我想知道是否可以仅在用户看到片段时才启动异步任务。 我想如果可能,因为我想显示一个进度对话框(获取数据......)。 现在我从数据库中获取的数据很少,但如果我有很多数据,我想显示进度对话框。现在,如果我在每个asynctask的onPreExecute中显示ProgressDialog,如果从Fragment 1更改为Fragment 2,我在Fragment 2上看到Fragment 3的ProgressDialog:/
也许我错了,使用asynctasks很糟糕。
编辑1: FragmentActivity
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>
编辑2(我的解决方案): 我用了一些更简单的东西。
在每个片段的布局中,我在内部添加了另一个布局,其中包含进度条和文本视图。在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进行测试。
答案 0 :(得分:0)
问题在于,取决于你用什么来改变你的碎片(从你所说的,我认为你使用的是ViewPager
,不是吗?),它会在显示它们之前缓存片段对于用户来说,加载UI并不会很长。
我会说你最好使用片段更改时调用的回调启动AsyncTask
。您可以拥有一个由Fragments实现的接口,并在您从一个片段更改为新片段时调用。
修改:您的代码中的更多信息
首先,创建一个由Fragments实现的简单回调接口,它将启动AsyncTask。
public interface OnFragmentShownListener {
void onFragmentShown();
}
然后,在SimpleOnPageChangeListener#onPageSelected
上,致电mInterestPointsPagerAdapter.getItem(position)
以检索显示的片段。
然后,仍然在你的onPageSelected中,你调用你的((OnFragmentShownListener) fragment).onFragmentShown()
,它应该启动你的AsyncTask。
希望这会有所帮助:)