Updating Data in Android Slices using onSlicePinned - android

Since lengthly operations can't be done inside onBindSlice(), I am fetching data from server from onSlicePinned() method and then showing it in slices. But I can't understand when is this function called.
I thought it would be called every time we fresh start Assistant (i.e. starting Assistant after killing it). It is working while testing on Slice-Viewer app, every time i kill slice viewer and start again then onSlicePinned() is called along with onSliceBind(), but not in case of Google Assistant. So is this a bug or should be the way it is?
And if this is how onSlicePinned() should work, then is there any way i can fetch data every time onBindSlice() is called after starting app.

To load content from a server into a Slice you should follow the delayed content best practices here:
https://developer.android.com/guide/slices/templates#delayed_content
The tl;dr is, you should return something immediately, then go off and load/process your content, once the content is ready, call notifyChange() which will result in onBindSlice() being called again where you can return the Slice with the new content.

Related

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.

App Design Issue : android.database.StaleDataException

Firstly I have investigated other StaleDataExceptions on SO but none really answer, or lead me to a solution to my current App design problem.
I'm creating a Music Player App, which I initially designed to query the MediaStore.Audio with a CursorLoader to retrieve information from the Content Provider - this works fine, however obviously if you have a big music library there could be a more than desirable wait time getting all the information back when the app loads each time. My second approach was to start a remote Service on app first launch, which queries the MediaStore.Audio using a CursorLoader and registers for any updates. When the Cusror is returned I then run an AsyncTask to process the information into an ArrayList of Custom POJO class that implements the Parcelable Interface which then gets marshalled/demarshalled via an Intent back to a handler in the Music App. This solution works well because if the app is closed, and reopened it just queries the Service for the latest ArrayList of custom Objects, rather than having to query the MediaStore.Audio at all - the Service implements LoaderCallback<Cursor> and always updates ArrayList of custom Objects and notifies the App if open, if not it has them ready for when the app is reopened.
Right - to the problem (ok took a bit of time, but necessary background information). The issue is : If I'm in another media app and start deleting music files in quick succession the registered Listener in my service is calledback and a new cursor is delivered, however the AsyncTask I am using to iterate over the existing cursor has a Race Condition where it is closed by another Thread / CursorLoader as the Cursor is updated - exception thrown : android.database.StaleDataException: Attempted to access a cursor after it has been closed.
The current workaround I'm using is use setUpdateThrottle to 20 seconds when registering the listener, this works, however means there is a delay in getting updated information back to the Service.
Is there any viable solution or approach where I can avoid this problem?
Thanks in advance.
UPDATE
A working viable solution, was actually quite easy to achieve - it initial problem however does illustrate my lack of experience with Loaders, however I've gained some knowledge on the way to finding a solution.
Solution:
I am still using a remote Service. However instead of using a CursorLoader - which was closing the cursor whilst I was still processing it in the onLoadComplete() callback, I am using a AsyncTaskLoader. The AsyncTaskLoader coupled with a ContentObserver can still monitor for underlying data changes from a Uri but is not directly coupled with the Cursor object like a CursorLoader. I am able to monitor for data changes and let the AsyncTaskLoader know it needs to reload data (forceLoad()), however this is queued, and doesn't affect the processing of loadInBackground() method - Once this returns, it simply cancels the task and starts the new task.

How do I delay the running of an android test so that an AsyncTask is finished first?

I'm writing a test for my android app. The app loads in some external data into a view using an AsyncTask. I want to test that the AsyncTask worked and that the data is properly placed into the view. The problem is that my test is running (and failing) before the AsyncTask is complete.
What's the best way of handling this scenario?
You could use mock data that is returned much faster or implement some sort of waiting/listening for an event in the test.
Create yourself a callback interface which continues your routines after the call returns or use a lock/mutex. I would suggest a callback so you can continue with other tasks while waiting for the data to return e.g. drawing the UI. You could put a loading screen in front to show the user the application is actually waiting for something.

Activity won't start until data is pulled from MySQL server

I have an Activity that displays a text based on data pulled from MySQL server. The problem is that the Activity won't load until data is pulled, which sometimes takes some long seconds or even doesn't load at all, and in the meantime the users gets a black screen.
I tried to pass the mission of getting the data from the server to a service, but also it waits for pulling the data and only then shows the layout of the Activity.
I also tried to make an activity with fixed text and then call the Activity that pulls the data from the server, but still the program wait for the data.
Can you think on a creative solution for it? or maybe a non-creative one as well :)
you can use asynctask for this:
http://developer.android.com/reference/android/os/AsyncTask.html
or you can show a waiting dialog to user until you get your data(do it in separate thread).....
or you can implement a splash screen and there you can fetch data.....
You need to do it inside another thread. Try using AsyncTask class.
The delay is probably due to the call to fetch the data being done on the main thread, also called the UI thread. Processes which take any significant amount of time, and by that I mean even a second or two should be done in a seperate thread. Android provides a class called AsyncTask to help make threading painless.
You mention you tried a service but did you take a look at an IntentService? (Can't link it yet but it's on d.android.com.) I like using them for these kind of tasks cause they handle the threading for you (like an AsyncTask) and it separates concerns better. The IntentService then sends a broadcast message that the activity picks up indicating that the data is available or not. Store the data locally in a sqlite db or as a json/xml file.

Is there a standard pattern for updating android views?

I'm currently building an android application with quite a few different connected activities. In each activity I've got a private updateView() method to update all the textViews and stuff on that screen. This gets called in the onResume() method so that each time the activity comes to the front it's views will be updated.
Is this the right way to do things or is there a more standard pattern for keeping your views in sync with the data?
I think that you are doing this correctly. onResume would be the perfect time to update your views, I assume you are only updating if there is actually new data to be displayed?
If retrieving the data during the updateView method takes a long time then you should do it in an AsyncTask to avoid clogging the UI Thread which will make your app hang.
In fact any data retrieval like getting data from the web or reading from your apps database should be done in an AsyncTask. This is because even if your data retrieval seems to take milliseconds on your device it may conceivably take longer on another, less powerful device.

Categories

Resources