Assuming I have a shared activity class defined in a Library project, which does not change for any application using it and thus does not need to be subclassed, can I get a way with creating applications without subclassing this activity for them?
To better explain my question, say I have a single activity in a Library project:
public class LibActivity extends Activity {
...
}
And now I am creating an application using that Library project. Do I really need to create
public class AppActivity extends LibActivity {
// totally empty!
}
Only so that the application have its own activity to be referenced in its own AndroidManifest.xml?
Can I get a way with a minimalistic approach, in which I subclass the activity only if I need to modify the library's activity core behavior?
Here is the fully qualified answer:
Yes, an activity based application doesn't have to derive an activity from the library's activity. The application simply uses the library's activity verbatim, unmodified.
Yes, I can get a way with a minimalistic approach, in which I subclass the activity only if I need to modify the library's activity core behavior.
I have been able to verify this with an AndroidManifest.xml that is identical in both the library and the application. It would be interesting to see whether some of this redundancy can be eliminated. I will experiment with this and report back.
UPDATE: Sure enough, it is possible to create a perfectly running application in which the only activity is defined in the library and the library's AndroidManifest.xml doesn't have any <application> or <activity>! This is possible if the application's AndroidManifest.xml has them.
You can reference library Activity classes directly from your application AndroidManifest.xml. Just specify the fully qualified name like so android:name="com.example.LibActivity"
Related
Is it okay or possible to extend the Application class in android twice and have two childs of it in an application? And also why do we need it & what's the purpose of extending it?
Is it okay or possible to extend the Application class in android twice and have two childs of it in an application?
You can only have one registered Application subclass in the android:name attribute of the <application> element. You are welcome to create as many subclasses of Application as you want, but only one will be used. However, you are welcome to have MyApp extend Application, have MyOtherApp extend MyApp, and register MyOtherApp in the manifest.
And also why do we need it
Few apps need it. Quoting the documentation, "There is normally no need to subclass Application".
what's the purpose of extending it?
If you have application logic that needs to be executed every time Android forks a process for you, Application is a common place to trigger that logic. For example, most crash logging libraries (e.g., ACRA) have you configure them in an Application subclass, so that they can handle crashes from everywhere else in your app, for every one of your processes.
You want something like this?
MyApp extends Application
MySecondApp extends MyApp
This is possible. There are several usecases for this. For example define an Application for your App but override it for a specific build type or product flavor (e.g. debug). Or a custom Application for your (Android) Tests:
MyApp extends Application
MyDebugApp extends MyApp
MyTestApp extends MyApp/MyDebugApp
Define each Application Class in the according AndroidManifest:
MyApp => main package
MyDebugApp => debug package
MyTestApp => androidTest package
Yes, it's possible. The reason extend classes is to reuse code written in the parent class and extend its functionality.
TLDR:
I have to extend the application class but don't know where to start.
Ok... I know this is a dumb one but I have to ask it.
I need to install LeakCanary and I see in their documentation that it requires me to put code in the Application Class.
I understand how to make a java class that extends the application class, but I have some questions before I do this.
SITUATION:
I have 9 classes in my app already.
The entry point to my app is MainActivity.class (figures, right?)
I have not had to extend the Application Class yet.
App name is "CST-ALERT"
QUESTIONS:
Do I just create a new Java class in my java source folder and name it the same as my overall
package name? What do I name this new class?
Do I need to adjust the manifest now to have this as the entry point
instead of MainActivity? Which I imagine will change things quite a
bit for me.
Do I have to change anything else in the manifest? I assume I will
at least have to declare it in there.
Hopefully my situation and questions will give you an idea of what I am asking.
Do I just create a new Java class in my java source folder
Yes.
and name it the same as my overall package name?
If by "it", you mean the Java package, you already have a directory for your existing Java code. Put your subclass of Application in there, unless you have a clear reason not to.
In this trivial sample app, I put my Application subclass in the same directory as my launcher Activity, which is the directory for my Java package (com.commonsware.android.button).
What do I name this new class?
That is up to you. I called it CanaryApplication. If you think you leak a lot, call it CoalMine. So long as it is a legal Java class name, it doesn't matter.
Do I need to adjust the manifest now to have this as the entry point instead of MainActivity?
Um, well, I wouldn't describe MainActivity as the entry point. Regardless, MainActivity is left alone. You need to add an android:name attribute to the <application> element, identifying your Application subclass.
Do I have to change anything else in the manifest?
No, that should suffice.
I'm working on code that will be stuck inside other people's apps. I have two activities that both play off of a video view (with slightly different behavior). However, i'd definitely like to NOT rely on other people manually having to declare AndroidManifest.xml activities that i create. (some developers might just forget to declare it in their manifest)
So essentially, i'd like to be able to tell android to load an activity which is not declared in Manifest. How do i do this?
here are my thoughts:
1) I've tried subclassing a declared activity (declared activity referring to it being declared in AndroidManifest). however, calling this subclass throws a ActivityNotFoundException not surprisingly.
2) i COULD pass in a static view via a static method like:
public class Blah extends Activity {
private static VideoView badIdea;
public void setBadIdeaView(VideoView vv) { badIdea = vv; }
//... start it up as usual, but `badIdea` is now configured
}
but i really don't want to do this because a view holds on to a context, and i DO NOT want a static strong reference to an Activity context.
3) does anyone know how Android actually loads your activities? i'm guessing Android uses reflection to open an instance of the class.... but... i mean, why do activities have to be declared in a Manifest? is this for security purposes in order to prevent bad dynamic classloading? is this a possible solution?
thanks
How do i do this?
You don't. All activities must be declared in the manifest.
However, i'd definitely like to NOT rely on other people manually having to declare AndroidManifest.xml activities that i create.
As suggested in a comment, if your code is implemented as an Android library project, you can try relying upon manifest merging.
some developers might just forget to declare it in their manifest
So? They should catch it in testing. You can also add sanity-checking to your exposed API, where you see if the app has your activities registered, by means of PackageManager, so that way your code will "fail fast" if they did not follow your instructions.
I have a project (in Eclipse) which I've turned into an Android Project Library so as to re-use some of the code in another similar project. I think I've shot myself in the foot however as I'm getting the error:
Unable to start activity ComponentInfo{com.test.scroller1/com.lib.scrolltest.ScrollTestActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.lib.scrolltest.resAppVars
com.lib.scrolltest is my Project Library which instantiates a class extending Application (resAppVars). In the onCreate() method I call:
mRav = (resAppVars) getApplicationContext ();
This way, I can use methods in the mRav object which would otherwise be a lot of duplicated code in other classes (such as passing a query to a generic select statement which returns an ArrayList of results).
What's the problem here? It seems I've hit a limitation in the way I've implemented the Application class.
Calling getApplicationContext() returns the Application object for the current application (i.e. the application that owns the activity that onCreate() is running inside of).
Unless you're doing something strange, you don't get to pick which Application class is used. There's even a note in the documentation for Application saying not to do this:
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.
You should just create a regular shared class inside of your library project. Or if you don't have a need for the special functionality library projects offer, you can also just use a regular .jar file.
And if you need shared state, just make it a singleton. ;)
Although this is a very old post. I encountered the same problem and solved it. So I thought I'll post the solution for everyone.
It turns out that I forgot to declare the subclassed application name in the manifest file.
The android:name should point to the extended app class, even if it is defined in the referenced library.
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name="com.example.lib.MyApp">
After I added that I could use the extended app with (<cast>) getApplication() anywhere in my project.
I want to open an activity without declaring it in an manifest file.
I don't know if it is possible or not.
What I actually want is to dynamically open an activity from my program using intents.
Can anyone help me if it is possible.
Not possible. Although I am unsure what you mean "dynamically open an activity".
See: http://developer.android.com/reference/android/app/Activity.html
Under Class Overview it states "To be of use with Context.startActivity(), all activity classes must have a corresponding declaration in their package's AndroidManifest.xml"
You can have an Activity in your package and not define it in the manifest, however you would not be able to start it successfully.
Your 'Dynamic' activity start is actually the normal way of starting an activity (as you have said in a comment to the answer of Matt M). Though you HAVE to add the Activities in manifest as Matt M said. In list view, clicking an activity will call a function that will start respective activity with startActivity() function.
I tried this very long, but since the Instrumentation class uses the IActivityTaskManager, which is a class of the internal API located at com.android.server.wm, that is not in the Activity classloader, I solved this by another method:
Using a subclass
I just made an Gist, with sample code.
GIST