Пример основной темы Google Cloud Messaging

У меня возникла проблема с примером обмена сообщениями Google Cloud to Device. Я следую инструкциям здесь (https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/GcmEndpoints), так как это были инструкции, данные Android Build при создании проекта. В соответствии с инструкциями я создал необходимые классы для регистрации и получения сообщений. Реестр был создан как AsyncTask и вызван из метода OnCreate моего основного приложения. Проблема, с которой я сталкиваюсь, заключается в том, что каждый раз, когда он запускается, я получаю IOException: MAIN THREAD. Я попытался изменить код на Runnable, но безуспешно, я просто получаю ту же ошибку. Все, что я прочитал в документации, говорит, что то, что я сделал, должно работать, поэтому я не могу понять, почему это не так.

Ниже приведен дамп Logcat, показывающий ошибку и трассировку стека.

10-19 13:04:21.637    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ java.io.IOException: MAIN_THREAD
10-19 13:04:21.637    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at com.google.android.gms.gcm.GoogleCloudMessaging.register(Unknown Source)
10-19 13:04:21.647    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at com.hillbilly.kidslauncher.GcmRegistrationAsyncTask.doInBackground(GcmRegistrationAsyncTask.java:75)
10-19 13:04:21.647    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at com.hillbilly.kidslauncher.MainActivity.onCreate(MainActivity.java:43)
10-19 13:04:21.657    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.app.Activity.performCreate(Activity.java:5008)
10-19 13:04:21.657    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
10-19 13:04:21.667    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
10-19 13:04:21.667    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
10-19 13:04:21.677    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.app.ActivityThread.access$600(ActivityThread.java:130)
10-19 13:04:21.677    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
10-19 13:04:21.677    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:99)
10-19 13:04:21.687    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.os.Looper.loop(Looper.java:137)
10-19 13:04:21.687    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:4745)
10-19 13:04:21.697    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
10-19 13:04:21.697    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
10-19 13:04:21.707    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-19 13:04:21.707    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-19 13:04:21.717    1291-1291/com.hillbilly.kidslauncher W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)

Любая помощь велика в полной мере.

В соответствии с запросом здесь приведен соответствующий код:

метод onCreate из основного действия:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_main);
    new GcmRegistrationAsyncTask().doInBackground(this);
}

Регистрационный класс

package com.hillbilly.kidslauncher;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import com.appspot.kidslauncherparent.registration.Registration;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
import com.google.api.client.googleapis.services.GoogleClientRequestInitializer;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Created by craighillbeck on 19/10/2014.
 */
public class GcmRegistrationAsyncTask extends AsyncTask<Context, Void, String> {
private GoogleCloudMessaging gcm;
    private Context context;
    private Registration regService = null;

    // TODO: change to your own sender ID to Google Developers Console project number, as per instructions above
    private static final String SENDER_ID = "978823093525";

    /**
     * Override this method to perform a computation on a background thread. The
     * specified parameters are the parameters passed to {@link #execute}
     * by the caller of this task.
     * <p/>
     * This method can call {@link #publishProgress} to publish updates
     * on the UI thread.
     *
     * @param params The parameters of the task.
     *
     * @return A result, defined by the subclass of this task.
     *
     * @see #onPreExecute()
     * @see #onPostExecute
     * @see #publishProgress
     */
    @Override
    protected String doInBackground(Context... params) {
        context = params[0];
        if (regService == null) {
            Registration.Builder builder = new Registration.Builder(
                    AndroidHttp.newCompatibleTransport(),
                    new AndroidJsonFactory(), null)
                    // Need setRootUrl and setGoogleClientRequestInitializer only for local testing,
                    // otherwise they can be skipped
                    .setRootUrl("http://10.0.2.2:8080/_ah/api/")
                    .setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
                        @Override
                        public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest)
                                throws IOException {
                            abstractGoogleClientRequest.setDisableGZipContent(true);
                        }
                    });
            // end of optional local run code
            builder.setApplicationName(context.getString(R.string.app_name));
            regService = builder.build();
        }



        String msg = "";
        try {
            if (gcm == null) {
                gcm = GoogleCloudMessaging.getInstance(context);
            }
            String regId = gcm.register(SENDER_ID);
            msg = "Device registered, registration ID=" + regId;

            // You should send the registration ID to your server over HTTP,
            // so it can use GCM/HTTP or CCS to send messages to your app.
            // The request to your server should be authenticated if your app
            // is using accounts.
            regService.register(regId).execute();

        } catch (IOException ex) {
            ex.printStackTrace();
            msg = "Error: " + ex.getMessage();
        }
        return msg;
    }


    /**
     * <p>Runs on the UI thread after {@link #doInBackground}. The
     * specified result is the value returned by {@link #doInBackground}.</p>
     * <p/>
     * <p>This method won't be invoked if the task was cancelled.</p>
     *
     * @param msg The result of the operation computed by {@link #doInBackground}.
     *
     * @see #onPreExecute
     * @see #doInBackground
     * @see #onCancelled(Object)
     */
    @Override
    protected void onPostExecute(String msg) {
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
        Logger.getLogger("REGISTRATION").log(Level.INFO, msg);
    }
}

person Hillbilly128    schedule 19.10.2014    source источник


Ответы (1)


Это не то, как вы выполняете фоновую задачу в фоновом режиме. Простой вызов метода doInBackGround() выполняет этот метод в том же (основном) потоке, что вызывает ваше исключение.

new GcmRegistrationAsyncTask().doInBackground(this);

Правильный способ:

new GcmRegistrationAsyncTask().execute(null,null,null);

Вот пример из официальная демонстрация GCM :

private void registerInBackground() {
    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            String msg = "";
            try {
                if (gcm == null) {
                    gcm = GoogleCloudMessaging.getInstance(context);
                }
                regid = gcm.register(SENDER_ID);
                msg = "Device registered, registration ID=" + regid;

                // You should send the registration ID to your server over HTTP, so it
                // can use GCM/HTTP or CCS to send messages to your app.
                sendRegistrationIdToBackend();

                // For this demo: we don't need to send it because the device will send
                // upstream messages to a server that echo back the message using the
                // 'from' address in the message.

                // Persist the regID - no need to register again.
                storeRegistrationId(context, regid);
            } catch (IOException ex) {
                msg = "Error :" + ex.getMessage();
                // If there is an error, don't just keep trying to register.
                // Require the user to click a button again, or perform
                // exponential back-off.
            }
            return msg;
        }

        @Override
        protected void onPostExecute(String msg) {
            mDisplay.append(msg + "\n");
        }
    }.execute(null, null, null);
}
person Eran    schedule 20.10.2014
comment
Эй, у меня та же проблема, но я выполняю ее так, как вы упомянули, можете ли вы взглянуть на мой вопрос здесь stackoverflow.com/questions/28417275/ - person ; 10.02.2015