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.
Related
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
}
}
}
I have a base activity from which I subclass several other activities.
Those other activities I do register in the manifest so I can use them from within my application.
However, Android inspection says, for my base activity, "Activity not registered in the manifest".
I see no reason to register the base activity as I never use it directly. However, maybe, I am missing something and the warning should not be ignored?
Why this warning anyway?
You'll only need to list activities that are entry points to your app in the manifest. That is, activities that are invoked with an Intent.
You should not have activities that are in fact not instantiable entry points. Make such activity classes abstract. This will also get rid of the lint warning.
You should make your BaseActivity as an Abstract class. No need to register such Activities in manifest, they are just simple java classes extending Activity class not an Activity of your application.
public abstract class BaseActivity extends Activity {
#Override
public void onCreate(bundle) {
super.onCreate(bundle);
setContentView(getLayoutResourceId());
}
protected abstract int yourmethods();
}
public class Activity1 extends BaseActivity {
#Override
public void onCreate(bundle) {
super.onCreate(bundle);
// do extra stuff on your resources, using findViewById on your layout_for_activity1
}
#Override
protected int yourmethod() {
//implemetation
}
}
Declare in the manifest only the activities that user can see during its experience. Usually these are called by intents. The others you should declare abstract.
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 an activity non visible, with some variables that must be accesed by static way. This activity can't be a service, because it is a MapView activity.
I need to access some static varibales of the activity anytime. I know that Android can close suspended activities (non visible activities) so.... how can i avoid it? i need that my suspended non visible activitity never get's deleted by Android.
The variable that i need to access staticly is a the own MapActivity instance variable because i need to pass it to another mapView objects from other activities
public class OsmMapActivity extends MapActivity {
public static OsmMapActivity instance;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View v = new View(this);
setContentView(v);
instance=this;
How many variables do you have? I would create a singleton and manage those with maybe SharedSettings. You can create a POJO and save it.
Also, you could make an object, implement Parcelable interface and pass it to the Activity where you need the information.
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.