I have an application that is very image-intense, and I'm finding that I'm running into alot of OutOfMemory issues when loading up multiple activities.
The activities are all gridviews or listviews of bitmaps, and clicking on an image takes you to another activity that contains another set of images (sort of like an album of albums of albums of albums). The first 3 activities run fine, but when navigating further down, I start running into some serious OutOfMemory Errors.
After doing a stack dump with DDMS, it appears that the GridViews and Listviews of the previous activities are hogging all the memory. This is kind of expected, since they are showing lots of bitmaps themselves, but I'm not sure how the VM goes about freeing activities in the stack, and if they do it even when you havn't called "finish()" on them.
Do Activities recylce their views when they go into the background and then restore them when you navigate back to the activity, or is clearing the imageviews in my gridviews and listviews this something I need to handle manually on the activities onPause() and onResume() when navigating away from the activity in the lifecycle functions?
Please see my answer on OOME
Always call bitmap.recycle() after using bitmaps, since GC cannot clear memory held by Bitmaps.
The above link has a generic solution, please go through it.
consider recycling bitmaps onPause
Related
I am developing an android social media type application, where I have a multiple tab activity. The tabs are fragments using viewpager.I have a home screen with a recycler view. The post have images on them. I am having memory problem with the recyclerview for post. I am using firebase as a database if thats helpful. To load the imageview I am using glide and I am doing diskcache and skipping the memory caches.
Issues I am having are
When too many posts are loaded, recyclerview becomes slow and laggy (I know that there are other post with this but couldnt really found anything helpful).
When I click on a username from the post, a new profile activity starts which also have all the posts from that user, I am trying to find a way clear the homepage tab recyclerview memory but struggleing with how to.
To solve the first problem, I have set up an onscrolllistner that loads 10 new post everytime you are near the end of the post list. The recycler view adapter currently loads 20 items initially and then so on.but I am not sure how to clear the old posts in an efficient way since I want the user to be able to scroll up.
To solve the second problem, In the homescreen fragment, when I launch the new activity, the onPause() function gets called. In the onpause() function I tried setting the list to empty, recyclerview adapter to null, recylerview to null but nothing has worked. In the android profiler tool, I see that I am using 200 mb memory, and when I start the new activity, it adds another 100 mb or so. I tried manual garbage collections but it doesnt work either. To be specific, native memory jumps up in the profiler. Ive tested and made sure that was only because of the images in the recyclerview.
I am not sure why when I set recyclerview, adapter and the post list to null, why the images from posts are still being held in the memory.
Glide caches the images
To load multiple post check paging library
When moving to detail fragment and clearing the reacyclerview of home fragment , I would not recommend this as next time user switches to home tab ,the user will not have previous state saved which he left previously.
I have 8 different activities that open each other on a button click randomly. After clicking the button that opens a new activity around 15 times, it crashes. Do I need to close the activities or is there another solution?
As Harsh Pandey said, you may want to look into using fragments instead of activities. Another possible way is to call finish(); right after you start the next activity. This will close the previous activity. However, if you ever intend to go back to this activity using a back button or something, it will not exist.
When you create new activities and close them, GC will automatically clean up the memory used by the old activities when required. You are getting an out of memory error because,
Your activities are holding up a reference which is still alive. This will prevent GC from cleaning up the old activities.
for example,
Look for animations which are not cleared properly.
The best way to deal with this is find the memory leak.
https://developer.android.com/studio/profile/investigate-ram.html
Suggestion:
As 3kings mentined, try to do in one activity. ie Use Fragments !!
You can request more heap size by adding this in your manifest:
android:largeHeap="true"
However, based on your comment, my guess is that this case is ideally suited for fragments, instead of activities. You can accomplish all of that in a single activity, with multiple reusable fragments.
I'm making an android app with a menu activity and a game activity. Switching from the menu to the game and then back to the menu works, but as soon as you try to go back to the game activity, I get an out of memory error. The game activity loads in a few bitmaps, so in the onStop() method for the game activity I tried recycling all the bitmaps, calling finish(),and calling gc(), but none of it worked, I still get the out of memory error when I try to switch back to the game activity. I've tried researching this but so far I haven't found anything that helps. Is there any way to fix this and ensure my game activity is completely released from memory when it is closed?
OutOfMemory error occurs when your application did not get enough memory to proceed for object allocation. Check with the memory size given to the application since you are using bitmap memory consumption might be more. Please increase the memory limit and check the behavior.
Hi i am working with android , and i have a problem with the activity stack. As i know, when someone uses the back button, reload the back activity. But in the case i have many layouts shown from one activity, how can i go back to them.
Here is the deal, i am using a listview filled with categories, and when i press an item, i reuse the activity and the layout, to show its subcategories. So what i need is to came back no to the back activity, not to the back layout, but to the back "state".
Well, the idea is simple, first i show all the categories with no parent, then when i pressed an item, i show its subcategories.
The easiest way is creating two Activities - for categories and for subcategories. If you try to implement all the logic in a single Activity you won't earn nothing and just end up totally confused. Using Activities simplifies things a lot just because it handles problems such as yours. Hope this helps.
Check out Fragments, they are the stepping stone between a view and an activity. An activity can have multiple fragments and will manage their back stack (if you tell it to).
http://developer.android.com/guide/components/fragments.html
You'll have to use the support library to used them on pre honeycomb devices.
I'm making a game in Android and I'm trying to add a set of menu screens. Each screen takes up the whole display and has various transitions available to other screens. As a rough summary, the menu screens are:
Start screen
Difficult select screen
Game screen.
Pause screen.
Game over screen.
And there are several different ways you can transition between screen:
1 -> 2
2 -> 3
3 -> 4 (pause game)
4 -> 1 (exit game)
4 -> 3 (resume game)
3 -> 5 (game ends)
Obviously, I need some stored state when moving between screens, such as the difficulty level select when starting a game and what the player's score is when the game over screen is shown.
Can anyone give me some advice for the easiest way to implement the above screens and transitions in Android? All the create/destroy/pause/resume methods make me nervous about writing brittle code if I'm not careful.
I'm not fond of using an Activity for each screen. It seems too heavy weight, having to pass data around using intents seems like a real pain and each screen isn't a useful module by itself. As the "back" button doesn't always go back to the previous screen either, my menu layout doesn't seem to fit the activity model well.
At the moment, I'm representing each screen as an XML layout file and
I have one activity. I set the different buttons on each layout to call setContentView to update the screen the main activity is showing (e.g. the pause button changes the layout to the pause screen). The activity holds onto all the state needed (e.g. the current difficulty level and the game high score), which makes it easy to share data between screens. This seems roughly similar to the LunarLander sample, except I'm using multiple screens.
Does what I have at the moment sound OK or am I not doing things the typical Android way? Is there a class I can use (e.g. something like ViewFlipper) that could make my life easier?
By the way, my game screen is implemented as a SurfaceView that stores the game state. I need the state in this view to persist between calls to setContentView (e.g. to resume from paused). Is the right idea to create the game view when the activity starts, keep a reference to it and then use this reference with setContentView whenever I want the game screen to appear?
This question has been asked a lot. Did you read these other posts?
Android: What is better - multiple activities or switching views manually?. This link in particular talks about the Android Design Guidelines which "don't mention switching Views at all; it's centered around an Activity-as-View design."
Android - Should I use multiple activities or multiple content views
Android app with multiple activities
How to pass the values from one activity to previous activity
I'm not sure what you mean by the back button not always going back to the right screen correctly. I've got a game with a similar structure to yours, and the back button always takes the user correctly up the chain of activities.
Furthermore, using the onResume, onPause etc is somewhat necessary. What happens to your application if the phone rings? (Yes I know, some people still do strange things like using their phone to receive calls! :P) The OS tries to call the onPause method in your activity, but if that isn't implemented then your application won't act as expected. Another useful thing with onResume is it lets you update your tables as soon as the user returns to the view. For example, your player has just completed a level and is then brought back to the select difficulty screen. If you simply recover the previous screen from memory, it might not have been updated to take into account that a the level was just completed. However, if you put some code in onResume to handle that, then that will always be executed before the player sees the screen.
Lastly, you say transferring data around activities is a pain with intents - yes, that's probably true. But I usually find transferring any kind of complex data a pain, no matter how you do it. Are intents really that much worse, or is it just that things aren't as easy as you'd hoped? I don't mean any offense with that; I also often find things which intuitively seem easy to be rather frustrating to implement in code.