FCM onTokenRefresh()无法在未调用Looper.prepare()的线程中创建处理程序

问题描述:

我有一个应用程序,基本上每次调用API时都会使用Firebase云消息传递服务从我自己的服务器获取通知,奇怪的是我安装它通过Android工作室运行菜单,这是安装应用程序直接到我的设备的APP工作正常,但是当我从我的项目目录应用程序调试并手动安装它,它给了我错误FCM onTokenRefresh()无法在未调用Looper.prepare()的线程中创建处理程序

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

该错误指出了我的方法,即使用onTokenRefresh()方法中的排空库将数据发送到我的数据库。

我正在把这个方法放在一个扩展了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); 

} 
+0

可能你正在改变后台线程的UI。你做? – Prashant

+0

@Prashant我didnt,我通过android工作室运行应用程序,测试它并将其卸载,我将调试应用程序复制到我的设备手动安装它,它给了我错误。 –

好吧,我已经解决了这个问题,由于某种原因,如果你从debug-app手动安装应用程序,你会得到我在问题中提到的错误。我通过将我从FCM获取的令牌保存到共享首选项以及稍后在用户登录时将该令牌发送到我的数据库来解决此问题。这样,imo的效率就会降低,因为用户每次登录时都必须发送令牌,但令牌保持不变(直到他们清除了数据或卸载应用程序为止)。

,你已经给了我们的代码的代码不是唯一的产生错误的代码的版本。后者正在创建一个敬酒。 onTokenRefresh()在后台线程上调用,并且不能直接显示Toast。

专注于在设备上获取正确版本的应用程序(没有Toast的应用程序),问题就会消失。