Firebase Code Running After Everything Else - android

I'm making an Android app with Firebase and within one of my activities I need to read data from Firebase before doing anything else. To do so, I'm using a ValueEventListener. The problem is, Android is running the rest of the code first and then it gets the result/runs the code within the listener's onDataChange() method. I know this because I debugged using Logs and indeed the result arrives a couple of seconds after the rest of the code runs.
I've seen examples of people writing the code you want to run after the query within another method, and then calling that method inside the onDataChange(). I tried doing that, also tried moving the listener to another class and calling the method and even tried controlling the flow of the code with variables, nothing worked. Any ideas of what can I do?
Btw, I don't know if this affects in any way of not but, my piece of code that depends on Firebase's result is inside the onStart() method, so I suppose Android would always run the onStart() first and then get the result from the listener.
Thanks!

The ValueEventListeners are asynchronous, so they won't run first. Instead, try calling a function that does what you wanted to do with the listener from inside the onDataChange() function.

Related

For ActivityResultContracts, what is the alternative for In-App Updates?

I am restructuring my code to use ActivityResultContracts, and I've been able to recreate the old way of doing things with onActivityResult by passing in "codes" with my Intents and just passing them back from the called activity. Everything is working fine, but how would I manage to do that with App Updates, even the Google documentation is still using onActivityResult to check for app updates.
After looking at it for the past few days, it does not seem like it is possible to forgo using onActivityResult; the cancel response is only returned to that method. If you have a listener setup to check for resumed downloads, you will get a response there (as onResume is called when the calling activity is moved back to the foreground) but you only get that an update is available and the install status is unknown (which coincidentally is the same value as cancelled, and you can't do anything there as you get the same values on the initial call to check for an update). I don't see the point in deprecating a method you're still required to use, but oh well.

onGetViewFactory() called only once

I have created Collection Widget and in which I need to updated data through API. Everything seems to work fine but ListView update call is executed only once. While debugging I found that onGetViewFactory() method is getting called only once.
I have searched for the problem and used the solution from below link
onGetViewFactory only called once for multiple widgets
But it didn't work for me.

Invoking Firebase listener to run

I'm trying to determine whether or not I download data in my android application. I can do this by making the method return true when it does download data, but the listener doesn't seem to be invoked until all other code is finished running (meaning it waits until a pause in your code). So I'm wondering if there is a way to sort of "forcibly" invoke these listeners? Perhaps by creating the listener in a different thread? Would this work or would it be a waste of time? I've already tried to sleep on the main thread for a few seconds, but that doesn't seem to do it either. If it wouldn't work, could you explain when exactly these listeners are invoked? Thanks in advance.
To add onto my question, I am NOT using the realtime database. I understand how realtime triggers work, but I am using the Firestore, so I am only getting data once, not getting realtime updates :)
As you have already noticed with the API calls that deal with reading and writing data are fully asynchronous. This means that the call always returns immediately, without blocking the code to wait for a result. The results come some time later, whenever they’re ready, since it may take some time for this. Depending on your connection speed and the state, it may take from a few hundred milliseconds to a few seconds before that data is available. So Firebase, already is using another thread (other than the main thread) to get the work done.
Calling a synchronous function on your app’s main thread could freeze the app indefinitely, which is a terrible UX. On Android, it could also soft-crash with an Application Not Responding (ANR) dialog.
Doug Stevenson, has explained in his post everything that you need to know about Fireabse asynchronous behaviour and what you need to do/avoid when dealing with Firebase.

wait till TextToSpeech onInit() has been initialized

I am developing a simple app which will speak the contact name or an unknown number when call is received. I am implementing the app using broadcastReceiver and Services. If i run the app on emulator and start the call using DDMS, with 2 or 3 contacts saved, the app works fine since onInit() is called before tts.speak() runs.
Now when i try to run the same app on my android phone, onInit is called after the tts.speak(). From what i have understood while searching for an answer to this question, this happens due to tts.speak() not waiting for onInit to called.
One solution i found on this question was on How to wait for TextToSpeech initialization on Android but that didn't work either.
This question has been asked a lot of times but i couldn't find a working solution. This link suggested to use handler http://davidcheney.wordpress.com/2010/11/16/multitasking-in-android/ but being a newbie i have no idea as to how to implement that.
From what i understood i have to wait till onInit is called before i can use tts.speak() but i don't know how to do it.
Update
I was trying to call speak function outside the onInit since the data which was to be spoken was coming from elsewhere and i didn't want to do all the coding in onInit,this was not working. So i changed my code and finally somehow managed to run that speak() inside onInit().
Although the code is now running but there must be a way to call speak() outside onInit. So i will wait for a better answer else post my code for others facing same problem.
You either set a class member flag boolean mTtsInitialized and check this flag everytime you call speak or put the code to get the data to be spoken in onInit
This is not the most elegant way of handling this, I'm sure, but could you extend the class containing the onInit() method?
In this class, you could have a boolean variable that effectively "locks" your thread. Override the onInit() method, call super(), and then after super() set this value to true. Then, enter a loop that blocks the thread which calls tts.speak() until this value is true.
You'll want to keep in mind that you can't do this in the UI thread, because if you block that for too long it will crash your app.
I hope I understood your question correctly. :)

Android Concurrency issue

I have strictly separated the layers between different parts of my Android application.
At some point of execution I am updating my data from xml service on Internet. That updating takes up about 10 seconds and is done completely in the background - meaning the user interface of an application works fine. However further calls to my class (later - DataManager) which is responsible for data updating (after update has been started but not yet finished) makes my application crash. NullPointerException is thrown with objects which NEVER are null.
So I assume that only one Thread can use my DataManager at one time and calls to DataManager from other threads ends up in exceptions.
I tried various combinations of putting 'synchronized' keywords near sensitive methods but it seems that when update is executing - NOTHING can use ANYTHING from my DataManager.
BTW other classes which are related to DataManager during the execution also seem to hold null objects.
I guess I am just missing some kind of design pattern which is used to deal with concurrency problems and maybe anyone can suggest me something?
I had trouble dealing with using the Apache http client because of threading issues and I think your issue could be similar in that respect. What I ended up doing was setting up a callback scheme. This may or may not work for you, of course.
This may seem a bit Rube Goldberg-like to you, but it worked for me.
I would have my UI thread call my data manager object with a method that spawned a thread to go and acquire the data. The method's return value is an object that would EVENTUALLY have the data in it. I would have my activity extend an interface, something like "DataCallbackInterface", with a method that the thread would call after it acquired the data (i.e. the last line in run()). Since that call will inherently be within another thread, you'll need to use a Handler to run anything useful in your implementation of the DataCallbackInterface method. When that method is called, you will know for a fact that the data is there and not rely on any strange synchronization flags to get it right.

Categories

Resources