Периодический сбой аутентифицированной облачной конечной точки в клиенте Android

У меня есть приложение в производстве, которое получает значительное количество принудительных / закрытий при вызове аутентифицированной конечной точки облака. Самое выразительное сообщение " java.lang.IllegalArgumentException: служба не зарегистрирована: [email protected] ", Логика работает правильно в 95% случаев. Трассировка стека ошибки выглядит следующим образом:

java.lang.RuntimeException: произошла ошибка при выполнении doInBackground () в android.os.AsyncTask $ 3.done (AsyncTask.java:200) в java.util.concurrent.FutureTask $ Sync.innerSetException (FutureTask.java:273 at) java.util.concurrent.FutureTask.setException (FutureTask.java:124) в java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask.java:307) в java.util.concurrent.FutureTask.run (FutureTask.j 137) в java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1068) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:561) в java.lang.Threadjr : 1096) Вызывается: java.lang.IllegalArgumentException: служба не зарегистрирована: [email protected] в android.app.ActivityThread $ PackageInfo.forgetServiceDispatcher (ActivityThread.java:1074) в android.app .ContextImpl.unbindService (ContextImpl.java:886) на android.content.ContextWrapper.unbindService (ContextWrapper.java:352) на com.google.android.gms.auth.GoogleAuthUt il.java.lang.String getToken (android.content.Context, java.lang.String, java.lang.String) (неизвестный источник) в 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.innerun (FutureTask.java:305) на com.google.android.gms.auth.GoogleAuthUtil.java.lang.String getToken (android.content.Context, java.lang.String, java.lang.String) (неизвестный источник) в 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. Строка getToken () (SourceFile: 192) по адресу com.google.api.client.googleapis.extensions.android.gm s.auth.GoogleAccountCredential $ RequestHandler.void intercept (com.google.api.client.http.HttpRequest) (SourceFile: 217) на com.google.api.client.http.HttpRequest.com.google.api.client.http .HttpResponse execute () (SourceFile: 836) по адресу com.google.api.client.googleapis.services.AbstractGoogleClientRequest.com.google.api.client.http.HttpResponse executeUnparsed (логическое значение) (SourceFile: 412) в com.google. api.client.googleapis.services.AbstractGoogleClientRequest.com.google.api.client.http.HttpResponse executeUnparsed () (SourceFile: 345) по адресу com.google.api.client.googleapis.services.AbstractGoogleClientRequgg.bject () (SourceFile: 463) в com.jdub.empiretracker.EmpireTrackerActivity $ QueryMarketStats.com.google.api.services.marketendpoint.model.Market doInBackground (com.google.api.services.marketendpoint.model.Market []) ( SourceFile: 355) на com.jdub.empiretracker.EmpireTrackerActivity $ QueryMarketStats.java.lang.Object doInBackground (java.lang.Object []) (SourceFile: 1) на android.os.AsyncTask $ 2.call (AsyncTask.java:185) на java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask.java:305) ... еще 4

Моя реализация очень соответствует образцам Google. Например, в Android я использую AsyncTask для совершения звонка следующим образом:

    private class QueryMarketStats extends AsyncTask {

    /* (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;
}

Что еще может вызвать этот прерывистый сбой? Это известная проблема?

Ответы на вопрос(1)

Вместо лучшей альтернативы я ловлю исключение и запускаю попытку с успехом. Независимо от того, какая непостоянная проблема приводит к тому, что служба не регистрируется в момент вызова конечной точки, будущие вызовы службы работают должным образом.

Обходной кодекс}

@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);
}       

Ваш ответ на вопрос