Why did performance of my Android phone app suddenly degrade? - android

I wrote an Android app with an Activity that creates a heavily-populated scrollable screen image. While it used to take several seconds to display the result, as of two weeks ago, it now takes two minutes. And it is not responsive to scrolling motions. Does anyone have ideas on why the performance of my app would change so abruptly about two weeks ago?
Some detail...
Several years ago I wrote an app that collects simple golf statistics. The result after this year is a file with 149 records.
I also wrote an app to display those statistics. For one set of stats, I have an Activity that creates a low-tech stacked bar chart as follows.
My layout xml has a horizonally scrollable LinearLayout within which I have another empty horizontal LinearLayout.
In my program I add vertical LinearLayouts to the empty horizontal layout. Each
vertical layout represent a stacked bar; there are 3 stacked bars for each record in the file or approximately 450 of them.
Then, to each of the vertical layouts I add small TextViews representing elements of the stacked bar. Two thirds of the vertical layouts have 36 TextViews, and one third have as many as 80 TextViews.
Then I color the TextViews to represent parts of the stacked bar.
So I build one scrollable view with almost 23000 TextViews.
I've used this app for several years. It took several seconds to display the resulting bar graph. Once the result was displayed it scrolled smoothly. That performance is acceptable to me, as my app doesn't need to be doing anything else during this processing.
Beginning about two weeks ago, it now takes some two minutes to display the result, and it only intermittently responds to a scrolling motion. This began when I started making changes in another Activity in the app. I haven't touched the Activity that creates the stacked bar chart, but, of course the whole app gets recompiled.
So I added some logging statements to the Activity, and, based on logcat, it now takes about 1 minute to create the LinearLayouts and TextViews and color all the TextViews. But the screen, remained black for another minute before the chart appears. During this time (ie. after the creation/coloring of bars) and also when I try to scroll the display, the logcat contains occasional messages of the form "Skipped xxxx frames! The application may be doing too much work on its main thread." This doesn't seem related to my code, as it has completed it's work by this time.
I've read about vsync. Is my problem related to that? If so, is vsync relatively new? If that's now the problem, is there a way to circumvent it?
As extra credit, I'm open to suggestions for more efficiently creating a stacked bar graph!

1 use recyclerview
Android recyclerview is the most advanced version of the listview. basically, an android listview is used to present a simple data set. if you want to display large data set in your app, you should use recyclerview.
2 Use constrain layout and avoid nested layout
It is a common misconception that using the basic layout structures leads to the most efficient layouts. However, each widget and layout you add to your application requires initialization, layout, and drawing. For example, using nested instances of LinearLayout can lead to an excessively deep view hierarchy.

Related

Android: swapping two elements on swipe, like Candy Crush

I am developing my first Android game whose main screen is composed of a 4x4 array of views, each view contains an image and a text. When we touch on a view and swipe it to the position of a neighbor view, the two views are swapped, just like Candy Crush. I've been searching for a couple of days but I haven't found any appropriate solution. I concern about the following problems:
Should I use GridView or simply an array of views for such swapping?
What kinds of event should I process for this requirement?
How can I add animation so that two exchanged elements seem to have a real moving effect.
Any help would be much appreciated!
This Link should point you in the right direction. Note this will also work with GridViews. You just have to add your desired rules for filtering which items may/may not be swapped with eachother.

Periodically change views

I'm trying to create an activity that consists of multiple layouts (imagine newspaper sections like 'News', 'World News', 'Sport'...and so on) that periodically change their content. So every x seconds a different news story is shown.
What's the most efficient way to do this in android?
I started out with my own layout. And just updated the different TextViews and ImageView programatically. That worked fine, except for image loading, as for the lack of view recycling the image was reloaded every time a certain story was displayed. This caused a noticeable lag (even when using Picassos image caching) as all the layouts were updating their news story at the same time.
Than I looked at ViewFlipper. Now I inflate multiple layouts programatically (one for each news story) and add it to the ViewFlipper (one for each news section). Once that is done everything runs pretty smoothly. But it takes ages until all those layouts are inflated.
So what's the best way to go here? I couldn't find any good examples online but maybe I'm just missing the right term to google for.
Thanks for any help.
Consider using a looping ViewPager. A ViewPager typically will preload the side of the pages when the current page is displayed, so that reduce the lag. There's a library for that. https://github.com/imbryk/LoopingViewPager. Hope this helps.

How to create UI only for the visible part of screen in a scrollView?

I am creating layouts at run time using heavy data, and adding these layouts to a scroll view. After the view get created, its working fine. The problem here is, the data is very heavy and it takes more than a minute to create the screen, which is not so good user experience. I want to create layouts only for the part of screen that are visible, and rest I can create on scrolling the scroll view. Pls suggest how is that possible? Also, If someone has a better approach, Pls suggest.
You can start by creating only a set number of views each time[1], but always add a dummy 'loading' view at the end of the list if there are more views 'pending'. As soon as the user scrolls the ScrollView at the end of the list, start loading the next part of views on a background thread, and as soon as they are built, remove the dummy loading view, and add the new views into your container.
An other approach would be to start loading the next group of views, as soon as the previous group is done finish, but that might be a waste of resources.
An even better approach, is to combine those two methods described, and always have the next group of views being created, if the user is halfway done scrolling to the end
You can check how to know when the scrollview scrolls to the bottom here: Android: Detecting When ScrollView Hits Bottom
[1] Since you care about UX I would suggest that the number of rows should depending on the row's height and device max height. I.e. 4 views on a small device, 6 on a medium, 10 on a large.

Getting Black screen between Activities-Android

I am not doing any network operation like downloading images or media in my Ui thread. i have a very complex UI that takes around 8 seconds to load and black screen comes in between , is there any way i can optimize it or show some kind of progress bar while my second activity loads its UI and remove the progress when i am done.
I cannot use asynctask doInBackground() since everything is UI only --Like For loops for creating LinearLayout childs dynamically, Putting views side by side on relativelayout and reordering them as per business rule. changing various image colors as per business rule etc.
Is there any way i can optimize this and reduce loading time?
Why you need such a complex layout in the first place? if the layout is too complex then it should NOT be. Try to find a simpler layout, if you must follow the current layout then I suggest an idea but it is not recommended.
Here is the idea, it's based on iOS development, you should take a snapshot of the complete layout (without any actual content, just layout) and display on top of your layout when you first load your activity. After all of your underneath layout already loaded, then you remove the snapshot on top and make the real layout visible (all the process must show the loading progress to avoid user interact with your UI). Although this is not ideal, it should help in your case.

Dynamically removing and adding views when needed

I have looked at this topic to dynamically add views when needed: Add and Remove Views in Android Dynamically?
However, I have a few questions.
1) Will there be a visible stutter or lag when creating these views on the go? For example, I use a panel system where each panel holds a separate view. However, these panels could reach a high number in quantity (40 odd panels?) when the program is complete. In order to preserve resources, I want only the view that is currently visible to actually be created, and the others views to not be instantiated until they are brought into the visible region. I have been told to use a ViewFlipper, but due to animation and user interaction requirements of my program, I cannot use a ViewFlipper, but have something along the same lines that I have created.
For example:
Imagine one of my "panels" to be pretty much like a screen in the Android Home launcher. The thing with the Home Launcher is that all it's views can be kept alive at any given time, because there's only really 7 of them. However, seeing as there are closer to 40 in mine (not all left and right, some above and below as well), I cannot have them all instantiated at the same time, or else the phone will begin to lag.
2) What is the code to destroy the views once they aren't in the visible region?
My program will determine when the panels are in the visible region or not, hence I will only need the code to destroy the views on the go.
Thanks.
Why don't you use a ListView or a GridView?
If you are not willing to use some of those, you will need to do something similar to what they do with the Adapter and how they recicle views.

Categories

Resources