I am writing a simple Android library. I have a couple of methods that I would like executed when certain activity events happen - like after activity got loaded or when the activity gets paused.
One way I could think of was to create a class that extends activity, and write my methods there, and then have "target" activities extend that class. This was all methods get called
But if the end user is extending some other activity already, this method won't work. Is there a better alternative?
If you need only provide support back to API 14 or higher, you might be able to make use of the application level activity lifecycle callbacks - see the Application.ActivityLifecycleCallbacks interface for details.
To make use of this you need to register an instance of this interface with an Application instance, using the registerActivityLifecycleCallbacks method. One way to get that would be to have the developer using your library initialise your library by passing their Application instance to it. This is what I do in an SDK that I maintain, and it seems to work nicely.
First of all: I am rather new to Android App programming and I have a rather basic question:
Already with the sandbox app I am currently working on, the code in the Activity class get quite huge because all the callback methods / listeners (click listener, callbacks from GoogleApiClient) are in there (either by implementing the respective interface or by creating a private class). But I would rather put those into separate classes.
But the question that I ask myself is this: how would I then be able to access the class attributes of the activity class? Sure, I would then probably create setter/getter, but still I first need a reference to the Activity object. How would I get this?
Thanks and regards!
It's a really wide question, since the answer depends by your project and by your programming style. The first suggestion is: move what you can move in one or more fragment. All stuffs related to google play services can be nicely handled in a fragment for example. Listener and callback are UI related components, so they need a Context of an Activity to work, but you can split your UI (again) with Fragment and keep a piece of logic in a Fragment and another piece somewhere else. If you have some logic that runs in background, then you should consider using Service. I tend to have empty Activities, but this is not a rule.
I am working on a solution or code that can be embedded inside of an Android APK to track how many times the app has been launched and how long the app has ran for. I know one way to do this is using the ActivityLifecycleMethods in API 14 and in lower versions of Android having code placed in all Activity Lifecycle events or by providing a base Activity class.
1) Is there a way to hook the ActivityLifecycleMethods without the developer having to make any changes to their code outside of dropping additional code into their App?
I believe this answer is no because even with an Enum Singleton it is not loaded until it is referenced. Also the Enum Singleton will go away once the activity is changed since a different class loader is used when activities change.
If I wanted to keep the Enum Singleton around would it be possible to store a reference to the applicationContext and thus it wouldn't be removed when the Activity changes? Is that what google means by
"There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton." on http://developer.android.com/reference/android/app/Application.html
2) I am not a fan of this solution for older API versions. It seems very likely developers could forget to modify their Activity Lifecycle methods or forget to inherit from the created BaseActivity. Are there any other unique solutions for these older platforms? Is there any other approaches that can be done to determine when an activity isn't running? Could any of the following work:
a) User a class loader to ensure the base activity with the proper metrics are always used
b) Implement some type of heart beat. Will a timer stop working if the app is paused or killed? Is there some other way? Could the ActivityManager be used?
You have many Analytic Agents like Flurry to do that.
When ever you want to track an event, you will add it to flurry and inturn it syncs with server after specific time.
You may use the same logic.
Better create a library file with following features:
Start Application
End Application and report time to db.
Track a specific event count and update to db.
Sync the data to server you like to.
Call appropriate events from your app.
When writing an android test case how can I call some methods on my application object before the activity is created? My test class extends ActivityInstrumentationTestCase2.
Some of the things I've tried are
Looking for a method my test case can override. I don't see one.
Creating a test activity that extends the app's activity. I dont think I can do this without adding the test activity to the real application's manifest.
Getting the application inside of my test's setUp() method. I can't find any way to access the application without first creating the activity
You can't do what you're trying to do. ActivityInstrumentationTestCase2 is not designed to do it. You need something like Robotium that can invoke your Application object first, before your Activity object is created.
ActivityInstrumentationTestCase2, except in a few cases, is designed to test things within the Activity, and not its interaction with things outside the Activity. Unit testing in Android isn't perfect.
I also question why you need something from Application. Whenever someone mentions Application, a warning light goes off in my head. I rarely see code that uses Application, and 90% of the time the developer should have used something else.
I've seen this in a few tutorials now... but how in the world can Android source code not have a main method and still run.
For example (from http://developer.android.com/guide/tutorials/hello-world.html):
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
That runs but there is no main!!!
I've also thought that using things like onCreate (or formLoad, etc.) was bad becuase a constructor should do that work and such built-in methods can be smelly sometimes. But onCreate is an entry point? Even without a main?
What if there is more than one activity... is there a hierarchy to these built in event handlers? OnCreate trumps everything else? Otherwise, how would the app know what to run or where to enter the program?
Thanks!
Each application will be having it's own Virtual Machine. To run an app, within it's space (VM), must have a main method.
Activities are not the actual classes to be invoked for start of application. There is a class called Application, which will be the root class for an application to be launched.
If there is no main method, how can a VM recognize how to start an app?
Framework has classes called Process, VMRuntime which are responsible for starting an application. Which indeed deal with main method.
For better understanding, study the Zygote service of Android. deals with Applicationmanager Service, ActivityStack Activity Threadds etc.
That runs but there is no main!!!
Of course. Many things that you might think of as a Java "application" do not have their own main() method. For example, IIRC, servlets, WARs, and the like do not have main() methods -- the main() method, if there is one, is in the container.
But onCreate is an entry point?
onCreate() is a method.
What if there is more than one activity... is there a hierarchy to these built in event handlers?
Not really.
OnCreate trumps everything else?
Not really.
Otherwise, how would the app know what to run or where to enter the program?
An app does not "know what to run or where to enter the program".
An Android application is a basket of components. Some components may be tied to icons in a home screen launcher. Some components may be tied to scheduled timers, like cron jobs or Windows scheduled tasks. Some components may be tied to system events, such as when the device is placed into or removed from a car dock. Those components will be automatically created and used when appropriate (e.g., when a user taps the icon in the home screen launcher). Yet other components are only created and used when your code specifically asks for them.
Thinking of an Android application as if it were a monolithic console-mode Java program will cause you no end of trouble.
You tell it which one to run on startup in the manifest file. There isn't a main() because there doesn't have to be, main may be a convention used for "regular" java apps, but it isn't for things like browser applets. The system creates the activity object and calls methods within it, which may or may not be called main. In this case, it's not.
onCreate is different from a main, and from a constructor, in that it can be called twice on a single activity, such as if the process is killed and the user navigates back to the activity. See http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Actually, this type of pattern is not peculiar of Android, but happens whenever you have some framework in the middle. Some basic examples are java Applets and Servlets. Some of the answers already provide give the correct response, but I will try to elaborate a bit.
When you launch a Java app, you start a JVM and then you need to load something into it: so you need a static method (the main) because there are no objects (yet) living in the JVM that you can refer to.
If you have some sort of framework in the middle, it is the framework that will start the JVM and will start populating it with its own service objects: writing your code then means writing your own objects (which will be subclasses of given "template"). Your objects can then be injected (loaded) by the framework. The framework service objects manage the lifecycle of the injected objects by calling the lifecycle methods defined in the "template" superclass.
So for instance when you provide an applet to a browser, you do not launch a static main method: you rather only provide a subclass of java.applet.Applet that implements some instance methods which act as callback to manage the lifecycle (init, paint, stop...). It is the browser that will launch the JVM, instantiate what's needed for the launching an applet, load your applet and call it.
Similarly, with servlets you subclass the javax.servlet.http.HttpServlet class and implement some instance (non static) methods (doGet, doPost...). The Web container (e.g. Tomcat) will be in charge to launch the JVM, instantiate what's needed for launching a servlet, load your servlet and call it.
The pattern in Android is pretty much the same: what do you do is to create a subclass of android.app.Activity. When you launch an app, the system looks in the manifest to find out which activity should be started, then the "framework" loads it and calls its instance methods (onCreate, onPause, onResume...).
In Java programs we need a main() method, because while executing the byte code the JVM will search for the main() method in the class and start executing there.
In Android, the Dalvik Virtual Machine is designed to find a class which is a subclass of Activity and which is set to start the execution of the application from its onCreate() method, so there is no need of a main() method.
The order in which Dalvik Virtual Machine calls methods is based on order of priorities called android life cycle for more information on android life cycle check the link below
Android Life Cycle: https://developer.android.com/guide/components/activities/activity-lifecycle.html
While there is no specific main entry point, intent filters describe which activity is started when the application is launched.
They are controlled in AndroidManifest.xml as described here:
http://developer.android.com/guide/topics/intents/intents-filters.html
where a note pad application example is described:
This filter declares the main entry point into the Note Pad application. The standard MAIN action is an entry point that does not require any other information in the Intent (no data specification, for example), and the LAUNCHER category says that this entry point should be listed in the application launcher.
An android programmer should learn this like the back of their hands it simply explains everything and would help in the future when creating activities.
http://developer.android.com/reference/android/app/Activity.html
There is a main of sorts, it just happens to be out of your hands. After all, there's nothing special about a main function in any language. It's just the entry point where your code starts executing. The Android operating system expects applications to have a certain structure and it calls your code based on the conventions you follow.
I found this particularly useful...
http://developer.android.com/guide/topics/fundamentals.html#appcomp
Applets don't have main() methods either. It just depends on how your code is packaged.
The Android UI frame encapsulate some Java common details, you can study the source code of the android UI framework
I think that Jonathon's answer is going in the right direction. He says the OS expects a certain structure. There's a name for that structure which is a "state machine". In this case Android calls it the "activity lifecycle". Rob gives a link to the documentation which contains an important diagram of that state machine though the text is a bit dry. A quick search also found me the following link that explains it fairly clearly: http://www.android-app-market.com/android-activity-lifecycle.html
In Java, there is a main even if it isn't listed as main(). The page you get after the icon click, whatever its name, is the main().