【问题标题】:Launch Service in setUserVisibleHint在 setUserVisibleHint 中启动服务
【发布时间】:2020-05-19 13:00:50
【问题描述】:

我正在尝试使用 FragmentViewPagerTabLayout。 现在我在片段中启动服务命令时遇到问题。

我有我的服务:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
  ....
}

我希望当我在 TabLayout 中更改选项卡时,所选片段会发出服务请求。

所以我试过这个:

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        Bundle extras = new Bundle();
        Intent msgIntent = new Intent(getActivity(), myService.class);
        msgIntent.setAction("INIT_REQUEST");
        msgIntent.putExtra("id", sectionNumber);
        msgIntent.putExtras(extras);
        getActivity().startService(msgIntent);

    }

但问题是在 getActivity() 中抛出一个异常,因为它为空:

原因:java.lang.NullPointerException:尝试调用虚拟 方法'java.lang.String android.content.Context.getPackageName()' 空对象引用

我哪里错了?

【问题讨论】:

  • viewPager 总是只加载当前之前的一个片段。因此,假设您有 3 个片段,而您是第一个片段。现在,当您转到第二个片段时,setUserVisibleHint 不会为空,因为该片段已经加载,但是当您从第一个片段转到第三个片段时,它将通过您的异常,因此您可以放心地打赌它启动片段的 onCreate 服务。
  • 谢谢,所以如果我不明白你所说的,我会用一个简单的 if(getActivity() != null) 解决
  • 通过使用 if(getActivity() != null) 你的应用程序不会崩溃,但你仍然会得到 null。因此,为避免您需要在片段的 onCreate 或 onAttach() 中运行服务。

标签: android android-fragments


【解决方案1】:

viewPager 总是只加载一个fragment 领先于当前。因此,假设您有 3 个fragments,而您是第一个。现在,当您转到第二个片段时 setUserVisibleHint 不会为空,因为 fragment 已经加载,但是当您从第一个片段转到第三个片段时,它将抛出异常,因此您可以放心地启动服务 @987654327片段的@ 或者您也可以在片段的onAttach() 中执行此操作。

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
          Bundle extras = new Bundle();
    Intent msgIntent = new Intent(getActivity(), myService.class);
    msgIntent.setAction("INIT_REQUEST");
    msgIntent.putExtra("id", sectionNumber);
    msgIntent.putExtras(extras);
    getActivity().startService(msgIntent);
    }

并在使用时检查您的活动是否为空。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
 if (((MainActivity) getActivity() != null) {
    Bundle extras = new Bundle();
    Intent msgIntent = new Intent(getActivity(), myService.class);
    msgIntent.setAction("INIT_REQUEST");
    msgIntent.putExtra("id", sectionNumber);
    msgIntent.putExtras(extras);
    getActivity().startService(msgIntent);
  }
}

也看看这个答案。它可能会帮助你。 setUserVisibleHint() throwing NullPointerException when calling getActivity()

【讨论】:

  • @LorenzoBerti 是的,当您从 tab1 转到 tab2 时,tab2 已经加载,因此不会调用 onAttach()。所以这就是为什么我说使用 onCreate() 并检查 setUserVisibleHint() 如果它为空,那么服务可以通过 onCreate() 运行。
  • 我用过这种方法。在附加时,我总是为任何片段调用服务,但是,在它不起作用之前,我为片段部分发送个人广播,因为我为所有片段注册了唯一的广播,所以当 tab1 发送广播以将数据从服务发送到片段时, 事件 tab2 得到相同的数据。所以我在我的服务中对广播接收器的逻辑进行了简单的更改
  • 好像是这样!我会测试,但现在,似乎工作!
【解决方案2】:

ViewPager.OnPageChangeListener 添加到您的ViewPager 并覆盖onPageSelected。您可以从那里向您的服务发送命令。

此外,如果您有少量不是很重的片段,您可以在 ViewPager 上调用setOffsPageLimit(int limit) 以在内存中保留更多片段,这应该避免使用NullPointerException

注意:这也取决于您的寻呼机适配器实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 2019-08-23
    • 2017-11-24
    • 2018-04-02
    • 2016-09-08
    相关资源
    最近更新 更多