Android Google云消息示例主线程
我对Google云到设备的消息传递示例有一个问题。我遵循此处的说明()因为这是我创建项目时Android Build给出的说明。按照说明,我创建了注册和接收消息所需的类。寄存器是作为AsyncTask创建的,并从我的主应用程序的OnCreate方法调用。我遇到的问题是,每次它运行时,我都会得到一个IOException:主线程。我尝试将代码更改为可运行,但没有运气,我只是得到了相同的错误。我在文档中读到的所有内容都表明我所做的应该是可行的,所以我不明白为什么不行 下面是显示错误和堆栈跟踪的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) 注册班Android Google云消息示例主线程,android,google-cloud-messaging,android-build,Android,Google Cloud Messaging,Android Build,我对Google云到设备的消息传递示例有一个问题。我遵循此处的说明()因为这是我创建项目时Android Build给出的说明。按照说明,我创建了注册和接收消息所需的类。寄存器是作为AsyncTask创建的,并从我的主应用程序的OnCreate方法调用。我遇到的问题是,每次它运行时,我都会得到一个IOException:主线程。我尝试将代码更改为可运行,但没有运气,我只是得到了相同的错误。我在文档中读到的所有内容都表明我所做的应该是可行的,所以我不明白为什么不行 下面是显示错误和堆栈跟踪的Log
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);
}
}
package com.hillbilly.kidslancher;
导入android.content.Context;
导入android.os.AsyncTask;
导入android.widget.Toast;
导入com.appspot.kidslancerparent.registration.registration;
导入com.google.android.gms.gcm.GoogleCloudMessaging;
导入com.google.api.client.extensions.android.http.AndroidHttp;
导入com.google.api.client.extensions.android.json.AndroidJsonFactory;
导入com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
导入com.google.api.client.googleapis.services.GoogleClientRequestInitializer;
导入java.io.IOException;
导入java.util.logging.Level;
导入java.util.logging.Logger;
/**
*craighillbeck于2014年10月19日创作。
*/
公共类GcmRegistrationAsyncTask扩展了AsyncTask{
私有谷歌云通讯gcm;
私人语境;
私人注册服务=null;
//TODO:按照上面的说明,将您自己的发件人ID更改为Google开发者控制台项目编号
私有静态最终字符串发送器_ID=“978823093525”;
/**
*重写此方法以在后台线程上执行计算
*指定的参数是传递给{@link#execute}的参数
*由此任务的调用方执行。
*
*此方法可以调用{@link#publishProgress}来发布更新
*在UI线程上。
*
*@param params任务的参数。
*
*@返回此任务的子类定义的结果。
*
*@see#onPreExecute()
*@see#onpost执行
*@see#出版进度
*/
@凌驾
受保护字符串doInBackground(上下文…参数){
上下文=参数[0];
if(regService==null){
Registration.Builder=新建Registration.Builder(
AndroidHttp.newCompatibleTransport(),
新的AndroidJsonFactory(),null)
//仅在本地测试时需要setRootUrl和setGoogleClientRequestInitializer,
//否则可以跳过它们
.setRootUrl(“http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(新的GoogleClientRequestInitializer(){
@凌驾
公共无效初始化(AbstractGoogleClientRequest AbstractGoogleClientRequest)
抛出IOException{
abstractGoogleClientRequest.setDisablegzip内容(true);
}
});
//可选本地运行代码结束
builder.setApplicationName(context.getString(R.string.app_name));
regService=builder.build();
}
字符串msg=“”;
试一试{
如果(gcm==null){
gcm=GoogleCloudMessaging.getInstance(上下文);
}
字符串regId=gcm.register(发送方ID);
msg=“设备已注册,注册ID=“+regId;
//您应该通过HTTP将注册ID发送到服务器,
//因此,它可以使用GCM/HTTP或CCS向您的应用程序发送消息。
//如果您的应用程序
//正在使用帐户。
regService.register(regId.execute();
}捕获(IOEX异常){
例如printStackTrace();
msg=“错误:”+ex.getMessage();
}
返回味精;
}
/**
*在{@link#doInBackground}之后的UI线程上运行
*指定的结果是{@link#doInBackground}返回的值
*
*如果任务被取消,则不会调用此方法
*
*@param msg{@link#doInBackground}计算的操作结果。
*
*@see#onPreExecute
*@see#doin background
*@see#onCancelled(对象)
*/
@凌驾
受保护的void onPostExecute(字符串msg){
Toast.makeText(context,msg,Toast.LENGTH_LONG).show();
Logger.getLogger(“注册”).log(Level.INFO,msg);
}
}
这不是在后台执行后台任务的方式。只需调用doInBackGround()
方法,即可在同一(主)线程中执行此方法,这将导致您的execption
new GcmRegistrationAsyncTask().doInBackground(this);
正确的方法是:
new GcmRegistrationAsyncTask().execute(null,null,null);
以下是来自以下方面的示例:
private void registerInBackground(){
新建异步任务(){
@凌驾
受保护字符串doInBackground(无效…参数){
字符串msg=“”;
试一试{
如果(gcm==null){
gcm=GoogleCloudMessaging.getInstance(上下文);
}
regid=gcm.寄存器(发送方ID);
msg=“设备已注册,注册ID=“+regid;
//您应该通过HTTP将注册ID发送到服务器,以便
//可以使用GCM/HTTP或CCS向您的应用程序发送消息。
sendRegistrationIdToBackend();
//对于本演示:我们不需要发送它,因为设备将发送
//向服务器发送的上游消息,使用
//消息中的“发件人”地址。
//坚持
new GcmRegistrationAsyncTask().execute(null,null,null);
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);
}