Save a list of Threads in Android - java

I have a question concerning the thread:
In my activity I get a list of threads(more exactly a list of Runnable). Inside these threads, I check if the time written in the activity is the same as the current time (basically like an alarm).
When I press back on my android, my activity finishes and I go back to the main screen of my phone...however the thread are still there (which makes sense for me as it is initialized in the heap).
However when I return to my app, I have no way to get access back to these threads...
DO you have an idea how to do it?
Here is a part of my code:
public class SmartAlarm extends AppCompatActivity {
private List<Runnable> listThreadAlarms;
#Override
protected void onCreate(Bundle savedInstanceState)
{
listThreadAlarms = new ArrayList<>();
for(Alarm alarm: alarmList) {
Runnable activateAlarm = new ActivateAlarm(this,(int)alarm.getId()-1,"alarm"+(alarm.getSound()+1),alarm.getTitle());
Thread threadAlarm = new Thread(activateAlarm);
listThreadAlarms.add(activateAlarm);
threadAlarm.start();
}
}
}

i think you should rethink your design. more on this to follow...
I Do NOT Recommend This
if you MUST retain references to these objects, one way to do this is to stash them as instances in a static collection in a long-lived singleton. a custom android.app.Application instance would be an option since it lives for as long as your app does and you can reference it from any standard component such as an Activity, ie:
public class MyApplication extends Application {
public static List<Runnable> runnables;
}
add Runnable instances to the collection as they are created...
...however, i have no idea what the criteria would be for removing them. Runnables are meant to run to completion/error, and then be GC'd. since they don't return a result, we'd need some sort of state within the Runnable instance to know if it has completed its work, which means it can then be removed from the collection so as to be GC'd. by keeping them in this collection, they live beyond their scope of viability, and we've created extra housekeeping for ourselves in pruning the collection.
this sort of approach would technically work, but strikes me very odd and untestable.
I DO Recommend This
let the Runnables communicate the state of their tasks independently through another medium, ie:
shared preferences
a database
an in-memory collection stored in the Application
when your SmartAlarm instance starts, interrogate the state of the associated tasks through that medium.

Related

How do I run a thread only once in an android application?

Maybe this is a stupid question, I don't have much experience with android studio. Sorry for that.
In my app I have many activities which represent pages. In MainActivity I create a thread which always listens for something (it stays in loop). But whenever I return to the MainActivity page it creates another thread. If I only want to run it once, what are ways to do it?
I was thinking if maybe using a static variable to count how many times client is running, and stop it from creating another if there already is one.
public class MainActivity extends AppCompatActivity {
private Thread client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
client = new Thread(new CheckForOrders());
client.start();
.
.
}
A thread can only be run once under any circumstances. What's likely happening is that you're creating a new copy of the thread every time your activity is destroyed and recreated on a configuration change (the most common config change being a device rotation.)
If you want to preserve a background thread between activity instances, you have two options:
If you want it to survive between different activities or when no activity is running, put it in a Service.
If you only need it to survive configuration changes, put it in a retained Fragment.
Since you only want one instance of the Thread you can declare it as static something like this:
private static Thread client = new Thread(new checkForOrders());

Memory Leak in practical example

I am constantly struggling with identifying memory leaks. I guess I have several memory leaks in my project circular progress view.
One of my guesses is I have a memory leak in the internal class FadeRunnable.
But to be honest I don't know exactly how to find out if this is exactly the source of the problem. Well, when I do the usual scenario and switch the orientation I see an increase of the memory usage as shown below. And if I comment out the usage of the FadeRunnable class the steps are smaller (but still there, so I guess that's not the only leak)
Once I analyze the heap dump, I see something. But actually I don't know what the values mean. The things I do is
Change orientation many times
Open heap dump and sort by 'Retained Size'
Now when I click on "CircularProgressView' I see 8 rows in the right area. I guess this means there are 8 instances of the 'CircularProgressView' leaked and living somewhere as orphan in the memory.
Is this correct? If so, how can I find out in the dump information (I guess somewhere in the lower pane) where this object is saved/held.
I would love to have a step-by-step explanation how to find out if and which object is leaking some memory.
All of the code of the suspected view can be found in this class.
https://github.com/momentummodules/CircularProgressView/blob/master/circularprogressview/src/main/java/momentum/circularprogressview/CircularProgressView.java
But also feel free to check out the full project for deeper insight and if you want to play around with it.
Thanks in advance!
UPDATE
The code link from above shows the fixed code of the mem-leaking inner class. The following snippet shows the original mem-leaking code that should never be used like that
/**
* Mem-leaking code, for fixed code see repository link
* https://github.com/momentummodules/CircularProgressView/blob/master/circularprogressview/src/main/java/momentum/circularprogressview/CircularProgressView.java
*/
public class CircularProgressView extends View
{
...
private Thread fadeThread = null;
...
...
class FadeRunnable implements Runnable
{
#Override
public void run()
{
...
}
}
...
...
private void startFade(boolean fadeIn)
{
// check existing
if(this.fadeThread != null)
{
// check if fade is already running
switch(this.fadeThread.getState())
{
case TERMINATED:
case NEW:
this.fadeThread = null;
break;
case RUNNABLE:
case BLOCKED:
case TIMED_WAITING:
case WAITING:
return;
}
}
// create new
this.fadeThread = new Thread(new FadeRunnable(fadeIn, this.fadeTime));
this.fadeThread.start();
}
}
Yes, you do have a memory leak in FadeRunnable class.
Every instance of inner class contains implicit reference to its outer class, accessible through OuterClass.this operator. In your project, when you execute the FadeRunnable and then trigger reconfiguration by orientation change, the whole activity and your CircularProgressView contained within get recreated, but the FadeRunnable from previous is still alive (allocated) and, because of it holding implicit reference to its outer CircularProgressView class, the view continues to live also, that's why after several reconfigurations you have 8 instances of CircularProgressView allocated in memory, and that gets worse - every View keeps a reference to it's context, and this cannot be freed also, resulting in bad memory leaks.
Runnables, Handlers and similar objects that can out-live their enclosing activities, fragments, views etc. should be declared as standard classes or STATIC inner classes (a static inner class doesn't hold implicit reference to its outer class), and shouldn't keep references such as Context, View etc., instead you can keep a WeakReference<> so when your Activity is recreated through config change, the View can be destroyed and freed by garbage collector.
This is a very informative article on the subject, I strongly suggest reading it.
I guess you have the correct direction there. This FadeRunnable is certainly not cool. Even if you have other memory leaks, you defo should check this out.
In general what you should really be doing in a view is quite different, specially that views already have facilities to deal with timing and animation without the need for threads.
I'll suggest you what I believe is a simpler and cleaner approach to animate stuff on views.
Start by removing your runnable and thread completely.
then to start an animation you do:
ValueAnimator animation = ValueAnimator.ofFloat(0, 1);
animation.setDuration(500);
animation.addUpdateListener(animationUpdate);
animation.addListener(animationUpdate);
animation.start();
and then you need those listeners
// this gets called for every animation update,
// inside this call you update `CircularProgressView.this.fadeAlpha`
private final ValueAnimator.AnimatorUpdateListener animationUpdate = new ValueAnimator.AnimatorUpdateListener() {
#Override public void onAnimationUpdate(ValueAnimator animation) {
// this fraction varies between 0f and 1f
float fraction = animation.getAnimatedFraction();
// ... do your calculation
ViewCompat.postInvalidateOnAnimation(CircularProgressView.this);
}
};
// this is an optional one only if you really need
// in that you get notified when the animation starts and ends
private final Animator.AnimatorListener animationListener = new AnimatorListenerAdapter() {
#Override public void onAnimationStart(Animator animation) {
// anything u need goes here
ViewCompat.postInvalidateOnAnimation(CircularProgressView.this);
}
#Override public void onAnimationEnd(Animator animation) {
// anything u need goes here
ViewCompat.postInvalidateOnAnimation(CircularProgressView.this);
}
};
and that's about it.
On the topic of actual memory leak analysis I'll suggest you to from now on and forever use the leak canary library: https://github.com/square/leakcanary it's a great tool to help us (developers) track memory leaks.
edit:
Why are you having a memory leak on this animation?
It's quite simple:
on startFade(boolean); you create a new thread and a new runnable
the runnable have a reference to the view (because it's an non-static inner class)
the thread have a reference to the Runnable, so can run it.
the framework destroy the view, because it's not part of the UI anymore (rotation, back button)
the thread is still running, with the runnable still looping, with the View object still not destroyed because the Runnable references it.
the view Object have an instance of Context, and this context is the Activity.
So at the end of this sequence your activity will not be garbage collected by the GC, AKA: Memory Leak !

Handling common code between different activities, fragments, tasks, etc

I have quite some (not too much, but quite some) experience with Java and object-oriented programming in other languages, but am fairly new to Android and my understanding of all its different classes is at best described as limited (more realistic would be confused).
I'm creating an application that for now consists of one activity and a widget. One of its functionality will be fetching some data from the internet. This data will only change every day on some arbitrary moment, so there's no need to fetch this data every time you start the app or look at the widget.
My problem is that I'd like to have one method to fetch the data and store it in shared preferences, together with the update time (so that it's only updated once a day). This method has to be accessible from the widget and the activity.
Normally I would simply create some class with a static method to do this. However, to access the shared preferences you need a Context. I can come up with two ways:
Option 1: static method, Context as parameter
public class MyClass {
public static String fetchData(Context context) {
return // ...
}
}
Option 2: singleton
public class MyClass {
private static MyClass instance = null;
private Context context;
public MyClass(Context context) {
this.context = context;
}
public String fetchData() {
return ...;
}
public static MyClass getInstance(Context context) {
if (instance == null)
instance = new MyClass(context);
return instance;
}
public static MyClass getInstance() {
return instance;
}
}
Now I would call it with MyClass.getInstance(getActivity()).fetchData() the first time, and after that MyClass.getInstance().fetchData().
My question
Is either of these preferred over the other, and if so, why? Or is there another, better, way to do this kind of thing? Or does it depend on the situation (and in that case, on what precisely?)?
Later, I may have more of these methods. Since the Context is something that normally doesn't change, I thought a singleton may be useful here because after the first instantiation you don't need to give a context anymore.
Option 1 is ok to use almost all the time. Option 2 is dangerous because you are keeping a reference to a Context. if the Context is of type Activity you can have memory leaks - your Referenced Activity will not be GC
If you are using option 2 make sure you are using Application Context.
To init the singleton do something like:
getInstance(myActivity.getApplicationContext())
option 1 is much better if the method is a utility method - does something and does not need to change it's state after the method has returned.
first of all you are not keeping a reference to Context. also you don't need to hold a singleton in the memory. Last Static methods are efficient.
Use option 2 if you are using the Singleton all the time and recreating objects during the process (Picasso, RetroFit are good examples for the need of Singleton)
A good example of when to use a Singleton is Android Volley library. It's also relevant to fetching data from remote so have a look
In essence, neither of your approaches are required for what you initially describe...
I'm creating an application that for now consists of one activity and a widget. One of its functionality will be fetching some data from the internet. This data will only change every midnight, so there's no need to fetch this data every time you start the app or look at the widget.
So what exactly is going to be responsible for the daily download and how is it going to be triggered? Neither an Activity nor an App Widget is suitable.
Add a few bits and pieces - use AlarmManager to create a repeating alarm set for around midnight (it won't be exact but normally within a few seconds). Have the alarm trigger a broadcast which is received by a BroadcastReceiver and then have the receiver start an IntentService to download and save what's needed.
It's a win-win scenario. The alarm will be fired regardless of whether your app is 'running' or not (or whether the phone is asleep or not). The receiver will be triggered and the IntentService uses its own worker thread so no need to worry about any problems with running network code on the main/UI thread. Also, an IntentService has a Context which can be used to access SharedPreferences and will shut itself down after it has done its work.

Combining Handler and AsyncTask in Android - Obvious Flaws?

I have a simple Android app which uses AsyncTasks for I/O. A frequent pattern:
User clicks a button
In response, an onClick handler instantiates and .execute()s an AsyncTask
Once the AsyncTask completes, the UI should be updated in some way
According to the documentation for AsyncTask, the correct way to accomplish the UI updates is to override onPostExecute in the AsyncTask class - this will be invoked back on the UI thread after execution and thus can touch the widgets, etc.
However, it seems wrong to me that onPostExecute should have any sort of hard reference to a UI element. I would prefer to keep my I/O tasks and UI code separate. Instead, this seems the obvious situation where I should pass an opaque callback to the AsyncTask - the callback retains a reference to the UI elements and thus we maintain isolation and reusability in the code. A classic delegate pattern (or perhaps listener, event, etc, many options here).
As an example, the code below seems wrong to me:
class QueryJobsDBTask extends AsyncTask<Void, Void, ArrayList<ContentValues>> {
#Override
protected void onPostExecute(ArrayList<ContentValues> freshJobsData) {
someList.clear();
someList.addAll(freshJobsData);
// BUG why does my DB query class hold UI references?
someAdapter.notifyDataSetChanged();
}
After some research, it looks like the Handler class is the most straightforward and lightweight way to accomplish a delegate pattern here. I can write reusable AsyncTasks for I/O and specify contextual UI update callbacks on a per-instance basis via Handler instances. So I have implemented this new Handler-enabled base class
public abstract class HandlerAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
private Handler preExecuteHandler, postExecuteHandler;
public void setPreExecuteHandler(Handler preExecuteHandler) {
this.preExecuteHandler = preExecuteHandler;
}
public void setPostExecuteHandler(Handler postExecuteHandler) {
this.postExecuteHandler = postExecuteHandler;
}
#Override
protected void onPreExecute() {
if (preExecuteHandler != null) {
preExecuteHandler.sendMessage(Message.obtain());
}
}
#Override
protected void onPostExecute(Result result) {
if (postExecuteHandler != null) {
Message msg = Message.obtain();
msg.obj = result;
postExecuteHandler.sendMessage(msg);
}
}
}
And voila, all of my I/O tasks are now properly partitioned from the UI - and I can still specify simple UI update callbacks when needed via Handler instances. This seems straightforward, flexible, and superior to me ... so of course I wonder what I'm missing.
How is the current framework solution superior? Is there some major pitfall to this approach? To my knowledge the topology of code execution and threads is the exact same at runtime, just code coupling is looser (and a few extra frames on the stack).
This is an elegant solution for segregating UI/Background tasks in small projects, although passing Runnables is even more elegant. Keep in mind that the AsyncTask is a wrapper around Thread/Handler, so you're doubling up on the thread-messaging that's already going on behind the scenes. The flaw here is that if you design the AsyncTasks to be reusable, you'll need to make sure that the IO you're running are all thread-safe, as there's no communication between the various AsyncTasks as to who is active or accessing which resources. An IntentService might be more appropriate if you need to queue background tasks rather than just fire them.
It's not so much a matter of superiority as purpose & use-case. AsyncTasks are usually written as private classes (or declared anonymously inline) within Activities, and as such inherit the Activity's references to various UI elements that need updating anyway.
If an AsyncTask is of sufficient size and/or complexity that it should be pulled out into its own class, and can be re-used by other classes, than using Handlers for better decoupling is a great idea. It's just that it's often not necessary, as the AsyncTask is accomplishing something specific to the Activity in which it was defined, and for simple ones, the corresponding handler code could even be larger than the entire AsyncTask itself.

Static references are cleared--does Android unload classes at runtime if unused?

I have a question specific to how the classloading / garbage collection works in Android. We have stumbled upon this issue a few times now, and as far as I can tell, Android behaves different here from an ordinary JVM.
The problem is this: We're currently trying to cut down on singleton classes in the app in favor of a single root factory singleton which sole purpose is to manage other manager classes. A top level manager if you will. This makes it easy for us to replace implementations in tests without opting for a full DI solution, since all Activities and Services share the same reference to that root factory.
Here's how it looks like:
public class RootFactory {
private static volatile RootFactory instance;
#SuppressWarnings("unused")
private Context context; // I'd like to keep this for now
private volatile LanguageSupport languageSupport;
private volatile Preferences preferences;
private volatile LoginManager loginManager;
private volatile TaskManager taskManager;
private volatile PositionProvider positionManager;
private volatile SimpleDataStorage simpleDataStorage;
public static RootFactory initialize(Context context) {
instance = new RootFactory(context);
return instance;
}
private RootFactory(Context context) {
this.context = context;
}
public static RootFactory getInstance() {
return instance;
}
public LanguageSupport getLanguageSupport() {
return languageSupport;
}
public void setLanguageSupport(LanguageSupport languageSupport) {
this.languageSupport = languageSupport;
}
// ...
}
initialize is called once, in Application.onCreate, i.e. before any Activity or Service is started. Now, here is the problem: the getInstance method sometimes comes back as null -- even when invoked on the same thread! That sounds like it isn't a visibility problem; instead, the static singleton reference hold on class level seems to actually have been cleared by the garbage collector. Maybe I'm jumping to conclusions here, but could this be because the Android garbage collector or class loading mechanism can actually unload classes when memory gets scarce, in which case the only reference to the singleton instance will go away? I'm not really deep into Java's memory model, but I suppose that shouldn't happen, otherwise this common way of implementing singletons wouldn't work on any JVM right?
Any idea why this is happening exactly?
PS: one can work around this by keeping "global" references on the single application instance instead. That has proven to be reliable when one must keep on object around across the entire life-time of an app.
UPDATE
Apparently my use of volatile here caused some confusion. My intention was to ensure that the static reference's current state is always visible to all threads accessing it. I must do that because I am both writing and reading that reference from more than one thread: In an ordinary app run just in the main application thread, but in an instrumentation test run, where objects get replaced with mocks, I write it from the instrumentation thread and read it on the UI thread. I could have as well synchronized the call to getInstance, but that's more expensive since it requires claiming an object lock. See What is an efficient way to implement a singleton pattern in Java? for a more detailed discussion around this.
Both you (#Matthias) and Mark Murphy (#CommonsWare) are correct in what you say, but the gist seems lost. (The use of volatile is correct and classes are not unloaded.)
The crux of the question is where initialize is called from.
Here is what I think is happening:
You are calling initialize from an Activity *
Android needs more memory, kills the whole Process
Android restarts the Application and the top Activity
You call getInstance which will return null, as initialize was not called
Correct me if I'm wrong.
Update:
My assumption – that initialize is called from an Activity * – seems to have been wrong in this case. However, I'll leave this answer up because that scenario is a common source of bugs.
I have never in my life seen a static data member declared volatile. I'm not even sure what that means.
Static data members will exist until the process is terminated or until you get rid of them (e.g., null out the static reference). The process may be terminated once all activities and services are proactively closed by the user (e.g., BACK button) and your code (e.g., stopService()). The process may be terminated even with live components if Android is desperately short on RAM, but this is rather unusual. The process may be terminated with a live service if Android thinks that your service has been in the background too long, though it may restart that service depending on your return value from onStartCommand().
Classes are not unloaded, period, short of the process being terminated.
To address the other of #sergui's points, activities may be destroyed, with instance state stored (albeit in RAM, not "fixed storage"), to free up RAM. Android will tend to do this before terminating active processes, though if it destroys the last activity for a process and there are no running services, that process will be a prime candidate for termination.
The only thing significantly strange about your implementation is your use of volatile.
Static references are cleared whenever the system feels like it and your application is not top-level (the user is not running it explicitly). Whenever your app is minimized and the OS wants some more memory it will either kill your app or serialize it on fixed storage for later use, but in both cases static variables are erased.
Also, whenever your app gets a Force Close error, all statics are erased as well. In my experience I saw that it's always better to use variables in the Application object than static variables.
I've seen similar strange behaviour with my own code involving disappearing static variables (I don't think this problem has anything to do with the volatile keyword). In particular this has come up when I've initialized a logging framework (ex. Crashlytics, log4j), and then after some period of activity it appears to be uninitialized. Investigation has shown this happens after the OS calls onSaveInstanceState(Bundle b).
Your static variables are held by the Classloader which is contained within your app's process. According to google:
An unusual and fundamental feature of Android is that an application
process's lifetime is not directly controlled by the application
itself. Instead, it is determined by the system through a combination
of the parts of the application that the system knows are running, how
important these things are to the user, and how much overall memory is
available in the system.
http://developer.android.com/guide/topics/processes/process-lifecycle.html
What that means for a developer is that you cannot expect static variables to remain initialized indefinitely. You need to rely on a different mechanism for persistence.
One workaround I've used to keep my logging framework initialized is for all my Activities to extend a base class where I override onCreate and check for initialization and re-initialize if necessary.
I think the official solution is to use the onSaveInstanceState(Bundle b) callback to persist anything that your Activity needs later, and then re-initialize in onCreate(Bundle b) when b != null.
Google explains it best:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html

Categories

Resources