GoogleApiClient.Builder.enableAutoManage in Fragment throws IllegalStateException: Recursive entry to executePendingTransactions
GoogleApiClient.Builder.enableAutoManage in Fragment throws IllegalStateException: Recursive entry to executePendingTransactions
我有一个 AppCompatActivity
,它有 3 个使用 FragmentTabHost
的选项卡。其中一个选项卡使用 LocationServices
。我想要最流畅的用户体验:
如果 LocationService
在 android 系统中关闭,并且 仅当 用户选择需要 Location
的选项卡时想显示 AlertDialog
让用户在系统设置中打开 Location
。
我有一个助手 class 可以完成所有这些工作,它在我的应用程序的其他 3 个地方也能正常工作。在这 3 个地方,它在 Activity
中工作 "directly",但是在这个地方它需要在选项卡的 Fragment
中工作 "within"。
问题是如果我有这条线:
builder.enableAutoManage(activity, 0, this);
然后builder.build()
抛出异常:IllegalStateException: Recursive entry to executePendingTransactions
知道如何实现我的目标吗?
这里是一些相关的代码片段:
public class CityPreferences extends AppCompatActivity {
private FragmentTabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(
mTabHost.newTabSpec("available_cities")
.setIndicator(getString(R.string.tab_all_cities))
, AvailableCityFragment.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("nearby_cities")
.setIndicator(getString(R.string.tab_nearby_cities))
, NearbyCityFragment.class, null);
}
}
在 NearbyCityFragment
我有这 1 行代码:
class NearbyCityFragment extends Fragment {
...
LocationServiceHelper.getInstance().startOrDisplayDialog(getActivity());
(我在onAttach
、onStart
、onResume
中试过了)
这是我的助手 class' 函数:
public class LocationServiceHelper implements
GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks {
public boolean startOrDisplayDialog(@NonNull final FragmentActivity activity) {
final boolean servicesConnected = GooglePlayServicesHelper.checkOrDisplayDialog(activity);
if (servicesConnected) {
final boolean isEnabled = isLocationEnabledInSystem(activity);
if (isEnabled) {
if (null == mGoogleApiClient) {
mContext = activity;
mActivity = activity;
final GoogleApiClient.Builder builder = new GoogleApiClient.Builder(mContext)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this);
// the next line seems to cause the problem:
builder.enableAutoManage(activity, 0, this);
mGoogleApiClient = builder
.build();
}
return start();
} else {
final Dialog dialog = getLocationDisabledDialog(activity);
GooglePlayServicesHelper.showDialog(dialog, activity);
}
}
return false;
}
最后是例外:
06-10 10:23:04.831 26725-26725/com.fletech.android.redalert.debug E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.fletech.android.redalert.debug, PID: 26725
java.lang.IllegalStateException: Recursive entry to executePendingTransactions
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1473)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
at com.google.android.gms.common.api.g.a(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.gI(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source)
at com.fletech.android.redalert.helper.LocationServiceHelper.startOrDisplayDialog(LocationServiceHelper.java:113)
at com.fletech.android.redalert.city.NearbyCityFragment.onAttach(NearbyCityFragment.java:44)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:907)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
我相信您每次启用自动管理器时都必须使用唯一的 clientId
。来自 documentation:
clientId
- A non-negative identifier for this client. At any given time, only one auto-managed client is allowed per id. To reuse an id you must first call stopAutoManage(FragmentActivity)
on the previous client.
我有一个 AppCompatActivity
,它有 3 个使用 FragmentTabHost
的选项卡。其中一个选项卡使用 LocationServices
。我想要最流畅的用户体验:
如果 LocationService
在 android 系统中关闭,并且 仅当 用户选择需要 Location
的选项卡时想显示 AlertDialog
让用户在系统设置中打开 Location
。
我有一个助手 class 可以完成所有这些工作,它在我的应用程序的其他 3 个地方也能正常工作。在这 3 个地方,它在 Activity
中工作 "directly",但是在这个地方它需要在选项卡的 Fragment
中工作 "within"。
问题是如果我有这条线:
builder.enableAutoManage(activity, 0, this);
然后builder.build()
抛出异常:IllegalStateException: Recursive entry to executePendingTransactions
知道如何实现我的目标吗?
这里是一些相关的代码片段:
public class CityPreferences extends AppCompatActivity {
private FragmentTabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(
mTabHost.newTabSpec("available_cities")
.setIndicator(getString(R.string.tab_all_cities))
, AvailableCityFragment.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("nearby_cities")
.setIndicator(getString(R.string.tab_nearby_cities))
, NearbyCityFragment.class, null);
}
}
在 NearbyCityFragment
我有这 1 行代码:
class NearbyCityFragment extends Fragment {
...
LocationServiceHelper.getInstance().startOrDisplayDialog(getActivity());
(我在onAttach
、onStart
、onResume
中试过了)
这是我的助手 class' 函数:
public class LocationServiceHelper implements
GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks {
public boolean startOrDisplayDialog(@NonNull final FragmentActivity activity) {
final boolean servicesConnected = GooglePlayServicesHelper.checkOrDisplayDialog(activity);
if (servicesConnected) {
final boolean isEnabled = isLocationEnabledInSystem(activity);
if (isEnabled) {
if (null == mGoogleApiClient) {
mContext = activity;
mActivity = activity;
final GoogleApiClient.Builder builder = new GoogleApiClient.Builder(mContext)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this);
// the next line seems to cause the problem:
builder.enableAutoManage(activity, 0, this);
mGoogleApiClient = builder
.build();
}
return start();
} else {
final Dialog dialog = getLocationDisabledDialog(activity);
GooglePlayServicesHelper.showDialog(dialog, activity);
}
}
return false;
}
最后是例外:
06-10 10:23:04.831 26725-26725/com.fletech.android.redalert.debug E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.fletech.android.redalert.debug, PID: 26725
java.lang.IllegalStateException: Recursive entry to executePendingTransactions
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1473)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
at com.google.android.gms.common.api.g.a(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.gI(Unknown Source)
at com.google.android.gms.common.api.GoogleApiClient$Builder.build(Unknown Source)
at com.fletech.android.redalert.helper.LocationServiceHelper.startOrDisplayDialog(LocationServiceHelper.java:113)
at com.fletech.android.redalert.city.NearbyCityFragment.onAttach(NearbyCityFragment.java:44)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:907)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
我相信您每次启用自动管理器时都必须使用唯一的 clientId
。来自 documentation:
clientId
- A non-negative identifier for this client. At any given time, only one auto-managed client is allowed per id. To reuse an id you must first callstopAutoManage(FragmentActivity)
on the previous client.