why is this problem “Can't create handler insi

2019-08-22 23:33发布

问题:

so i'm trying to call realtime database from inside a firebasemessagingservice to get some infos from the database but each and every time the app is on background this error is happening

09-17 19:27:21.596 4083-4140/? E/AndroidRuntime: FATAL EXCEPTION: Firebase-MyFirebaseMessagingService
    Process: com.kirtu.simpletexts.texts, PID: 4083
    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 com.google.firebase.database.zza.<init>(com.google.firebase:firebase-database@@16.0.2:1024)
        at com.google.firebase.database.obfuscated.zzb.zza(com.google.firebase:firebase-database@@16.0.2:77)
        at com.google.firebase.database.obfuscated.zzu.zza(com.google.firebase:firebase-database@@16.0.2:2234)
        at com.google.firebase.database.obfuscated.zzad.zzb(com.google.firebase:firebase-database@@16.0.2:92)
        at com.google.firebase.database.obfuscated.zzad.zza(com.google.firebase:firebase-database@@16.0.2:42)
        at com.google.firebase.database.FirebaseDatabase.zza(com.google.firebase:firebase-database@@16.0.2:357)
        at com.google.firebase.database.FirebaseDatabase.getReference(com.google.firebase:firebase-database@@16.0.2:201)
        at com.kirtu.simpletexts.texts.MyFirebaseMessagingService.onMessageReceived(MyFirebaseMessagingService.java:60)
        at com.google.firebase.messaging.FirebaseMessagingService.zzd(Unknown Source)
        at com.google.firebase.iid.zzc.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at com.google.android.gms.common.util.concurrent.zza.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:761)

why is this problem happening suddenly?previously it never happened.

here is my code

@Override
    public void onMessageReceived(final RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
...
...
...
FirebaseDatabase.getInstance().getReference("xxxx").child(xxxx).addListenerForSingleValueEvent(new ValueEventListener()//problem is happening at this line
                    {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot)
                        {
...
...
...
    }
});

thanks in advance.

回答1:

Calls to the Firebase Realtime Database client are expected to be made from the main thread. More specifically, the Firebase client invokes the onDataChange callback on the main/UI thread of your app. Since onMessageReceived is part of a service, it may be called when the main/UI thread is not active. And, while I've never seen it before, the error message you get is the result when that happens.

The trick is to post from your onMessagesReceived to the main thread (see Access data from Firebase Service in main thread), or ensure that the looper is initialized so that your code can be called from the correct context (see Firebase Cloud Messaging: Accessing UI elements in onMessageReceived()).



回答2:

solved it with the help of the answer by @Frank Van Puffelen

i just needed to put

FirebaseDatabase.getInstance().getReference("xxxx").child(xxxx).addListenerForSingleValueEvent(new ValueEventListener()//problem is happening at this line
                    {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot dataSnapshot)
                        {
...
...
...
    }
});

inside

Handler handler = new Handler(Looper.getMainLooper());
                    handler.post(new Runnable() {
                        @Override
                        public void run() {

.....
.....
.....}
                        });

then it worked.