Android 在应用程序启动时预加载一些片段

Android 在应用程序启动时预加载一些片段,android,fragment,navigation-drawer,Android,Fragment,Navigation Drawer,我有一个带导航抽屉的Android应用程序。我的问题是,一些片段需要几秒钟来加载解析器MapAPI。我想在应用程序启动时加载我的所有片段 我不确定这是否可能或是一个好的方法,但我正在考虑在主活动的onCreate方法中创建我的每个片段的实例。然后,当用户在导航抽屉中选择一个片段时,我使用现有实例,而不是创建一个新实例 问题在于,当我第一次展示一个特定片段时,它并不能阻止延迟。在我看来,原因是片段构造函数没有执行很多操作 在搜索web之后,我找不到一种优雅的方法在应用程序启动时预加载片段,而不是在

我有一个带导航抽屉的Android应用程序。我的问题是,一些片段需要几秒钟来加载解析器MapAPI。我想在应用程序启动时加载我的所有片段

我不确定这是否可能或是一个好的方法,但我正在考虑在主活动的onCreate方法中创建我的每个片段的实例。然后,当用户在导航抽屉中选择一个片段时,我使用现有实例,而不是创建一个新实例

问题在于,当我第一次展示一个特定片段时,它并不能阻止延迟。在我看来,原因是片段构造函数没有执行很多操作

在搜索web之后,我找不到一种优雅的方法在应用程序启动时预加载片段,而不是在用户选择抽屉中的项目时

一些帖子谈到了AsyncTask,但看起来MapFragment操作无法执行,除非在主线程中。我尝试时遇到了一个异常:java.lang.IllegalStateException:不在主线程上

以下是我到目前为止所做的尝试:

mFragments = new Fragment[BasicFragment.FRAGMENT_NUMBER];
mFragments[BasicFragment.HOMEFRAGMENT_ID] = new HomeFragment();
mFragments[BasicFragment.CAFEFRAGMENT_ID] = new CafeFragment();
mFragments[BasicFragment.SERVICEFRAGMENT_ID] = new ServiceFragment();
mFragments[BasicFragment.GOOGLEMAPFRAGMENT_ID] = new GoogleMapFragment();
在导航抽屉中选择项目时:

private void selectItem(int position) {

    Fragment fragment = mFragments[position];

    // here, I check if the fragment is null and instanciate it if needed

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.replace(R.id.content_frame, fragment);
    ft.commit();

    mDrawerList.setItemChecked(position,true);
    mDrawerLayout.closeDrawer(mDrawerList);
}
我也试过了;它允许阻止一个片段被加载两次或更多,但它不能阻止我的应用程序在第一次显示它时延迟。这就是为什么我尝试在应用程序开始使用启动屏幕或其他东西时加载所有片段,以防止进一步的延迟


感谢您的帮助/建议。

您可以做的一件事是在FragmentonCreateView中返回null,以无UI的片段加载资源。您还可以调用FragmentsetRetainInstancetrue以防止片段被销毁

这可以添加到ActivityonCreate中的FragmentManager中。从那里,您添加的片段可以挂接到此资源片段,以获得所需的资源

比如说:

public class ResourceFragment extends Fragment {
   public static final String TAG = "resourceFragment";

   private Bitmap mExtremelyLargeBitmap = null;

   @Override
   public View onCreateView(ViewInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     return null;
  }

  @Override
  public void onStart() {
     super.onStart();
     new BitmapLoader().execute();
  }

  public Bitmap getExtremelyLargeBitmap() {
     return mExtremelyLargeBitmap;
  }

  private class BitmapLoader extends AsyncTask<Void, Void, Bitmap> {
      @Override
      protected Bitmap doInBackground(Void... params) {
          return decodeBitmapMethod();
      }

      @Override
      protected void onPostExecute(Bitmap result) {
          mExtremelyLargeBitmap = result;
      }
  }
}
您可能需要设置一个注册/取消注册侦听器,因为您仍然需要等待资源加载,但是您可以尽快开始加载资源,而不必首先创建一堆片段。

要预加载片段,可以使用“附加”。因此,在OP的情况下,它将是:

ft.attach(fragment).commit();

请确保将片段存储在某个位置,并在下次调用ft.replace时使用该片段。

您可以将片段放入ViewPager中。默认情况下,它预加载2个页面片段。您还可以增加预加载页面片段的数量

mViewPager.setOffscreenPageLimit(int numberOfPreloadedPages);

不过,您需要重写showFragment方法并重写回栈逻辑。

谢谢您的帮助,但加载视图时,如果将自定义listview中的~40个元素膨胀,则可能会导致延迟,因此我无法使用您的解决方案绕过它。。。
mViewPager.setOffscreenPageLimit(int numberOfPreloadedPages);