【问题标题】:Getting "Already managing a GoogleApiClient with id 0" exception when using TabLayout Viewpager使用 TabLayout Viewpager 时出现“已在管理 id 为 0 的 GoogleApiClient”异常
【发布时间】:2017-02-09 13:29:46
【问题描述】:

我想使用 TabLayout ViewPager Fragments 集成 Google 注册。 ViewPager 包含两个片段 LoginFragment 和 RegistrationFragment 并且都包含“Google 注册”按钮。

问题是我在启动活动时遇到以下错误。

java.lang.IllegalStateException:已经在管理 GoogleApiClient id 为 0

完整的错误日志-

java.lang.IllegalStateException: Already managing a GoogleApiClient with id 0
at com.google.android.gms.common.internal.zzac.zza(Unknown Source)
at com.google.android.gms.internal.zzzt.zza(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.zzf(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source)
at com.naturesouq_shopping.fragment.RegistrationFragment.buildGoogleApiClient(RegistrationFragment.java:174)
at com.naturesouq_shopping.fragment.RegistrationFragment.getIds(RegistrationFragment.java:140)
at com.naturesouq_shopping.fragment.RegistrationFragment.onCreateView(RegistrationFragment.java:85)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2184)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1298)
at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1969)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:620)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1642)
at android.view.View.measure(View.java:20236)

我正在尝试以下代码

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

 // Configure sign-in to request the user's ID, email address, and basic
 // profile. ID and basic profile are included in DEFAULT_SIGN_IN.
        gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .build();

        buildGoogleApiClient();

     // .....
 }

private synchronized void buildGoogleApiClient() {
    /** build_client */
   try {
       mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
               .enableAutoManage(getActivity() /* FragmentActivity */, this /* OnConnectionFailedListener */)
               .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
               .build();
   } catch (Exception e) {
       e.printStackTrace();
   }
}

@Override
public void onStart() {
    super.onStart();
    if (mGoogleApiClient != null) {
        mGoogleApiClient.connect();
    } 

}

@Override
public void onStop() {
    Log.d("GARG", "***** on Stop ***** ");
    if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
        Log.d("GARG", "***** on Stop mGoogleApiClient disconnect ***** ");

        mGoogleApiClient.stopAutoManage(getActivity());
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

还有其他方法可以连接 Google API 客户端吗? 知道我在哪里做错了和正确的方法吗?

【问题讨论】:

    标签: android android-fragments google-api-client


    【解决方案1】:

    我认为您正在尝试通过已构建和连接的 googleApiClient 构建和连接。这可能会解决您的问题:

    if(mGoogleApiClient == null || !mGoogleApiClient.isConnected()){
     try {
       mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
               .enableAutoManage(getActivity() /* FragmentActivity */, this /* OnConnectionFailedListener */)
               .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
               .build();
     } catch (Exception e) {
       e.printStackTrace();
     }
    }
    

    【讨论】:

    • 这种方法的问题是,当 RegistrationFragment 尝试获取已由 LoginFragment 构建和连接的 GoogleApiClient 时,它只会静默失败,如果稍后在 RegistrationFragment 中有使用 mGoogleApiClient 的代码,它会抛出一个 NPE。
    • 只是想针对具体问题。当我研究 OP 的代码时,我相信这就是漏洞所在。
    • 你的代码很好,因为它解决了 OP 代码的问题,但更好的代码可以避免产生未来的问题。
    【解决方案2】:

    official doc for enableAutoManage 这么说:

    在任何给定时间,每个 ID 只允许一个自动管理的客户端。要重用 id,您必须首先在前一个客户端上调用 stopAutoManage(FragmentActivity)。

    您的代码使用的是不带 clientId 参数的 enableAutoManage 版本,因此默认为 0。下面我将解释为什么您将为 clientId 0 拥有多个自动管理的客户端,这是上述文档所警告的。

    在您的一个 Fragment 附加到 FragmentActivity 后,它会通知该 Activity 开始管理 GoogleApiClient 的新实例。但是如果 FragmentActivity 已经在管理另一个 GoogleApiClient 实例呢?那是你得到错误的时候。

    在您的情况下,包含 ViewPager 的 FragmentActivity 被要求管理两个不同的 GoogleApiClients,一个来自 RegistrationFragment,一个来自 LoginFragment。根据堆栈跟踪,FragmentActivity 首先开始管理 LoginFragment 的 GoogleApiClient,然后在您要求它管理 RegistrationFragment 的 GoogleApiClient 时崩溃。

    您可以尝试一些方法:

    • 将两个不同的 clientId 传递给 enableAutoManage,一个用于 LoginFragment,另一个用于 ReservationFragment。
    • 找出需要调用 stopAutoManage 的位置。这对于 ViewPager 中的 Fragments 可能会很棘手。
    • 如果我是你,我会认真考虑在包含 ViewPager 的 FragmentActivity 中而不是在 RegistrationFragment 和 LoginFragment 中创建 GoogleApiClient。然后,您可以在 Activity 中执行需要 GoogleApiClient 的工作,或者在从 Activity 获取 GoogleApiClient 后继续在两个 Fragment 中执行此操作,如下所示:

    私有的 GoogleApiClient googleApiClient;

      @Override
      void onAttach(Activity activity) {
          super.onAttach(activity);
          googleApiClient = activity.getGoogleApiClient();
      }
    
      @Override
      void onDetach() {
          super.onDetach();
          googleApiClient = null;
      }
    

    【讨论】:

      【解决方案3】:

      只是改变 enableAutoManage(getActivity() , this)

      到 enableAutoManage(getActivity(),1, this)

      【讨论】:

        猜你喜欢
        • 2018-05-28
        • 1970-01-01
        • 2018-09-18
        • 1970-01-01
        • 2017-01-10
        • 2017-06-13
        • 1970-01-01
        • 1970-01-01
        • 2019-01-07
        相关资源
        最近更新 更多