AppWidget: How to retain static objects between updates? - android

I am creating a AppWidget that consists of a ImageView that gets filled with a custom rendered bitmap. This widget is refreshed every minute (using the AlarmManager).
All the rendering and storage is done in the AppWidgetProvider.
Being a good citizen I wanted to minimize CPU usage etc, so I had my Paint objects and other pre-calculated values stored in static fields in the AppWidgetProvider.
However, it turns out that my AppWidget process is very eager to die on me when it's hanging around with the cool kids doing nothing. I understand this is standard behaviour. However, with it's tragic death, it also takes my precious statically stored objects with it into the grave, never to be seen again, which is a lot less convenient.
My mourning doesn't solve anything, so I wonder: is there a way to deal with this? Or is there just no way to do that, and should I fall back to reinitializing everything on every redraw?

Not a real solution, but I solved it by not caching all the stuff.

I am doing something similar -- creating a clock widget -- and have discovered that it's even worse than you think. Android isn't merely killing the AppWidgetProvider when it gets tired of having it around. It's killing it IMMEDIATELY and recreating it for EVERY update (as print statements in the constructor demonstrate).
This is a problem if you, like me, are doing something memory-intensive like drawing a rather heavy object to a rather heavy offscreen bitmap.
The best solution I can offer you is to try handling the maintenance and storage of your objects in something more persistent -- say, the configuration activity, or maybe a service. Seems like overkill for Paint objects, though.

I'm not sure what sort of precalculation you are doing, or what sort of data is being saved, but Android will tell you when it is about to kill your AppWidget. You can use that as an opportunity to some sort of persistent store. You would still have some processing in serializing/deserializing the data, but it could be faster than recomputing.

Related

Android Traceview - It holds the Answers to my Unresponsive App... I think

Yesterday, I spent 12 hours becoming a student of Traceview. I didn't even know it existed (hangs head in shame) previous to this.
Now that I've overcome the absolute shock of the data it produces, I find Traceview can be boiled down into a couple simple concepts:
Sort by "EXCL CPU TIME" to determine exactly how much usage each individual method is using in isolation.
Look at the frequency of calls and the cpu time/real time per call. Obviously higher calls should be looked into. In most of my experience, if you sort by #1 above, methods which are called too much and take too much time will also be at the top of the list (makes sense as they are also using the most CPU).
Anyway, doing these two steps above I find 3-4 methods which are always using 90% of my CPU and taking up most of the real time delays in my app. The only problem is, none of these methods are methods I wrote, they are system methods such as:
BitmapFactory methods
WebKit methods
And other system methods
This being said, is it a correct to assume that if the top resource hogs are system methods, then it must have something to do with my design of my layouts? I am at a loss as to how BitmapFactory could be so high, my layouts aren't extremely complicated, though in one Activity BitmapFactory is taking 95% of resources itself.
TL;DR - If I run a Traceview, and if I find the top hogs of resources are all system methods, does this mean it's a layout issue? Or, how else can I tell why the system method is so high as it doesn't relate directly to my custom methods.
Thank you very much,
Ryan
I find Traceview can be boiled down into a couple simple concepts:
Those concepts are not the best, IMHO.
Sort by "EXCL CPU TIME" to determine exactly how much usage each individual method is using in isolation
In particular, this concept is fairly lousy IMHO. Yes, this is useful data. However, you then need to work back up the call stack to try to figure out what is triggering this. Sometimes, it will directly be your code. Sometimes, it will be something else that you recognize that is part of the framework (e.g., onDraw() of a View). Just knowing that some random method is taking up a bunch of time does you no good until you identify what is triggering that method to be invoked in the first place.
If I run a Traceview, and if I find the top hogs of resources are all system methods, does this mean it's a layout issue?
No.
Or, how else can I tell why the system method is so high as it doesn't relate directly to my custom methods.
Work your way up the call stack to figure out who is calling these methods so frequently, or at inopportune times.
For example, in the BitmapFactory example, you will probably find that you (or a library that you are using) is calling BitmapFactory, and perhaps is doing so on the main application thread.
To work your way up the call stack, click the triangle on the left edge of the row representing some method of interest. You will then see two branches beneath that: "Parents" and "Children". The "Parents" represent the next level up the call stack from the method, and you can continue working your way up the chain of parents until you find something that you recognize.
That's why, IMHO, you are better served sorting by inclusive time, as your code (where it directly is the culprit) will tend to bubble towards the top.
Well, I found the problem and it's bitter sweet. It's sweet because it wasn't my code nor layout causing the problem, it was the admob AdView using the loadAdOnCreate="true" to create ads. It's bitter, because I now may have to switch sources of revenue if I can't remove the loading delay created by the AdView! That was a tough one to find, I should have anticipated this though!

Executing 120k queries in android

I am doing some sort of benchmark for sqlite android. If I were to pre-load total of 120k before executing, will most device have enough memory? While the queries are executing, there are also other threads that are going on so memory might be the problem. How can I make use of the onLowMemory() method? There doesn't seem to be much examples on using that method. Thanks for any advice.
Making use of the method is as easy as overriding it in your Activity.
However, read the documentation carefully:
This is called when the overall system is running low on memory, and
would like actively running process to try to tighten their belt.
While the exact point at which this will be called is not defined,
generally it will happen around the time all background process have
been killed, that is before reaching the point of killing
processes hosting service and foreground UI that we would like to
avoid killing.
Applications that want to be nice can implement this method to
release any caches or other unnecessary resources they may be holding
on to. The system will perform a gc for you after returning from
this method.
I'm not sure (and the docs don't define) if "background process" includes AsyncTask instances and services, or just backgrounded applications, but I would guess so.
So, when this method is called (if it is ever called) the System has already killed everything it could (with lower priorities than your Activity) and now asks you to release any unnecessary resources in memory.
So, If you want to react on low memory, this might be too late already.
As for the general question if most Android devices would run out of memory, I don't know. The problem is, that devices vary a lot.
I also find it hard to imagine any real live situation, in which you would need to pre-load (or stack) 120k queries before executing. You could easily stack 200 and commit those, than stack another 200 and so on.
I'm not sure why you need to benchmark this, but please don't execute 120k queries for default entries in your applications database.
You can deliver your application with a filled database and copy it over from the assets/-folder. See android-sqlite-asset-helper

Static variables in Android and low memory - a few questions

In my app, I use a static variable to hold the current user id. There is a bug that is very hard to reproduce of this user id simply disappearing. While it could be related to a bug in how this variable is set during application loading (I still wasn't able to reliably reproduce this situation in a controlled environment, so I'm not really sure exactly what happens), I'm starting to think this is related to how memory gets reclaimed from static variables (something I didn't consider before).
So, when can my static variable simply disappear?
As far as I understand, static memory can get reclaimed if the OS reports low memory - can it happen while the app is in the foreground? Or only background?
Are there any possible ways static memory is getting reclaimed without a low memory condition? I think sometimes the variable disappears without the app even going to the background and I'm not sure any low memory events occur (AFAIK low memory refers to the whole OS, not the app's memory)
What is a good way to simulate static variables getting reclaimed by the OS to see how the application behaves and subsequently fix the bugs?
Anything adding more clarity to my understanding will be appreciated.
Thank you.
This is question super, super old, but I was writing a blog post and mentioned seeing this. I have no idea if you're still working on this app (doubtful), or if you're still seeing this issue (also doubtful). My guess is you set these statics in the Activity that your app launches with. Of course, if your app gets shut down, then restarted, you won't go through that activity.
Lazy loading statics, or initializing them in a custom Application object generally takes care of this.
I've done a fair amount of research on the "statics removed in low memory" idea, and the basic answer is it doesn't happen. Ever.
I suggest you are not using static variable to hold the current user ID as the static variable is not one of the best way to store your data (I assume userID as a data which will remain on every session of your app, except when the user is logout).
The simplest way is to go with Shared Preferences. Look at the Android Data Storage to read the best (practice) way to store your data in Android.
From your need, I guest you should go on with SharedPreferences. No more problem and you don't even need to simulate any variables reclaimed by the OS.

Android Game Development - Level progression methods

I am currently developing an Android game that is similar to a classic arcade space shooter. Thus far I have almost everything finished, but my code is not quite to my liking and I am trying to find out how to improve it.
The problem I am having is with enemies and other objects entering the screen.
Currently I am using a Runnable object that I pass to a thread, and in this Runnable is an array of all of the distances that will trigger new enemies to come in from the top or sides of the screen. In the run() method, I check the time and if the System.uptimeMillis() is greater than or equal to an element in my array, I fire another method that uses a switch statement to determine the event to run.
This is all becoming quite a hassle to manage and that is why I was wondering if anybody know of a more efficient and neater way to manager the queued enemies.
Also, my array I create is of 200-some objects and once they are off the screen I was nulling them. Obviously this was firing of the GC too often for a well-performing game. Is it best just to reuse enemies that are destroyed or go off screen? Or is there a better way for this as well? (I am just ensuring that my program is the best it can be before it ventures into the wilds of the Market)
Thank you in advance,
-Roflha
I suggest you look at this code for reference. It has a good way of dealing with objects, collisions and stuff.
And its written by a google employee which always sounds cool for some reason.

how do "saved states" work? (Android)

I just read a pretty interesting article on how android (and i assume other OSs) work when low on memory. How is this done theoretically? Is it similar to Java's object serialization?
In a word: yes.
In a few more words, sort of. You have to handle more of it manually than personally I'd like. Essentially, all Android provides for you is a hash to shove a few serializable objects, referenced by strings, that is guaranteed to be safe across application shutdowns. So, whenever something happens that you'd like to preserve across a shutdown of your application, you are responsible for updating this saved state hash (and letting Android know that you've done so). This includes things like half-finished text entry in form fields. That means you have a lot to listen to.
Android will then call a particular hook in your Activity that handles restoring state to the Activity when it recycles your application and you need to do so. This doesn't happen for all recycles — there are various states of being/existence for your application.
The screwy part is that because you're expected to do this sort of tedious work anyway, Android gets lazy and implements things like screen rotation as a full recycle of your application.
I'm making it sound worse than it really is once you get used to it; it's really not a bad way of solving the problem in the confines of Java and mobile computing.
Of course, this is a response regarding Android. Other (desktop) OS's rely on Virtual Memory and Paging to deal with memory constraints.

Categories

Resources