Does the SharedPreference really have async API for writing in Android? - android

I've just read an article which is about SharedPreferences and it baffles me.
I've believed that SharedPreferences's apply() works asynchronously when it writes until now. You can see the reason here.
But the article which is posted by Florina Muntenescu in the Android Developers Blog said
SharedPreferences has a synchronous API that can appear safe to call on the UI thread, but which actually does disk I/O operations. Furthermore, apply() blocks the UI thread on fsync().
There is only async API for reading changed values via listener.
So, What i want to ask are...
is apply() also synchronous method?
the official android document is wrong?

is apply() also synchronous method?
No. It returns immediately.
the official android document is wrong?
Probably not. Florina is pretty good.
What Florina is saying in that blog post is that a side-effect of apply() is that at some point, the UI thread will be blocked due to the fsync() when the new preference values are written. Think of the side-effect as akin to pollution: the polluter (apply()) is not affected directly, but the pollution still has an impact, just a bit later on.

Related

Is Task<T>.await() main-safe?

I'm writing my first Kotlin app and am using firebase services for auth, db & storage. As it is not possible to make an atomic Firestore + Storage operation, I find myself in quit a callback-hell for a simple image upload (with error fallbacks and all). Thus - I decided to refactor my app to use coroutines. I found some examples (like here and here) but I noticed that the repository-level functions in those examples are not wrapped with withContext(Dispatchers.IO){ } like shown in android docs. Should they? I guess this is two questions in one:
Should Firebase operations always be called with the IO dispatcher?
Is kotlinx-coroutines-play-services's Task<T>.await() main-safe?
And a bonus question: I wrap all my Firebase calls in a proxy object for decoupling - is there a way to set all functions of an object (/class) to run with the same context, or do I have to wrap each function with withContext(Dispatchers.IO){ } separately?
Thanks a lot!
Should Firebase operations always be called with the IO dispatcher?
All Firebase APIs are asynchronous and designed to be called safely from the main thread unless otherwise stated in the API documentation.
Is kotlinx-coroutines-play-services's Task.await() main-safe?
Yes. As the API documentation states (emphasis mine):
Awaits for completion of the task without blocking a thread.
It's a suspend fun, and they do not block. However, they do not really make sense to call outside of a coroutine.

Android Studio Asynctask Alternative

I'm new to Android Development, and I've run into this problem that I haven't found a solution for.
It starts off first with going to a webservice api for login. From there if the login is successful it executes to 2 functions for the actually data it needs, stores in sqlite and then proceeds to next activity. All 3 api requests are using AsyncTask and from what I understand my Activity is actually running faster than my "doInBackground" background thread. I want to know the path or what i should look into. I've read posts about using sleep, and read posts about how that is bad to do. I want to get the json data i need, store it, and use it immediately. I think i'm suppose to find away to connect directly and use a progress bar to get the data. Keep in mind, it's not a lot of data, but it's enough to stall my application.
Not sure what a ProgressBar has to do with retrieving data from a server but if you're looking for AsyncTask alternatives (particularly for HTTP calls) you can look at these frameworks (you'll probably only want to pick one):
Square's Retrofit
Google's Volley
Either one will make your life a lot easier when it comes to making HTTP requests. Their own documentation explains how to use them pretty well so I'm not going to go into how to use it here.
If you're looking for a native, lower level AsyncTask alternative, have a look at AsyncTaskLoaders. The AsyncTaskLoader essentially does exactly the same thing as an AsyncTask but they live within the life cycle of the Activity or Fragment so your code tends to be less error prone.

Android - SQLite ContentResolver insert/delete/update on UI Thread?

I have looked through many examples/tutorials of using SQLite in Android. Let's say you have an app that uses SQLite, ContentProvider, CursorLoader, a custom CursorAdapter.
Now all major examples of this that I've found rely on a CursorLoader to fetch data to the CursorAdapter, which by the nature of CursorLoader happens in an Async - UI thread safe manner. However, these same examples all make insert/delete/update calls through the ContentResolver on the main thread (e.g. from onClick, onResume, onPause). (Example) They don't wrap these calls in an AsyncTask or launch a separate thread or use the AsyncQueryHandler.
Why is this, how can so many well written blogs/examples make such an obvious mistake? Or are simple single row insert/delete/update calls so quick that they are safe enough to launch from the Main/UI thread? What is the proper way to do these quick calls?
I also got confused about the samples making calls on the main thread. I guess the samples just simplified the demonstrations avoiding extra threads and callbacks, since single insert/update/delete call may return quickly.
Besides the Loader pattern for query, android did provide a helper class AsyncQueryHandler, since API level 1, for async CRUD operations with full CRUD callbacks supported. The AsyncQueryHandler works inside with a HandlerThread for the async operations and delivers the results back to the main thread.
So I do believe the ContentProvider queries should run in worker threads other than the UI, and those samples may not be best practices according to the official design.
=== edit
Found an annotation from the official framework docs, see this or this, Line 255:
In practice, this should be done in an asynchronous thread instead of
on the main thread. For more discussion, see Loaders. If you are not
just reading data but modifying it, see {#link android.content.AsyncQueryHandler}.
=== edit 2
Link to actual android dev guide containing the above quote
This question has been on my mind since a long time. I guess, this depends on the complexity of the file we are trying to Insert, Update or Delete. If our application is going to Insert or Update large files, it would be always right to do it asynchronously and if the files aren't going to be that big, running it on UI thread can be done.
However, it is always recommended to continue with Database operations on a separate thread.
I think you've answered your own question. I do believe CursorLoader extends AsyncTaskLoader. Calls made from UI thread only process the call TO the CusorLoader (which uses AsyncTask.) What is being done BY the call still does not occur on UI Thread. Making a call to a method/function that then runs things on a seperate thread is still doing work away from UI thread.
What work do you think is happening on the UI thread?
Please show Debug log if possible or example where you think work is done on UI.
It shouldn't be.
Not trying to argue just want to know how you've come to the conclusion of UI work?

Does modifying a SharedPreferences instance result in an immediate I/O operation on Android?

In my application I modify a SharedPreferences instance every time I finish / start and Activity. I only modify 1 property in it (tho I don't think that it matters now). I was wondering if these modifications are persisted to disk with some file I/O operations right after commit, or Android batches these operations somehow?
I'm thinking about battery life here, as afaik file I/O is slow (especially for writing operations) and is hard on the battery. I couldn't find anything about this in the docs, does anyone know something about this?
Thank you
Yes, committing changes to a preferences file will cause the file to be written synchronously. (see source).
Yes. The only difference between commit() and apply() is commit is synchronous.
I'd say the SharedPreferences are stored immediately when
commit;
is called.
Looks like Android OS philosophy is to rely on the apps (and their developers) to store their data whenever they want, and in the documentation an accent is put to persist your data in onPause / onDestroy yourself, not rely on the system to do anything for you, if I make myself clear.

android concurrency

I have an application that makes a lot of network requests for xml data that is parsed and presented to the user. Best practices dictate to relegate the network request code and parsing to another thread but since the UI elements have thread affinity it's hard to get the information onto the main thread to be displayed. Does anyone know of any good resources for android threading?
I like to use the Handler class. When you post or sendMessage with it, it will always execute its command on the thread it was created in.
This Android Developers blog post covers a couple techniques:
Painless Threading: http://android-developers.blogspot.ro/2009/05/painless-threading.html
Have you seen this google.io talk about consuming services?
http://www.youtube.com/watch?v=xHXn3Kg2IQE

Categories

Resources