我有一个应用程序,它基本上是在调用api时使用firebase云消息服务从我自己的服务器获取通知,奇怪的是,当我通过android studio运行菜单安装它时,它将应用程序直接安装到我的设备上应用程序运行良好,但是当我从我的项目目录中获取应用程序调试并手动安装它时,它会给我一个错误

Can't create handler inside thread that has not called Looper.prepare()

这个错误指出了我使用onTokenRefresh()方法中的volley库向数据库发送数据的方法。
我将这些方法放在扩展firebaseInstanceIdService的Serveice中。
这是完整的错误消息
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);

}

最佳答案

好的,我已经解决了问题,出于某种原因,如果您从调试应用程序手动安装应用程序,您将得到我在问题中提到的错误。我通过将从fcm获得的令牌保存到共享首选项来解决这个问题,然后当用户登录时,我将令牌发送到我的数据库。这种方式imo效率较低,因为用户每次登录时都必须发送令牌,但令牌保持不变(直到他们清除数据或卸载应用程序)。

07-27 19:39