Android GCM Sending token to server

2019-07-11 03:37发布

问题:

The GCM Sample Project gives a stubbed out example of sending a GCM token to your server:

public class RegistrationIntentService extends IntentService {

    ...

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            ...
            String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
                    GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

            Log.i(TAG, "GCM Registration Token: " + token);

            // TODO: Implement this method to send any registration to your app's servers.
            sendRegistrationToServer(token);
            ...
        } catch (Exception e) {
            ...
        }
    }

    /**
     * Persist registration to third-party servers.
     *
     * Modify this method to associate the user's GCM registration token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationToServer(String token) {
        // Add custom implementation, as needed.
    }
}

but this is done in an IntentService which finishes as soon as onHandleIntent returns right? So if starting an http call to send the token with the popular android-async-http library, I'm not even seeing my onStart hit:

private void sendRegistrationToServer(String token) {
    post("/devices", params, new AsyncHttpResponseHandler() {
        // TODO: MAKE SURE ONSTART ACTUALLY CALLED TO MAKE SURE REQUEST AT LEAST GOES UPSTREAM EVEN IF I DON'T RECEIVE A CALLBACK SINCE IN INTENTSERVICE
        // IF NOT THEN MIGHT HAVE TO CHANGE THE INTENTSERVICE TO A SERVICE FOR DEVICE REGISTRATION
        @Override
        public void onStart() {
            // not actually using callback because request sent from intentservice
            Log.d("tagzzz", "sending upstream");
        }

        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
            // not actually using callback because request sent from intentservice
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
            // not actually using callback because request sent from intentservice
        }
    });
}

Will my http request even be sent upstream before onHandleIntent returns and finishes the IntentService? If not, why does Google give this as their example for sending your token to your server?

回答1:

Will my http request even be sent upstream before onHandleIntent returns and finishes the IntentService?

Given that you are using a library named "android-async-http", I would assume that the default behavior is for it to execute the HTTP asynchronously. It is indeterminate whether or not the post() call will complete its work before onHandleIntent() returns, but it seems unlikely.

why does Google give this as their example for sending your token to your server?

Google doesn't. Google has a stub sendRegistrationToServer(), as you can see in your first code listing. I am not aware of any Google examples that use the "android-async-http" library.

You decided to use an asynchronous mechanism for sending that HTTP request. That is an inappropriate choice for inside an IntentService. Now, perhaps that library has a synchronous option, in which case you could switch to that. Otherwise, use something else synchronous for the HTTP request (HttpURLConnection, OkHttp3, etc.) from the IntentService.

Note that Volley is not a great choice here, insofar as Volley is also strongly tilted towards asynchronous work.