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

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

翁阳曜
2023-03-14

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

我不确定这是否可能或是一个好方法,但我正在考虑在主活动的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);
}

我也尝试了这个解决方案;它允许防止一个片段被加载两次(或更多),但它不会阻止我的应用程序在第一次显示时延迟。这就是为什么我尝试在应用程序启动时加载所有片段(使用启动屏幕或其他方式),以防止进一步的延迟。

谢谢你的帮助/建议。

共有3个答案

薛墨一
2023-03-14

要预加载片段,可以使用附加()。所以在OP的情况下,它将是:

ft.attach(fragment).commit();

确保将片段存储在某处,并在下次调用时使用该片段。

金谭三
2023-03-14

您可以做的一件事是通过在片段#onCreateView()中返回null来加载无UI片段中的资源。您还可以调用#setRetainInstance(true),以防止片段被破坏。

这可以添加到Active#onCreate()中的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;
      }
  }
}

首先将其添加到活动中的片段管理器。然后,无论何时加载其他片段,它们只需从片段管理器中获取资源片段,如下所示:

public class FakeFragment extends Fragment {

   @Override
   public View onCreateView(ViewInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final ResourceFragment resFragment = getFragmentManager().findFragmentByTag(ResourceFragment.TAG);
        Bitmap largeBitmap = resFragment.getBitmap();
        if (largeBitmap != null) {
            // Do something with it.
        }
   }
}

您可能需要设置一个“注册/取消注册”侦听器,因为您仍然需要等待资源加载完成,但您可以尽快开始加载资源,而无需首先创建一堆片段。

闽朝
2023-03-14

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

mViewPager.setOffscreenPageLimit(int numberOfPreloadedPages);

但是,您将需要重写您的show片段方法并重写回堆栈逻辑。

 类似资料:
  • 我试图集成一个旧的weblogic应用程序来使用Okta SSO saml2.0流。我已经成功地使用@ServletCompenentScan将应用程序与Spring Boot集成,并且能够成功地使用Spring Security性进行基本身份验证。但是,当将特定于SAML的配置添加到SecurityConfiguration时,应用会在部署时失败。对于okta saml,我遵循这个教程https

  • 我正在尝试集成一个旧的weblogic应用程序来使用Okta SSO SAML2.0流。我已经使用@ServletCompenentScan成功地将应用程序与spring boot集成,并且能够成功地使用spring security进行基本身份验证。但是,当向SecurityConfiguration添加特定于SAML的配置时,应用程序在部署时会失败。关于okta saml,我将遵循本教程htt

  • 这是我的第一个问题。我一路寻找,尝试了很多,但没有得到我想做的。问题是:我有一个应用程序使用SoundPool播放声音,仅此而已。但是要加载的东西很多(>50),一个一个加载需要时间。看一看; @Override公共视图onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){View V

  • 我有一个jar实用程序,可以实现一些功能。我将jar作为依赖项添加到maven应用程序中。它使用简单的java。我希望jar中的一个类在应用程序启动时运行。我们怎么能做到?

  • 我的的一个有一个奇怪的问题。我有一个,里面有三个。到现在为止一切正常。当应用程序启动时,(带有)附加了三个片段,这样我就可以毫无问题地从一个浏览到另一个。当我尝试像这样手动(注销后)重新启动应用程序时,问题就来了: 现在,当我注销和应用程序重新启动时,应用程序崩溃,并通过一个试图从片段上访问资源。 下面是我附加的代码,即: 然后,设置:

  • 问题内容: 我有一个Java应用程序。 该应用程序具有一个设置,该设置决定该应用程序是否在启动时启动。 目前,我可以通过在“启动项目”文件夹中放置/删除快捷方式来实现此目的。 但是,我想知道是否有更好的方法来处理此行为。 编辑 是的,它是Windows。抱歉,之前没有清除该内容。 该应用程序具有一个用户可以在其中触发动作的UI,并且该应用程序在运行时会定期在后台运行一些任务。 @Peter,如何在