How to improve Room query times - android

I'm using Android Room and combination of LiveData in my app successfully, but I notice it has a significant delay between query and presenting the data to the UI. It is not the end of the world, not unsustainable at all, but when opening other messaging Apps (like WhatsApp) the difference is monumental. When I open such an app the conversations and messages are already available, there isn't even time to play the fade in default animation that is typically available in RecyclerView lists.
On the other hand in my app I can clearly see the delay the data takes until it is presented to the UI.
I understand that attaching the viewmodel to a fragment means that same viewmodel is reconstructed every time the associated fragment is rebuilt, so in theory attaching that viewmodel to the activity's would mean that data would survive even longer in memory, thus saving loading times when rebuilding the fragment, but the very first time it loads it still will show that significant delay, so this isn't an ideal solution nor do I know if this would be an ill advised modification (attach the fragment's viewmodel to the activity lifecycle instead of fragment's).
Are there any ways that I can improve this? Is perhaps WhatsApp using a completely different SQLite library that is marginally faster than Room so I will never be able to achieve this performance with Room?

I think, you have to investigate the issue before try to fix, possible bottle necks:
slow database queries
reasons:
huge amount of data
not optimized queries
middleware converts (if you use it)
Just calculate a middle time for 5-10 calls.
slow UI drawing
check your RecyclerView or other UI.
Use AndroidStudio profiler to find out potential slow code.

Related

Performance issues in android

Hai I'm developing an android app that contains many fragments, Recyclerviews, Layout.
My app's performance was very poor. Suggest me a correct way to use the Recylerview, Fragments and activities.
Assume that my recycler view is a timeline like in instagram/facebook. So i have so many onClickListeners, image loading(I used Glide), and some calculations(basic calculations like Time, simple loops...) and few function calls.
I have implemented onViewRecycled() and in that, I have unset all the listeners and freed the loaded images using Glide.clear(img).
When I used the profiler to lookup the memory usage, it shows >1 GB in android 6.0 devices and >250 MB in android 7.0 devices.
And I'm loading images and text data from the Firebase Firestore.
My problem is even after doing all those things, the performance of my app is very low.
So please help me to improve my app's performance.
Thanks in advance!
Use Loaders! A background thread started by doInBackground(Params…params) will not be destroyed along with Activity Lifecycle onStop() or onDestroy(). And an attempt of modifying activity state on basis of it’s result can cause in crash! It takes up your memory when doInBackground again and again. Or else you can implement Volley or retrofit for network call etc.

Android: using a Singleton to load data from the network

So here is a very standard task in Android: load data from the server and display it on the screen. One of the biggest problems is, of course, handling configuration changes. For example, when loading is started and device is rotated, the loading must not be started again and loading progress must still be shown.
Now, there is a ridiculous number of ways people approach this basic problem. Let's say, we use the Model-View-Presenter pattern. A lot of solutions revolve around saving Presenter, entirely or partially (in the View's bundle, in a Singleton or any other way), to not lose data on rotation. Others involve Retained Fragments and AsyncTasks. And I quite rarely encounter a solution that uses a Singleton to perform loading data! Why is that?
Here's the way I think it can be easily done. We make Presenters "light" and not perform any state saving, and handle data loading in a Repository that is a Singleton. When device is rotated, the newly created Presenter can just get current loading status from the Repository, update its View accordingly and, if data is loading, resubscribe to the Repository (via callbacks or RxJava Observable) to get notified when data is loaded. As for the Repository, it can easily load data in the background with the help of RxAndroid. So, isn't it easier to handle all data loading business in one place and not worry about activity's lifecycle?
This way we basically skip the whole configuration change problem. There are only a couple of things I see that must be handled carefully:
Activity leaks in the Singleton. To prevent this we just have to unsubscribe Presenter from the Repository when its View gets destroyed.
Testing, as it is harder to test a Singleton. But this is not an issue if we use Dagger - in this case we can test out Repository like any other class.
So my question is this: why is this approach (performing data loading in a Singleton) is not a common solution? What am I missing?
I seriously recommend you read up on a library specific for the purpose of network requests, rather then trying to reinvent the wheel and having to deal with all the pitfalls which might arise.
Recently I've been trying out RoboSpice. If you read up on their page below, you'll see that it "executes network requests asynchronously (in a background AndroidService)", precisely to avoid memory leaks.
I say, give it a try! Lots of projects in my workplace make use of RoboSpice and they all work pretty well.
https://github.com/stephanenicolas/robospice

Is it bad to have a lot of AsyncTasks for simple database actions?

There is a settings screen with multiple categories and each category has 5 to 6 its own settings. Just imagine settings screen of Android OS.
Now, to avoid having Set button on the bottom and trying to implement application of changes immediately upon a user changes any settings (thus to gain speed in the app and to have a better user experience), I thought of having dozens of AsyncTask classes, each implementing just a simple thing.
For example, there is a settings screen with 4 things to set. A user changes setting no.1 and I immediately call AsyncTask for that specific setting in the background. And like this for each change a user makes.
How smart is to do this? Would this overload AsyncTask idea or even come to the point that too many AsyncTasks are called consequently (I read that there is a limit of AsyncTasks that can be called, 5 or something)?
Is it a better design to call 1 AsyncTask with all changes when a user leave the specific settings screen?
Note: I am not asking here how to implement AsyncTask. My questions is directly bound to best design and the best speed of the app, as well the best UX.
You should not use asynctask when you have more than 1/2 operation(s) a minute or so (Quote in Android pushing the limits). You allocate a lot of objects and I peronally found that it looks like the Asynctasks are waiting on another. Maybe use a handler/runnable.
On a site note, you can save all the changes in variables in memory and then periodically save the settings to a backing store. There is nothing faster than just setting an instance variable/array.

Android AsyncTask vs. Threads for a specific case

I am working on an application that Looks similar to the Google Play App (swipe view with gridviews inside the fragments, in addition data in the gridview [image + text] is retrieved from a remote server).
My problem is with background tasks. I can’t decide what to use for retrieval of data from the internet. Mainly I am trying to decide whether to use AsyncTask or manual threading.
Of course it would be easier to implement AsyncTask, but after some research I noticed that many people find it limiting.
In my particular case, I want to download data from the internet as Json Objects, parse them and display the data in the gridview. The gridview would have up to 30 items, each item contains a thumbnail and 3 textviews. In Android documentation, they say that AsyncTask is suitable for short operations (few seconds at most). Would filling up to 30 items be considered as a short operation?
I want the data to be fetched concurrently. Also I want to support Android phones from API 8 and above. I read that for different APIs AsyncTask behaves differently (serially or concurrently)
My question is: Is it appropriate to use AsyncTask for my app? Or do I have to do everything manually? Is ThreadPoolExecutor a 3rd way to do this? Is it easier than manual threading?
Any advice would be appreciated, I can't move forward in the implementation without deciding on this issue.
Thanks in Advance!
My understanding is that the comment about using AsyncTasks only for short operations is aimed more at not expecting the same views to be available when a long operation finishes. For example, if a user leaves the app and comes back or the current activity goes away for some reason. Typical ways around this would be to use a Service and start up a plain old Thread there, then send some message telling the current Activity to refresh when the operation is done.
The download and processing of your data is likely to be the longest operation. So I'd use that as a basis for whether this is short or long. If you don't care about persisting data at all and don't mind restarting downloads if a user leaves and comes back, you can just use an AsyncTask with very little thought.
If you are using a GridView, you should only ever be populating enough views to for just over the number displayed on the screen at one time.
I'd say that AsyncTask is fine in your situation assuming it's a few kilobytes of data and not megabytes or hundreds of kilobytes. Megs of data, I'd say move to a Service with a Thread. Hundreds of k, is a toss up.
Also, take a look into Loaders... if you want to see an alternative that is better for this kind of loading.
When attending DroidCon in London last year, a presentation brought to my attention why using AsyncTasks for loading data from the network is unreliable.
This presentation was about the RoboSpice library.
The site also has a very nice infographic explaining why exactly AsyncTasks are unreliable and what RoboSpice does to amend these problems.
Disclaimer:
I am in no way affiliated with RoboSpice, nor have I ever tried it. I was just impressed and convinced by their presentation that it's a tool worth trying.
Friend, I am working in a project exactly as you need, and to support API 8 and above you should use Asynctask to download anything or you will get a crash for API 15 and above, because it won't even let you run your app without AsyncTask even for short operations.
So as I almost did everything that you need and it is working very well for API 9 above, you should use Asynctask, I´ve implemented SherlockActionbar, EndlessAdapter and ViewPager all with AsyncTask, so go on, if you need more help just ask again later.

Content providers: wrap with a static facade?

I am going through a bit of a design dilemma, I have been targeting Android 2.3.3 and have a custom implementation of a ContentProvider. I then have a class of static methods to abstract the Content provider - providing me with objects representing each entity (row) based upon my query. For a while I was very comfortable with working like this, until I started wanting to use the whole collection in a number of places, for performing "hit tests" and drawing to the screen. I then had the headache of keeping my object representations up to date, and at this point have decided I need to step back and reconsider where to take this.
As I say, I am presently using 2.3.3, and realise that in 3.0 CursorLoader overcomes a lot of the problems I have encountered. I still need to support smart phones though, so unless there will be a backport I cannot do this.
As an interim solution I started to register notifyChange listeners so that I can rebuild a collection with my original query, but this strikes me as very CPU intensive and potentially slow. I haven't yet decided whether I should roll back from using my static facade and instead use the now obsolete managedQuery call from Activity.
I therefore have two questions:
1) Is there a preferrable way to avoid the issues with working against a collection based around a contentProvider?
2) Have you any advice on working with raw cursors in an activity? Should I be making objects out of them or working with the cursor as-is? I certainly feel they should be in an AsynTask while performing the query, but after that can I use them anywhere?
Ok, well I came to a decision and it works reliably.
1) Is there a preferable way to avoid
the issues with working against a
collection based around a
ContentProvider?
I have decided that the approach I took was correct; In my situation it is preferred to make a cache rather than maintain a cursor (managed or not) to the ContentProvider; this allows me to reuse methods and reduce the amount of code that requires testing. NotifyChange listeners are important until working on 3.0+ and that means I should guarantee the NotifyChange is called - another argument for centralising all of this code, so that it indeed triggers the changes when expected.
2) Have you any advice on working with
raw cursors in an activity? Should I
be making objects out of them or
working with the cursor as-is? I
certainly feel they should be in an
AsyncTask while performing the query,
but after that can I use them
anywhere?
In my use case I have decided it is a matter of thinking about what it is I am planning to create - avoid unnecessary work, with respect to returning unnecessary rows & fields and potentially creating unnecessary objects. If I am looking to create a map of entry names and entry IDs then I shouldn't be getting all of the other fields too. Abstracting from the collection is good but it must be lightweight and take in to account how the data is used - whether it is a one-off or may be used repeatedly. It is important that it is written for performance rather than completeness.

Categories

Resources