Global object (based on "extend Application") evaporates overnight.. why? - java

I have an android app where I extend the application object as such
public class Globals extends Application {
private Map<String, Object> Creators = new LinkedHashMap<>();
}
Globals has various things in it. usually HashMaps of things - I use it as a global json cache where each Context has an instance of this. Now overnight it appears the Application object can sometimes be empty. i.e. I use the app go away and go to sleep, go back to testing it in the morning and all the json caches are empty. But the user is still "logged in". I assume this is because of garbage collection on the OS.
Now. I could just refresh the json cache or force "logout" when the json cache is empty but there is a problem - it may be empty because there IS legitimately no json from the server. i.e "being empty" is no reason to go get more. What I need to be able to do is detect when android has flattened the cache, or at least know the minimum amount of time that Android will keep the Application extension.
Would it set everything to null?
Has anyone got any ideas? Bear in mind the context will re-initialise null HashMap members of the Application in the context in onCreate (which is required for reason outside the scope) because I declare the new but simply testing for "null" is not really an option. I suppose making a blank null that is changed only on json gather would be ok but I need to KNOW this will work or I lose yet another day chasing this (i.e it's VERY hard to test)

Now overnight it appears the Application object can sometimes be empty. i.e. I use the app go away and go to sleep, go back to testing it in the morning and all the json caches are empty.
Your process was terminated, most likely. See the documentation and the documentation.
What I need to be able to do is detect when android has flattened the cache
You are not informed when your process is terminated.
or at least know the minimum amount of time that Android will keep the Application extension
Your process can be terminated milliseconds after it leaves the foreground.
[Application works] fine as a data store
Only for data that you can easily reload from a persistent data store.
[Application] works works on multi thread
Only if you add your own thread-synchronization logic. There is nothing magic about properties and functions on Application that makes them thread-safe.
where there is no place to store mutable data - this is the best alternative
Any data that you wish to keep should be stored on disk (database, SharedPreferences, or other types of files) or on a server.
so my question remains how to mitigate it
Any data that you wish to keep should be stored on disk (database, SharedPreferences, or other types of files) or on a server. Use in-memory caches as caches.
because things like SQLite are useless they're not thread safe
If you use the same SQLiteDatabase instance for your operations, SQLite is thread-safe.
effectively making it impossible to run anything in parallel
You are certainly welcome to use other persistent data stores if you find SQLite to be distasteful.

Related

Use of global variable in never ending service

I created a never ending service but I'm not sure that it's OK to do what I did with this service. I declared global variable like static String list_contact
and fill the list from a db in onCreate method. I wanted to avoid to retrieve data from database each time because I need to compare to the list fast. But maybe it's a problem to store data in global variable of Service. Plus I need another list with thousands of data. If it's no good, can I find a compromise between memory and speed for retrieving data ? Thanks.
Its not a great idea put the static variable in Service and assume that service would run forever.
The biggest drawback is, service won't run in background forever, starting from Android O. Latest version applies more restrictions on the background processing and kills your service few minutes after app is put in background.
You can implement Object pool pattern which will store the frequently accessed data in an Object. This doesn't require to have a service running and could serve your purpose. You need to ensure that you are not maintaining sensitive data in clear text in these Objects.
Alternatively, you can also read this post which describes caching for Android.

java.util.ConcurrentModificationException in XPages

We have this multi-page browser-based application in XPages. The main window contains 5 frames with different pages, a 2nd (and there may be more) contain documents, all with a different page layout. We used to run the application with "all pages in memory" (coming from R8.5.1 originally), it was lightning fast but hogging memory. We're now in the process of moving it to "one page in memory, the rest on disk".
I think the situation we have right now is this:
all pages share the same sessionScoped bean
page A is refreshed automatically: every minute an Ajax request is sent to fetch data
page B happens to be serializing a HashMap at the same time
the refresh of the first page changes the HashMap being serialized
The HashMap is an object inside the bean. Why is the bean serialized? I might be mistaken, it might just be a different HashMap that's being serialized...
Anyway, my question: how can I synchronize these actions, is there some easy way?
PS I already tried with a ConcurrentHashMap, but I got some very weird results...
Thanks for anything helpful!
"Why is the bean serialized?" A sessionScoped bean would not be serialized by default. It can happen if you use a load-time binding that evaluates to the bean like ${someBean} or if its serializing the HashMap you might have referenced that in a load-time binding, like ${someBean.someHashMap} (where ${ is load-time bindings, and #{ are runtime bindings ). The results of load-time bindings are saved in the control tree, which is serialized when you're saving server-side pages on disk. The solution there would be to change those references to runtime bindings.
"how can I synchronize these actions"
There's a synchronized keyword in SSJS, see:
http://mattwhite.me/blog/2009/9/14/on-synchronization-in-xpages.html
but that can only protect the object from concurrent access in SSJS; the page state serializing won't be synchronized on the same object, so you'd still have to fix it to not-serialize the bean&HashMap.
As always when encountering an error like this you should ask yourself why and read the documentation for the exception. This exception occurs because you modify a collection while iterating it (eg reading from it). For this exact reason Java ship with a collection implementation called CopyOfWriteList which allows writes while reading. It does this by making a new list (eg copy the pointer) when the list is written. This is great when writes are less frequent than reads. Unfortunately there is no such thing for Maps built into the jdk.
My suggestion would be to encapsulate the map and implementing a similar feature so a new map is created on new data. This would make the map immutable for readers and hence would remove the concurrent mod exception. Users that read while new data arrive would get the "old" data but it would perform much better than synchronizing access.
Hope is helps.

Best practices to get data and save it

I have an android application and in one of my activities I am making a call to get say "Customers", this call is made to an external API, when I get the response I get it as a JSON object. The problem i am having is that I have a ListView in the activity and when you click on of its items it shows you the details but then when you hit the back button I have to make the call again to populate it. In Samsung Galaxy 4S it seems to keep the data of the list view but in the HTC android incredible it's blank. So what I did is, make it rebind OnResume(), this fixed the issues for both BUT the consequence is making another call to that server. When its 10 or 100 customers it doesnt matter but I know that there are some accounts that have up to 5000 and I am sure it will crash.
What are my options to improve performance on this issue with Android?, I tried a static variable but at some point that object got cleared too.
How do Android applications usually handle this cases where the data is retrieved from API's and they need to be stored through out the application and there is no need to make another call for the same information?, I was thinking on static object but i want to make sure I do this the right way.
You have a couple of options.
1) You can cache the data in memory. For example you can make a static cache or cache the data within the Activity or the App object. If you are doing this in only one view and if it is not a lot of data, this might be an ok solution. However, if you have to do this for many activities and there is a lot of data that has to be cached, you might want to go for option 2. Also storing data in memory in android, does not mean it won't be garbage collected (in some cases, even if you have a reference to it.)
2) You can cache the data in the internal storage and refresh it from time to time.
You can find more info about the internal storage and how to use it here: http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
Basically, you store the response within the internal storage under a specific identifier. The next time you open the activity, you check if the storage has data for that identifier and if yes, you read it and display it. If no, you make the API call.
Keep in mind, that you will have to refresh the cache from time to time.
I had the problem with ListViews on my application too. What I did is that I wrote a custom adapter and that solved the issue..
However the thing you can do is to make a global variable and save the returned results to it. When your application wants to call the server, check the variable, if it's null make the call, if it's not then just draw the ListView with the already fetched data..
Keep in my mind, to implement a refresh button, you need to skip the check.

Switched from singleton to application object, still getting null pointer exceptions

I switched from a singleton to an application object to store application data because as I understood it, there was a much better chance of my cached data surviving in an application object, than in a regular singleton.
I am still having issues however. If I switch to several other apps, and come back to my app, the call to load my event after i've loaded getApplication() is throwing an null pointer exception.
What I find even more bizarre, is that the bundle from my original intent, is still active and has survived the application switching.
How can I keep data, which doesn't necessarily need to be persisted in a permanent way (if the entire application were killed, and reloaded, it would just pull it down from the webservice and start fresh, this is why I thought switching to an application object would be ok )
Are you looking to persist data relating to when your application is put into the background by the user, and then brought back?
Perhaps overriding the methods onSaveInstanceState and onRestoreInstanceState, and storing and recovering from a bundle is what you are looking for.
http://developer.android.com/reference/android/app/Activity.html#onRestoreInstanceState(android.os.Bundle)
http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
You may then want to define a Parcelable interface
http://developer.android.com/reference/android/os/Parcelable.html
on the classes you wish to store.
Alternatively You may also use the shared preferences api.
http://developer.android.com/reference/android/content/Context.html#getSharedPreferences(java.lang.String, int)

How to apply static class in php

I am java and php programmer.
In java i can use static class/method so that anyone can use the same one time created class during run-time.
But for php how to do it since it is script based and only run while we refreshing the page?
My main objective is, I want to use syncronized class/method so that it wont clash while executing the PHP...
Need your help to give input.
Thanks
Update:
I am doing portal like multi level marketing(mlm)
Once register a member, we should pay bonus to the uplines
I don't want immidiately calculate the bonus because it is risky and could take some time to finish, so is is better just to register the member and show successfull.
My idea is, after registration, just invoke another class to run bonus with syncronized method so that the bonus calculation will not disturb by another registration.
Given that a php scripts runs from new every sinlge time a "static" class would not be very different from an ordinary class.
If you want to store some sort of state or preserve some data between runs of a php program then there are a number of options.
SESSION variables can be used to store data between requests from a single users as long as he keeps the session open.
COOKIES can be used to store data which persists between sessions as long as the user is using the same browser, on hte same machine and hasnt emptied the cookie jar.
memchached and similar packages can be used to store data and make it available to any php program on the server.
Databases are the most scalable solution as they will persist data between sessions, and between servers. There is some overhead involved is establishing connections and retrieving the data compared with the other solutions.
PHP is shared-nothing. Everything just lives for the Request. If you want to share information between Requests, you have to implement some additional technology layer that can do so. Or look into process control, shared memory segments and semaphores. The latter three are uncommon usage in PHP though. And all of the above will still be asynchronous.
To my knowledge, there is no way to update class Foo in one Request and have it change state immediately in a concurrent Request with PHP.

Categories