Singleton gets recycled - java

I have a singleton in Android for data loaded from xml. It gets recycled from time to time and I don't understand why. Singleton should exist through the lifetime of app process by my knowledge. Here's my singleton:
public class DataLib {
public static CategoryList categories = new CategoryList();
public static RegionList regions = new RegionList();
public static CompanyTypeList types = new CompanyTypeList();
public static SearchData searchData = new SearchData();
public static CompaniesList companies = new CompaniesList();
private static RegionData currentRegion;
private static final DataLib INSTANCE = new DataLib();
protected DataLib() {
}
public static DataLib getInstance() {
return INSTANCE;
}
public static void loadData() {
loadCategories();
loadRegions();
loadTypes();
}
/* ... some more static functions are here ...*/
}
As you can see it is not instantiated by any activity directly but rather by the process itself. The data are loaded by calling DataLib.loadData() when the application starts = activity which will end when the data are loaded.
I cannot tell for sure what triggers the recycling - sometimes app needs to stay in the background for longer time, sometimes it's in a few minutes. I am logging the pointer of the DataLib class so I can tell that it truly changed = got recycled.
Any ideas? Thanks.
EDIT: Answer is partially in marked answer + comments to it.

It gets recycled from time to time and I don't understand why.
Android will terminate your process "from time to time".
sometimes app needs to stay in the background for longer time, sometimes it's in a few minutes
The OS and the user can get rid of your process whenever they feel like it. Singletons and other static data members need to be caches for persistent data, loading that data using background threads and the like.
If there is particular work that you are doing in the background, you should be using a Service for that, to indicate to the OS that you are doing work in the background independent of any activities. That does not prevent Android from terminating your process (e.g., at user request), but it will make it a bit less likely to terminate your process on its own (i.e., the OS will tend to choose other processes).

Related

Reasons for objects becoming null in Extended Application class

In my android application, I have extended Application class. I am having some meta data which I do not want to re-initialize again and again. I initialize them in Application class and then use them.
private SampleSettings getSettings(){
return sampleSettings;
}
public class SampleApplication extends Application {
public void onCreate(){
super.onCreate();
sampleSettings = getSettingsFromDB();
}
}
Here getSettings returns null in some cases when accessed in application using applicationContext.
Sometime I am getting null pointer exception for such properties. I have seen when the app goes to background it occurs but not frequently.
My understanding is that those values should not become as long as application is started.
What am I missing which is causing them to become null?
Thanks
Your process does not live forever. When you are not in the foreground, your process may be terminated at any time by Android, to free up system RAM for other apps.
A custom Application object, or any static fields, are only for caching and other in-flight data. Your app needs to be able to start up, from any activity, lazy-initializing all of that as needed.

In android, how can I separate the data loading into its own thread?

So I'm working on my "hello world" application in android/java, and elected to do a sports app (which is strange...I don't like sports...but whatever). So I set up my layout, allow users to 'drill down', so they can see the layout for Baseball, or MLB, or the Indians. Say a user selects 'Indians' from the MLB view. I update the tabs, potentially the color scheme, background, etc, and load the data for the 'news' and 'players' tabs (the latter of which is unique to team layouts). Unfortunately, api calls can sometimes take relatively long to complete, especially when the free API from ESPN is capped at 1 call per second. I do some significant caching already, but there's no way I can guarantee that I won't be loading both 'news' and 'players' for 'Indians' at the same time, so one of the requests will have to wait a full second to return.
So my solution is to have a data loading thread - the UI says 'get me this data', and does the UI work not contingent on the data being there. The question though is - once the data is returned from the data loader (as each piece comes back), how should it update or notify the UI appropriately? My current thought is:
UI thread:
OnSelectIndians()
{
DataLoadThread.GetIndiansPlayers();
DataLoadThread.GetIndiansNews();
// UI stuff
}
OnPlayersLoaded(Array Players)
{
if (layout == INDIANS_LAYOUT) // Make sure we haven't changed layouts
{
foreach player in Players
tab[PLAYERS].textview.text += player
}
}
But this isn't a problem I've had to deal with before. Is this the right way to go about it? Or is there a better/easier design I can use? I don't particularly like requiring the UI thread to have a 'on data returned' method for every type of data I can request. My other loosely-formed idea is to create a lambda function in the UI code, which is passed to the data loader and executed in the data loading thread, so:
DataLoadThread.Queue(
foreach player in GetIndiansPlayers()
myView.tab[PLAYERS].textview.text += player;
);
But I think this is probably the worse route, as now we have 2 threads interacting with the UI. Any advice?
Edit: Okay I got it working using AsyncTask. Out of the box, it still has the problem listed above that I would have to create a new derived class for every type if data I load (so PlayerLoadTask, NewsLoadTask, StandingsLoadTask, etc etc). I also wanted was to have most of the logic visible during the call, so if I'm looking at the event code I know what its doing. Below is the working implementation - would appreciate any feedback on it, but I'll accept the first answer below just the same.
abstract public class LoadDataHelper {
public LoadDataHelper(DataLoader dl, Object param) {
mDataLoader = dl;
mParam = param;
}
abstract public LinkedList<String> LoadData();
protected DataLoader mDataLoader;
protected Object mParam;
}
abstract public class UpdateUIHelper {
public UpdateUIHelper(MyActivity context) {
mContext = context;
}
abstract public void UpdateUI(LinkedList<String> results);
protected MyActivity mContext;
}
private class LoadDataTask extends AsyncTask<Void, Void, LinkedList<String> > {
private LoadDataHelper mLdh;
private UpdateUIHelper mUih;
LoadDataTask(LoadDataHelper ldh, UpdateUIHelper uih) {
mLdh = ldh;
mUih = uih;
}
#Override
protected LinkedList<String> doInBackground(Void... params) {
return mLdh.LoadData();
}
#Override
protected void onPostExecute(LinkedList<String> results) {
mUih.UpdateUI(results);
}
}
//
// .....
//
LoadDataTask task = new LoadDataTask(new LoadDataHelper(mDataLoader, "football") {
public LinkedList<String> LoadData() {
return mDataLoader.LoadLeaguesFromSport((String)mParam);
}
},
new UpdateUIHelper(this) {
public void UpdateUI(LinkedList<String> results) {
TextView tv = (TextView)findViewById(R.id.tv1);
tv.setText("");
for (String res : results) {
tv.append(res + "\n");
}
}
});
task.execute();
Take a look at:
1) AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
The AsyncTask.onPostExecute will be executed in the UI thread.
I think this is the most common technique to do background processing.
2) runOnUIThread: If you are managing your own worker thread, you can use this in a worker thread to make sure code is run on the UI thread.
Its always better to have UI work in UI thread, and Non-UI work in Non-UI thread, But this became a Law from the arrival of HoneyComb in Android.
2 ways to do it in Android.
1. Use Java thread with Handler..
Create a thread to do the process heavy background task, and then display the data using
Handler...
2. Use AsyncTask<>, which is specially designed for Android, to sync the UI work and Non-UI
work. AsyncTask is also known as painless threading.
This is what AsyncTask was designed to do ,
Here is the tutorial that I learned from.
Here is what you do
Create a class that extends AsyncTask
Implement doInBackground and onPostUpdate methods
In the onPostUpdate method update the ui , you can use runOnUiThread to avoid any issues during ui update
The advantage of this using Async tasks is that you can even update the progress and display a visual indicator to the user , You can as easily cancel the task to stop the loading if required
AsyncTask is essentially a helper that simplifies the use of threads
Your best bet is to use the AsyncTask. I created a similar app that made 25+ calls to a server to download images. Using the AsyncTask will cut that time greatly, and still provide a great user experience. Here is a great tutorial on how to use/setup an AsyncTask:
http://www.peachpit.com/articles/article.aspx?p=1823692&seqNum=3
async task is the solution for you
here is a tutorial

Managing cleanup from views (rather than Activities)... Dangers of singleton pattern?

Coming from a non-Java background, I find myself writing a lot of View classes with extensive functionality (in an effort to be portable), that don't necessarily fit nicely into the Android FW setup as far as maintenance - for example, I might have a widget that does something on a interval that I want to stop and clean up when an Activity is paused/stopped/destroyed. Generally I can manage this by just calling a public method on the widget from the containing Activity, but A) sometimes this gets pretty deep, and having to create a public method to access a child in every parent can get ugly, and B) requires extra (uneeded?) attention.
I'm considering using an approach like a global delegate to manage this kind of thing, but have read a lot of warnings about this sort of approach - would something like the class that follows have any inherent flaws that I might be missing?
import java.util.HashMap;
import java.util.HashSet;
public class ActiveRegistry {
private static final ActiveRegistry instance = new ActiveRegistry();
public static ActiveRegistry getInstance(){
return instance;
}
private HashMap<String, HashSet<Runnable>> registry = new HashMap<String, HashSet<Runnable>>();
private ActiveRegistry(){
}
public void register(String key, Runnable runnable){
if(!registry.containsKey(key)){
HashSet<Runnable> list = new HashSet<Runnable>();
registry.put(key, list);
}
HashSet<Runnable> list = registry.get(key);
list.add(runnable);
}
public void execute(String key){
if(registry.containsKey(key)){
HashSet<Runnable> list = registry.get(key);
for(Runnable runnable : list){
runnable.run();
}
}
}
}
Use might be something like...
A View has something that needs to be cleaned up. On instantiation, register it... ActiveRegistry.getInstance().register("paused", someRunnableThatCleansUpStuff)
Extend Activity so that onPause calls ActiveRegistry.getInstance().execute("paused");
You are doing way more work than you need to. Using Fragments (from the support package, if you want to ensure backwards compatibility with older versions of android), will make your life a whole lot easier. Each fragment is embedded in an activity and has a lifecycle that is directly linked with its host activity's lifecycle. Using them should significantly reduce the complexity of your code, as most of what you are currently worrying about will be managed by the system instead.

How to Stop running singleton class multiple times in play framework

I have a singleton class in my play app. This singleton class is a long process which will generate reports from DB which consumes huge amount of memory. When i run my application in dev mode this singleton functionality is executing several times. I want this functionality to run only once. What should I do for that?
My code is:
public class DataGridManagerImpl extends ComponentContainer implements DataGridManager {
private static DataGridManager instance = null;
private DataGridManagerImpl(){
load();
}}
#Override
public void load() {
//Myreports function
}
public static DataGridManager getInstance(){
if (instance == null){
instance = new DataGridServiceManagerImpl();
}
return instance;
}
}
In my controller file inside a template function
DataGridManager dataGridMgr = DataGridManagerImpl.getInstance();
If i access the page it is executing the load reports function again.
Without code explaining how did you create your class it's hard to answer. From what I understand what you want is to run a process only once.
Problably the best approach is to use a Scheduled Job. This will trigger the process at a certain time, and Play ensures that only 1 instance of this process is running at the same time, even if the schedule would indicate another instance has to run. Let's say you have a process scheduled every hour and the process takes 3 hours. The initial process will be the only one running for 3 hours until it finishes.
Now, I would assume you want your process to be recurring as it generate reports. If not, if you only want to run it once, then you may want to use an asynchronous bootstrap job instead. This would run just once, at the beginning of the application.
EDIT on update: during development the #OnApplicationStart may execute several times, as Play may automatically reload the application when you do certain code changes. This is part of the dev process (the same that an #OnApplicationStart job won't start in Dev until the server gets a request).
As it's a job that you only want to run once, you may try to skip it in dev mode using the check:
if(Play.mode == Play.Mode.DEV)
If you need to run it at least once, add a dev-only url that you can access during dev to start the process.
Now, on your update you also mention that you are calling that code in a controller, and that every time the controller is acessed the method is called. That's expected. Singleton doesn't mean that it will run only once, but that there is only 1 object in the system. If in your controller you launch the calculation, that will happen everytime you access the controller.
SECOND EDIT (on comments): Arasu, the other issue is that you are calling the method load() when you construct the object. A singleton doesn't garantee that the object will only be constructed once. It garantees that, once constructed, only 1 object will exist. But it may happen that the object is removed by GC, in this case as per your code if you construct it again then you'll call load() and redo the processing.
The best solution is to not call "load" on constructor, but to force the user (you) to call it after retrieving the instance. An alternative is to set some flag at the beginning of load that detects if the code has been run. Be aware that Play is stateless, so that flag will need to be stored in the database.
the defition of a singleton is that it can run only once, it's practically the nature of the pattern. If you somehow manage to run it multiple times, you might have implementation errors in your singleton.
Recheck the singleton pattern in Wikipedia.
Edit:
This code makes it impossible to fetch more than one instance. How would you get more than one?
public class Singleton {
private static Singleton _instance;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (null == _instance) {
_instance = new Singleton();
}
return _instance;
}
}
Or do you mean that you instanciate the Singleton class, instead of calling Singleton.getInstance()?
It is possible to have a Singleton doing a time consuming processing and be called the same time by two different threads. I think this is the situation here. The same Singleton object's method is called multiple times from the program.
I have run a little test... two thread calling the same Singleton object and here is the result
Thread[Thread 1,5,main] internal loop number = 0 Object = example.Singeton#164f1d0d
Thread[Thread 2,5,main] internal loop number = 0 Object = example.Singeton#164f1d0d
Thread[Thread 1,5,main] internal loop number = 1 Object = example.Singeton#164f1d0d
and here is the code.
package example;
public class Singeton {
private static final Singeton INSTANCE = new Singeton();
private Singeton() {}
public static Singeton getInstance(){
return INSTANCE;
}
public boolean doTimeConsumingThing(){
for (int i=0; i<10000000;i++){
System.out.println(Thread.currentThread() + " internal loop number = " + i + " Object = " + toString());
}
return true;
}
}
package example;
public class MulThread extends Thread{
public MulThread(String name) {
super(name);
}
#Override
public void run() {
while(true){
Singeton s = Singeton.getInstance();
System.out.println("Thread " + getId());
s.doTimeConsumingThing();
}
}
public static void main(String[] args) {
MulThread m1 = new MulThread("Thread 1");
MulThread m2 = new MulThread("Thread 2");
m1.start();
m2.start();
}
}
Please correct my notion above if i am wrong.
Hence what you need is a variable to keep track of the state of the time consuming procedure (i.e. a boolean isRunning) or the times the procedure has been called.
You can also make the pertinent time consuming method of the Singleton synchronized so only one thread can access the method while it is running (in my example if you make the doTimeConsumingThing() synchronized, the second thread will block until the singleton's method called from the first thread is finished.
Hope it helps
I had the same problem in DEV mode, and what I did is create a module for the tasks I don't want to be run at every #OnApplicationStart.
The trick is to launch those tasks in a overriden "onLoad()" method, in the module:
public void onLoad()
{
// tasks to run one time only
}
The onLoad() method is called one time only, not each time the application is restarted.
I don't know if this will help, but here are some things to check:
The code in your question is not thread-safe. You're missing the synchronized keyword in getInstance. That could cause the constructor to be called more than once by different threads.
Could DataGridManagerImpl be getting loaded by different classloaders? That static instance variable isn't static for the whole JVM, just static for that class' classloader.
load is public. Could some other code being calling that method?

Usage of Static variables in Java Servlets (e.g. in AppEngine)

I have an application where Servlet has a method called Update(ReqIn, ReqOut). I call it from doGet & doPost and pass the Request and Response variables, and it is then up to Update(...) to fill out the following static variables:
...
public class Server extends HttpServlet {
public static HttpServletRequest In = null;
public static HttpServletResponse Out = null;
public static boolean isDebug = true;
public static boolean isPost = false;
public static String URL = "";
public static String IP = "0.0.0.0";
public static Cookie[] Cookies = null;
public static UserClass User = null;
public static boolean isLoggedIn = false;
...
}
Basically Abstracting most used stuff & updating it on every request. This also allows me to access IP address & current user data from anywhere in the website, by writting just Server.User.getUsername(); insead of making a new Class instance everytime a page is loaded and using much longer access code: Server.getUser().getUsername();
Now the question is: When in multi user environment (Jetty on AppEngine), can this introduce any problems? E.g. some threading/racing issues making user see incorrect IP address or in extreme case suddenly being logged in as different user?
Or should I rewrite code and change it to Public UserClass User instead of Public static UserClass User, etc?
Using statics is a hugely bad idea, since if you get two requests come in at the same time then they will write over each other. Take this trivial example to see what can go wrong:
1:public class Server extends HttpServlet {
2: public static int requestNo = 0;
3: public void doGet(HttpServletRequest req, HttpServletResponse resp)
4: {
5: requestNo++;
6: resp.getWriter().println(requestNo);
7: }
8:}
Now imagine the following timeline:
Request 1 comes in, and processes up to, and including, line 5.
Request 2 comes in, and processes completely.
Request 1 continues processing.
Both requests will get the text "2", instead of one getting "1" and one getting "2". This is a simple example of the state being stomped on.
Now, to answer the second part of your question;
Or should I rewrite code and change it to Public UserClass User instead of Public static UserClass User, etc?
No, that is also not good enough, since the J2EE spec allows the servlet container to use one instance of a class to service all of the requests for that servlet mapping, that is, the instance level variables will have exactly the same effect as being statics, they are shared between all requests.
This leaves only three real options:
Shove everything into HTTPSession. The problem here is that this is a map, so you lose type safety, and it is difficult to see where things are being used.
Create a Holder class to hold all of your state and pass that around everywhere. This is a little better, since at least you don't lose the type safety, but you still don't have full visibility either.
Pass the individual required items around.
Yes, this is a hugely bad idea!
What would you expect to happen if you got two requests at the same time? Each static variable can only hold one value, so you're going to lose data.
You could use ThreadLocal so that each thread only had access to the current request/user/etc that it was dealing with - but that's still basically a bad idea. It's brittle, and hides the fact that lower layers need the information. Pass the state down to the code that needs it instead.

Categories

Resources