I am writing an application and using some temporary files in internal storage e.g. (/myapp/files/tmp/*)
The files are temporary and are considered expired when the application exits.
What are some good practices for cleaning up such files?
There is no onDestroy() in Application class. Interchanging between activies means it's not trivial to know when an activity's onDestroy is exiting the activity, or application. Furthermore, none of these will get called when the application crashes, for instance. They are not guaranteed to be called.
So I am cleaning those files in onCreate in my instance of the Application class (in an AsyncTask launched at onCreate).
But it seems a little quirky to me. Launching the application will launch a thread to delete unnecessary files from previous usage. Is there a better way to do this?
file.deleteOnExit() is also discouraged on Android
You can achieve this by using activity's life cycle.
Follow the steps.
1) Create BaseActivity.java which extends Activity or FragmentActivity.
2) All other activity will extends BaseActivity.
3) Now you need to override two methods say
onResume();
onPause();
4) How your base activity looks like.
public abstract class BaseActivity extends Activity {
public static int actictyCounter=0;
#Override
protected void onResume() {
super.onResume();
actictyCounter++;
}
#Override
protected void onPause() {
super.onPause();
actictyCounter--;
// This was the last activity
if(actictyCounter==0){
//code to remove your temp files
}
}
}
Related
As i already know, activities in android can go through recreation phase, e.g. be destroyed and than created again, as mentioned here https://developer.android.com/reference/android/app/Activity#activity-lifecycle
To preserve state of my app during lifecycle changes, I use onSaveInstanceState() and onRestoreInstanceState() in my activity, and everything goes fine.
But, when Application is recreated, I cannot correctly save/restore state, cause there are already a lot of another activities in my app, that doesn't support saving/restoring state.
What I what to achieve, is simply drop stack of all activities, that was previously opened, and launch app from the scratch.
Can anybody help my, how can I detect application recreation event, so I can told my app, that it should not restore any previously saved state?
Update:
Same problem described in this article, but It doesn't provide solution to my problem
https://medium.com/#elye.project/dont-keep-activities-alone-is-not-enough-for-testing-407b7c01bd60
The only way to do that is the following:
public class BaseActivity extends AppCompatActivity {
private static boolean isFirstInit = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(isFirstInit) {
isFirstInit = false;
if(savedInstanceState != null) {
// is after process restart
}
}
}
}
But I think you're just supposed to properly implement state persistence in the first place.
I know, as a user, that an app that restarts from scratch just because I opened the camera and uploaded an image to Google Photos and then came back to it, is very annoying.
You can use a flag under your Application class. Though below example is just one way to maintain the state. There are multiple ways like storing in BaseActivity or Listening the activity state changes and saving the state.
Base class for maintaining global application state. You can provide your own implementation by creating a subclass and specifying the fully-qualified name of this subclass as the "android:name" attribute in your AndroidManifest.xml's tag. The Application class, or your subclass of the Application class, is instantiated before any other class when the process for your application/package is created.
You can try with below example and maintaining flag. So whenever application is launched BaseAppwill be the first one to exectue.
public class BaseApp extends Application{
private boolean isAppRestarted;
#Override public void onCreate() {
super.onCreate();
isAppRestarted = true;
}
public static boolean isAppRestarted() {
return isAppRestarted;
}
}
One can access the isAppRestarted state and know whether it has restarted or not. I mean fresh start. After couple of seconds you can change the state using some timer or based on user activity(making isAppRestarted to false).
I am having trouble applying the concept of inheritance to Android Activities - eg.
ActivityA extends Activity and
ActivityB extends ActivityA , then if I launch with ActivityB then onCreate() method for both Activities (A then B) is called .
My question is, in typical Java , onCreate from ActvityA should be over-ridden - but onCreate is rather behaving as a constructor even though its a function. How does inheritance work in Android, esp. wrt other functions like onPause(),onResume etc. ?
EDIT: I also noticed that ActivityA may have many abstract methods called in its onCreate() whose definitions are provided in ActivityB. How does this work ?
If you have your base Activity and then extend it like so Activity -> Activity A it means that when your onCreate of Activity A is called and you call super.onCreate(); then the onCreate() method of the original Activity is also called.
If you then extend Activity A into Activity B the calls work like so...
Activity B.onCreate() - super.onCreate();-->Activity A.onCreate() - super.onCreate()-->Activity.onCreate().
Its not a constructor, its a method thats called to create the Activities. If you then extend them from other Activities its superclass is going to be called via its super method. It doesn't mean that the Activities you have inherited from are going to be created too. Activity B will be your created Activity.
EDIT: This page on the Android Developer website is very useful as it visually explains the Android Activity lifecycle.
Yes as a typical java function onCreate should have been inherited but it doens't get : why? - because it's not just a method, it's a life cycle stage.
AFAIK, Activity is not just a java class but it's a special type of a JAVA Class which has it's own life cycle and Life Cycle stages are meant to be called each and every time you use that class/activity even if you have declared or not those methods onCreate(), onPause() etc gets called for sure.
So every time the base activity will get created and destroyed. That's it's nature.
If you have problem with that you can try using Abstract classes, Interfaces and any other public class to have common code inherited in your all activities.
How does Inheritance work in Android?
There nothing special about Android. It works exactly as it should.
Example?
Lets create a BaseActivity which listens to a BroadcastReceiver (SCAN_RESULTS_AVAILABLE).
So common functions are,
Register a BroadcastReceiver in onCreate()
Unregister a BroadcastReceiver in onDestroy()
BaseClass:
public class BaseActivity extends AppCompatActivity{
private WifiScanReceiver wifiScanReceiver;
#Override
public void onCreate(Bundle sis)
{
super.onCreate(sis);
// Don't call setContentView() because no layout is needed
}
#Override
public void onDestroy(){
super.onDestroy();
unregisterReceiver(wifiScanReceiver);
}
private void registerMyReceiver(){
wifiScanReceiver = new WifiScanReceiver();
registerReceiver(wifiScanReceiver, new
IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
manager.startScan();
}
}
Child class:
public class BlahBlahActivity extends BaseActivity{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); // this will call BaseActvity method which will call AppcompatActivty method
setContentView(R.layout.yourlayout);
}
}
I have a set of commands that I want my app to run when it's restarted, regardless of what activity it's on. I know I need to put an onRestart() into every one.
Since it's the same set of commands regardless of what activity it's on, is there a way I could have them all refer to a single function for that? It seems like that would be better then having to copy paste the commands into each onRestart() handler. It will be a lot less work if I need to change the set of commands too.
You have a couple of options, depending on the code.
You can put it in a helper class as a static function: public static void doWork() { .. } This should work, unless whatever you are doing depends on being in the activity. You can generally just pass it what it needs though, like the Context.
Or, you could extend Activity with your own class, MyActivity and place the work in that onResume. Then extend MyActivity for each of your real activities. They will now automatically do that work when you call super.onResume(). This works well as long as you really want to do the same thing in every activity, and don't use a lot of specialized activities like ListActivity.
Edit:
public class MyHelper {
public static void doWork() {
// do your work here
}
}
public class MyActivity extends Activity {
public void onResume() {
super.onResume();
MyHelper.doWork();
}
}
A search for "static method" will provide more details.
Derive all your activities from a single class (something like ActivityBase) that, in turn derives from system-provided Activity. Then implement onRestart() in ActivityBase.
Is it your application that is restarting from scratch? Or just your activities that are restarting/resuming?
The Application class has an onCreate() method, and you can extend Application in your app to override its behavior. Just remember to change the name of the application in AndroidManifest.xml so it picks up your custom Application class when starting. This code would run before any activities start up. But it won't run every time an activity is stopped and restarted. If that's what you need, this won't do it.
You could also implement a singleton class that contains an initialize() method, or restart() method. You simply call it from onRestart() in each activity you want it in. It sounds like this special code ought to be localized away from your activities so I don't think I'd recommend extending Activity to put the code there.
Is there a way to intercept whenever the Application creates a new Activity instance? I'm only interested in Activities belonging to the Application process not all Activities on the phone. Is there some way to do this? Is the Application class involved in doing this in some way? What methods can I override to get at the Activity instance after it's been created?
Ok, just an idea - in your app you can create a base activity class so all the rest of activities are subclassed from that base activity. Then in the onCreate() callback you may notify some listener instance about the fact of a new app activity instance creation:
public class BaseActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// put the code to notify a listener here
}
}
public class YourWorkingActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
}
If you use a ListActivity (that is common for an average Android app), then you should also create a similar BaseListActivity for it.
Most likely the best candidate for a listener would be an Application subclass since it is guaranteed by the OS that is will be created before any Activity will be instantiated.
Warning: you should avoid keeping a strong reference to an Activity in the listener since it will create a memory leak when the OS will try to kill that Activity (as a part of the Activity or Process life-cycle). Probably use WeakReference for this.
I would like to run a piece of code every time any activity or service is started. In this piece of code, I might do things such as set the default uncaught exception handler and manage log levels.
The problem is that I have an activity which starts with the user clicking the application icon. I have another which starts if a certain intent is broadcasted, possibly from another app and possibly called before the user click the launch icon. Same goes for services.
I need to guarantee that a certain piece of code will be run while keeping the code clean; that is to say, without having to manually add that snippet of code to every activity and service class that I have.
Could you not extend the basic Activity class for Android like this:
public class MyClass extends Activity {
public void onCreate(Bundle bundle) {
//Add custom code here
}
}
Then have all of your actual "Activity"'s in your application extend the custom class?
public class MyInterfaceClass extends MyClass {
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
//Other code here
}
}
That way all your custom code will be called when the Activity starts up.
For an application called Wibble...
public class Wibble extends Application {
protected static void DoSomething()
{
// Do your common code here
}
}
Then extend Activity...
public class WibbleActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Wibble.DoSomething();
}
}
Then derive all activity classes from WibbleActivity...
public class Whatever extends WibbleActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// WibbleActivity calls Wibble.DoSomething()
// so the 'Whatever' class doesn't have to.
}
}
Any Activity derived from WibbleActivity will run Wibble.DoSomething() implicitly.
If you want Services in the mix I can't help - I'm an Android 'rookie' and haven't got on to Services yet but I suspect extending your own app-level Service class might work in the same way.
You could extend Application and do it in its onCreate() method.
You have two choices
A) You can manually add the code - it might be only two lines importing and instantiating something from a source file you copy in unmodified - to every separate component that you write. It will only be in your projects, not in other people's unless they do it too.
B) You can, after no small difficulty, learn to make your own custom version of android that automatically does this each time it starts up a suitable component, and install this customized version on developer phones or hacked consumer phones.
"started" is ambiguous - what are you referring to? onCreate? onResume?
In any case, your best bet is to have a separate class with a static method that does the code you are talking about, and you call that in every single onCreate (or onResume, whichever you need) of each one of your activities.
That, or you create your own Activity subclass and derive all your activites from it, and override onCreate (or onResume). All your onCreate/onResume implementations are required to call the superclass' implementation, so you're guaranteed to have your code caled.