我正在尝试通过 GCM 获取我的设备注册 ID。我这样做的代码包含在从我的主线程调用的 AsyncTask 中。
主要代码
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() 一直处于阻塞状态,直到我的超时异常被命中。有谁知道为什么会发生这种情况?
最佳答案
原因是因为你正在执行 gcm
.get(5, TimeUnit.SECONDS);
此调用会阻塞线程 5 秒,但是由于网络连接不稳定等不同原因,注册过程可能需要 5 秒以上。这不是做您想做的事的最佳方法。
看看这个例子,摘自 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);
结合这个例子,一切都应该工作。
关于java - GCM 注册阻塞 AsyncTask 直到发生超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31686227/