本文介绍了GCM寄存器阻塞AsyncTask,直到发生超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的设备注册ID与GCM。我的代码包含在从我的主线程调用的AsyncTask中。

I'm trying to get my device registration ID with GCM. My code to do so is contained within an AsyncTask which is called from my main thread.

主代码

Main code

try
{
    String deviceId = new Gcm().execute(this.activity).get(5, TimeUnit.SECONDS);

    Log.i("Login", "User device id returned as " + deviceId);
    return deviceId;
}
catch (Exception e)
{
    Log.e("Login", "Exception", e);
}

GCM课程

public class Gcm extends AsyncTask<Activity,Void,String>
{

@Override
protected String doInBackground(Activity... params)
{
    Log.i("GCM", "Attempting to get device id");
    Activity activity = params[0];
    try
    {
        Log.i("GCM", "Getting GCM instance");
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(activity.getApplicationContext());

        Log.i("GCM", "Registering with GCM");

        String regId = gcm.register(PROJECT_NUMBER);

        Log.i("GCM",  "Device registered, registration ID=" + regId);

        return regId;
    }
    catch (IOException e)
    {
        throw new IllegalStateException(e);
    }
}
}

这里是我的日志转储

07-28 13:07:39.093  I/GCM﹕ Attempting to get device id
07-28 13:07:39.093  I/GCM﹕ Getting GCM instance
07-28 13:07:39.093  I/GCM﹕ Registering with GCM
07-28 13:07:44.103  E/Login﹕ Exception
    java.util.concurrent.TimeoutException
        at java.util.concurrent.FutureTask.get(FutureTask.java:176)
        at android.os.AsyncTask.get(AsyncTask.java:507)
I/GCM﹕ Device registered, registration ID=XXXXXX

因此,出于某种原因,调用gcm.register ()被阻塞,直到超时异常被命中。有没有人知道为什么会发生这种情况?

So for some reason, calling gcm.register() is blocking until my timeout exception is hit. Does anyone have any idea why that might be happening?

推荐答案

原因是您正在执行gcm

The reason is cause you're executing gcm with

.get(5, TimeUnit.SECONDS); 

这个调用会阻塞线程5秒,但是由于不同的原因,比如注册过程中网络连接不稳定可能需要5秒以上。这不是最好的方法来做你想做的。

This call blocks the thread for 5 seconds, however due to different reasons like unstable network connection the registration process can take more than 5 seconds. It is not the best approach to do what you want.

看看这个例子,摘自:

Take a look at this example, taken from official GCM demo:

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

合并这个例子,一切都应该有效。

Incorporate this example and everything should work.

这篇关于GCM寄存器阻塞AsyncTask,直到发生超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 01:48