我有一个应用程序,无论何时调用API,我都会使用Firebase Cloud Messaging服务从我自己的服务器获取通知,奇怪的是当我通过Android studio RUN菜单安装它时,这是将应用程序直接安装到我的设备APP工作正常,但是当我从我的项目目录中进行app-debug并手动安装时,它会给我错误
Can't create handler inside thread that has not called Looper.prepare()
错误指出我的方法是使用onTokenRefresh()
方法中的排球库将数据发送到我的数据库。
我将这些方法放在扩展FirebaseInstanceIdService的服务中。
这是完整的错误消息
E/AndroidRuntime: FATAL EXCEPTION: pool-3-thread-1
Process: proizzy.com.qrcodeproizzyadm, PID: 5704
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.widget.Toast$TN.<init>(Toast.java:645)
at android.widget.Toast.<init>(Toast.java:137)
at android.widget.Toast.makeText(Toast.java:440)
at proizzy.com.qrcodeproizzyadm.Notification.FirebaseInstanceIDService.onTokenRefresh(FirebaseInstanceIDService.java:25)
at com.google.firebase.iid.FirebaseInstanceIdService.zza(Unknown Source)
at com.google.firebase.iid.FirebaseInstanceIdService.zzm(Unknown Source)
at com.google.firebase.iid.zzb$2.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
我对我的代码出了什么问题一无所知。
这是我完整的服务类代码
public class FirebaseInstanceIDService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
final String token = FirebaseInstanceId.getInstance().getToken();
Log.v("tok", token);
String tokUrl = "someurl.php";
JsonObjectRequest regToken = new JsonObjectRequest(Request.Method.POST, tokUrl, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.v("success", response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.v("errorvolley", error.getMessage());
}
}){
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("token", token);
return params;
}
};
RequestQueue regQueue = Volley.newRequestQueue(getApplicationContext());
regQueue.add(regToken);
}
答案 0 :(得分:1)
好的,所以我已经解决了这些问题,出于某种原因,如果你从debug-app手动安装app,你会得到我在问题中提到的错误。我通过将我从FCM获得的令牌保存到共享首选项来解决它,之后当用户登录时,我将令牌发送到我的数据库。这种方式imo效率较低,因为用户每次登录时都必须发送令牌,但令牌保持不变(直到他们清除数据和/或卸载应用程序)。
答案 1 :(得分:0)
您提供给我们的代码不是产生错误的代码版本。后者正在创造一个祝酒词。 onTokenRefresh()在后台线程上调用,无法直接显示Toast。
专注于在设备上获取正确版本的应用程序(没有Toast的应用程序),问题就会消失。
答案 2 :(得分:0)
您遇到的问题是,您已经在工作线程/后台线程中时尝试执行异步任务。
如您在堆栈跟踪中所见,您(系统)创建了一个只能从主线程调用的处理程序:
android.os.Handler。(Handler.java:114)
解决方案:
添加这样的支票:
if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
// do stuff that is allowed on main thread
} else {
// do stuff that is allowed on background thread
}
答案 3 :(得分:0)
怎么样?
$ sed 's/\(S\.\)\(.\)/\1\n\2/g' file
1900-01-01 00:00:00|1|S|S|S|S.
1900-01-01|S.
1900-01-01 00:00:00|1|S|S|S|S.
1900-01-01 00:00:00|1|S|S|S|S.