4

我有一个生产中的应用程序在调用经过身份验证的 Cloud Endpoint 时收到大量强制/关闭。最能说明问题的是“java.lang.IllegalArgumentException: Service not registered: com.google.android.gms.internal.es@4481e6a8”。逻辑在 95% 的时间内都能正常工作。失败的堆栈跟踪如下:

java.lang.RuntimeException:在 java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 的 android.os.AsyncTask$3.done(AsyncTask.java:200) 处执行 doInBackground() 时发生错误java.util.concurrent.FutureTask.setException(FutureTask.java:124) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 在 java.util.concurrent.FutureTask.run(FutureTask.java: 137) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 在 java.lang.Thread.run(Thread.java :1096)引起:java.lang.IllegalArgumentException:服务未注册:android.app.ActivityThread$PackageInfo.forgetServiceDispatcher(ActivityThread.java:1074)的com.google.android.gms.internal.es@4481e6a8在android。app.ContextImpl.unbindService(ContextImpl.java:886) 在 android.content.ContextWrapper.unbindService(ContextWrapper.java:352) 在 com.google.android.gms.auth.GoogleAuthUtil.java.lang.String getToken(android.content .Context,java.lang.String,java.lang.String)(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) at java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:305) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 在 com.google。 android.gms.auth.GoogleAuthUtil.java.lang.String getToken(android.content.Context,java.lang.String,java.lang.String)(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun( FutureTask.java:305) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 在 com.google.api.client.googleapis .extensions.android.gms.auth.GoogleAccountCredential.java.lang.String getToken()(SourceFile:192) at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.void intercept( com.google.api.client.http.HttpRequest)(SourceFile:217) at com.google.api.client.http.HttpRequest.com.google.api.client.http.HttpResponse execute()(SourceFile:836) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.com.google.api.client.http.HttpResponse executeUnparsed(boolean)(SourceFile:412) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.com .google.api.client.http。com.google.api.client.googleapis.services.AbstractGoogleClientRequest.java.lang.Object 的 HttpResponse executeUnparsed()(SourceFile:345) com.jdub.empiretracker.EmpireTrackerActivity$QueryMarketStats.com 的执行()(SourceFile:463)。 google.api.services.marketendpoint.model.Market doInBackground(com.google.api.services.marketendpoint.model.Market[])(SourceFile:355) at com.jdub.empiretracker.EmpireTrackerActivity$QueryMarketStats.java.lang.Object doInBackground(java.lang.Object[])(SourceFile:1) at android.os.AsyncTask$2.call(AsyncTask.java:185) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) ... 4 更多EmpireTrackerActivity$QueryMarketStats.com.google.api.services.marketendpoint.model.Market doInBackground(com.google.api.services.marketendpoint.model.Market[])(SourceFile:355) at com.jdub.empiretracker.EmpireTrackerActivity$QueryMarketStats .java.lang.Object doInBackground(java.lang.Object[])(SourceFile:1) at android.os.AsyncTask$2.call(AsyncTask.java:185) at java.util.concurrent.FutureTask$Sync.innerRun( FutureTask.java:305) ... 4 更多EmpireTrackerActivity$QueryMarketStats.com.google.api.services.marketendpoint.model.Market doInBackground(com.google.api.services.marketendpoint.model.Market[])(SourceFile:355) at com.jdub.empiretracker.EmpireTrackerActivity$QueryMarketStats .java.lang.Object doInBackground(java.lang.Object[])(SourceFile:1) at android.os.AsyncTask$2.call(AsyncTask.java:185) at java.util.concurrent.FutureTask$Sync.innerRun( FutureTask.java:305) ... 4 更多还有 4 个还有 4 个

我的实现与 Google 示例非常一致。例如,我的 Android 活动正在使用 AsyncTask 进行调用,如下所示:

    private class QueryMarketStats extends AsyncTask<com.google.api.services.marketendpoint.model.Market, com.google.api.services.marketendpoint.model.Market, com.google.api.services.marketendpoint.model.Market> {

    /* (non-Javadoc)
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected com.google.api.services.marketendpoint.model.Market doInBackground(com.google.api.services.marketendpoint.model.Market...markets) {

        com.google.api.services.marketendpoint.model.Market result = null;

        try {
            result = service.market().latest(state.getServerID()).execute();
        }
        catch (SSLException e) {
            PrimeDataStore();
            Log.d("app", e.getMessage(), e);
        }
        catch (GoogleAuthIOException e) {
            Log.d("app", e.getMessage(), e);
        }
        catch (IOException e) {
            Log.d("app", e.getMessage(), e);
        }

        return result;
    }

    /* (non-Javadoc)
     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
     */
    @Override
    protected void onPostExecute(com.google.api.services.marketendpoint.model.Market result) {

        // Process result...
    }

}

给出错误的行是: result = service.market().latest(state.getServerID()).execute();

我已验证 getServerID() 的参数返回的值是可接受的。在这一点上,我的理论是 Google Play 服务无法提供仍然经过身份验证的帐户。虽然我无法重现,但我相信当应用程序进入睡眠状态时可能会出现问题。因此,我确认了我的 onResume() 逻辑,如下所示:

    @Override
protected void onResume() {
    super.onResume();
    checkPlayServices();
    isInFront = true;
}

还有什么可能导致这种间歇性故障?这是一个已知的问题?

4

1 回答 1

2

In lieu of a better alternative, I am catching the exception and triggering a retry with success. Whatever intermittent issue is causing the service not to be registered at the point in time the endpoint is called, future invocations of the service work properly.

Work-around Code

@Override
protected com.google.api.services.marketendpoint.model.Market doInBackground(com.google.api.services.marketendpoint.model.Market...markets) {

    com.google.api.services.marketendpoint.model.Market result = null;

    try {
        result = service.market().latest(state.getServerID()).execute();
    }
    catch (SSLException e) {
        PrimeDataStore();
        Log(e);
    }
    catch (GoogleAuthIOException e) {
        Log(e);
    }
    catch (IOException e) {
        Log(e);
    }
    catch (IllegalArgumentException e) {
        // This caused a lot of intermittent force/closes.
        Log(e);
    }

    return result;
}

@Override
protected void onPostExecute(com.google.api.services.marketendpoint.model.Market result) {

    DismissProgressDialogIfPresent();

    com.google.api.services.marketendpoint.model.Market m = (com.google.api.services.marketendpoint.model.Market) result;

    if( m == null)
    {
        // Verify the current activity is active
        if( isInFront ) {

            // Present a retry/cancel dialog
            AlertDialog.Builder builder = new AlertDialog.Builder(EmpireTrackerActivity.this);
            builder.setMessage("An error was encountered retrieving the latest market data.\n\nPlease verify you are connected to the Internet.");
            builder.setPositiveButton("Retry", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();

                    m_ProgressDlg = ProgressDialog.show(EmpireTrackerActivity.this, "Please wait...", "Retrieving data ...", true);
                    new QueryMarketStats().execute();
                }
            });
            builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {

                    dialog.dismiss();
                }
            });
            AlertDialog alert = builder.create();
            alert.show();
        }

        return;
    }

    // Process newly posted data            
    state.setMarketObj(m);
    state.setIsInitialized(true);
    state.WriteFile(EmpireTrackerActivity.this);

    super.onPostExecute(result);
}       

}

于 2013-06-10T14:52:42.467 回答