I am looking for information regarding writing my own application class. In many tutorials on the net I have seen the following code:
class myapp extends Application
{
private static myapp mm;
private Context context;
public Context getContext()
{
return getApplicationContext();
}
public myapp getmyapp()
{
if(mm == null)
mm = new myapp();
return mm;
}
}
What is the difference in getting object of myapp and getApplicationContext and where to use object of myapp and where to use context object. I just want to clear the concept of usage of these objects.
that code is completely wrong:
public myapp getmyapp()
{
if(mm==null)
mm=new myapp();
return mm;
}
only the Android framework can instantiate the Application object. I mean, you can call new but the object won't be "connected" to the underlying framework
To have a static reference of the application object you should do as follows:
class MyApp extends Application{
// I fixed the names to follow some Java convention
private static MyApp instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static MyApp getMyApp(){
return instance;
}
Regarding the context, the code is not wrong, but simply doesn't make any sense. That's because the Application object already is the application context. So there's not need to ask for it.
Context is what gives Android apps access to resources, file system specific folders, permissions, etc (what I said about the Android framework creates it). The Application is one class that extends Context, other examples are Activity and Service classes.
I hope it's a bit clearer.
Related
I have created one class that is extending Application class and using the static method to expose the contexts as follows. moreover i am using many util methods like checking internet connections e.c.t into this class.
Problem is i am not sure
how safe is to use following method to expose the application level context
would this create any memory leaks when i will use App.getAppContext() method
public class App extends Application {
private static Context mContext;
#Override
public void onCreate() {
super.onCreate();
mContext = this.getApplicationContext();
}
public static Context getAppContext() {
return mContext;
}
}
I have access to application context but not to application. I want to get the application (so I can get all running activities), but couldn't find a way to do so. Is there an existing API to get application from application context or I will have to override getApplicationContext for that?
No, there's no such API out of the box. However, you can either get application context and cast it to Application object, or Extend Application class, and make it a singleton so you can grab an instance of it from everywhere.
public class MyApplication extends Application {
private static MyApplication singleton;
// Returns the application instance
public static MyApplication getInstance() {
return singleton;
}
public final void onCreate() {
super.onCreate();
singleton = this;
}
}
I'm working on an Android application that has several Activities. In it I have a class with several static methods. I would like to be able to call these methods from the different Activities. I'm using the static methods to load data from an xml file via a XmlResourceParser. To create a XmlResourceParser requires a call on the Application Context. So my question is, what is the best way to get a reference to the Application Context into the static methods? Have each Activity get it and pass it in? Store it somehow in a global variable?
The better way would be to pass the Activity object as parameter to the static functions.
AFAIK, there is no such method which will give you the application context in the static method.
This should get you access to applicationContext from anywhere allowing you to get applicationContext anywhere that can use it; Toast, getString(), sharedPreferences, etc. I have used this to get applicationContext inside of static methods multiple times.
The Singleton:
package com.domain.packagename;
import android.content.Context;
/**
* Created by Versa on 10.09.15.
*/
public class ApplicationContextSingleton {
private static PrefsContextSingleton mInstance;
private Context context;
public static ApplicationContextSingleton getInstance() {
if (mInstance == null) mInstance = getSync();
return mInstance;
}
private static synchronized ApplicationContextSingleton getSync() {
if (mInstance == null) mInstance = new PrefsContextSingleton();
return mInstance;
}
public void initialize(Context context) {
this.context = context;
}
public Context getApplicationContext() {
return context;
}
}
Initialize the Singleton in your Application subclass:
package com.domain.packagename;
import android.app.Application;
/**
* Created by Versa on 25.08.15.
*/
public class mApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
ApplicationContextSingleton.getInstance().initialize(this);
}
}
If I´m not wrong, this gives you a hook to applicationContext everywhere, call it with ApplicationContextSingleton.getInstance.getApplicationContext();
You shouldn´t need to clear this at any point, as when application closes, this goes with it anyway.
Remember to update AndroidManifest.xml to use this Application subclass:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.domain.packagename"
>
<application
android:allowBackup="true"
android:name=".mApplication" <!-- This is the important line -->
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:icon="#drawable/app_icon"
>
Please let me know if you see anything wrong here, thank you. :)
I am not sure this is going to work all the time but it works for me now:
public class myActivity extends ListActivity
{
public static Context baseContext;
public void onCreate(Bundle savedInstanceState)
{
baseContext = getBaseContext();
}
Then you may use the static in your package:
myApplication.baseContext
There's a post in Sane Tricks For InsaneWorld blog with an answer.
It says you can replace the Application object with your own subclass and then keep the app context statically there.
You can find example code in the post.
The original blog post - http://uquery.blogspot.co.il/2011/08/how-to-get-application-context.html
I'm considering creating a singleton wrapper for a Context so my model objects, if necessary, can open and read from a database connection. My model objects do not have access to a Context, and I'd like to avoid needing to pass a reference to a Context from object to object.
I was planning to place into this singleton a reference to the Context returned by Application.getApplicationContext(). This singleton object would be initialized in my custom Application instance before anything else would need to or have a chance to use it.
Can anyone think of a reason to not do this?
I would urge you to think about what reasons you have for not passing a reference of the application context into your model objects.
There are various well-documented disadvantages of using singletons. I won't go into detail here but you might want to consider:
How singletons limit your ability to properly unit-test your application.
Singletons hide dependencies between different entities in the code- you cannot determine dependecies from inspecting the interfaces.
You have no real control over the lifetime of a singleton, it could exist for the lifetime of your application. Do you really want to potentially hold a DB connection for the lifetime of your app?
The thread safety of your singleton.
If you valid reasons for not passing a reference to a context to other parts of your application then perhaps you should consider some other pattern- a factory might be one possible solution, a service another.
I'm not sure I get your idea, but here's what's been working for me:
public class MyApp extends Application {
private static MyApp instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
// ...
}
public static MyApp getInstance(){
return instance;
}
// misc helper methods
}
Pasted here to preserve formatting.
public class ContextContainer
{
private static boolean initialized;
private static Context context;
private ContextContainer()
{
//
}
public static synchronized void setApplicationContext(Context context)
{
if (!initialized) {
ContextContainer.context = context;
initialized = true;
} else {
throw new RuntimeException("ApplicationContext has already been set!");
}
}
public static synchronized Context getApplicationContext()
{
return context;
}
}
In an Android app, is there anything wrong with the following approach:
public class MyApp extends android.app.Application {
private static MyApp instance;
public MyApp() {
instance = this;
}
public static Context getContext() {
return instance;
}
}
and pass it everywhere (e.g. SQLiteOpenHelper) where context is required (and not leaking of course)?
There are a couple of potential problems with this approach, though in a lot of circumstances (such as your example) it will work well.
In particular you should be careful when dealing with anything that deals with the GUI that requires a Context. For example, if you pass the application Context into the LayoutInflater you will get an Exception. Generally speaking, your approach is excellent: it's good practice to use an Activity's Context within that Activity, and the Application Context when passing a context beyond the scope of an Activity to avoid memory leaks.
Also, as an alternative to your pattern you can use the shortcut of calling getApplicationContext() on a Context object (such as an Activity) to get the Application Context.
In my experience this approach shouldn't be necessary. If you need the context for anything you can usually get it via a call to View.getContext() and using the Context obtained there you can call Context.getApplicationContext() to get the Application context. If you are trying to get the Application context this from an Activity you can always call Activity.getApplication() which should be able to be passed as the Context needed for a call to SQLiteOpenHelper().
Overall there doesn't seem to be a problem with your approach for this situation, but when dealing with Context just make sure you are not leaking memory anywhere as described on the official Google Android Developers blog.
Some people have asked: how can the singleton return a null pointer?
I'm answering that question. (I cannot answer in a comment because I need to post code.)
It may return null in between two events: (1) the class is loaded, and (2) the object of this class is created. Here's an example:
class X {
static X xinstance;
static Y yinstance = Y.yinstance;
X() {xinstance=this;}
}
class Y {
static X xinstance = X.xinstance;
static Y yinstance;
Y() {yinstance=this;}
}
public class A {
public static void main(String[] p) {
X x = new X();
Y y = new Y();
System.out.println("x:"+X.xinstance+" y:"+Y.yinstance);
System.out.println("x:"+Y.xinstance+" y:"+X.yinstance);
}
}
Let's run the code:
$ javac A.java
$ java A
x:X#a63599 y:Y#9036e
x:null y:null
The second line shows that Y.xinstance and X.yinstance are null; they are null because the variables X.xinstance ans Y.yinstance were read when they were null.
Can this be fixed? Yes,
class X {
static Y y = Y.getInstance();
static X theinstance;
static X getInstance() {if(theinstance==null) {theinstance = new X();} return theinstance;}
}
class Y {
static X x = X.getInstance();
static Y theinstance;
static Y getInstance() {if(theinstance==null) {theinstance = new Y();} return theinstance;}
}
public class A {
public static void main(String[] p) {
System.out.println("x:"+X.getInstance()+" y:"+Y.getInstance());
System.out.println("x:"+Y.x+" y:"+X.y);
}
}
and this code shows no anomaly:
$ javac A.java
$ java A
x:X#1c059f6 y:Y#152506e
x:X#1c059f6 y:Y#152506e
BUT this is not an option for the Android Application object: the programmer does not control the time when it is created.
Once again: the difference between the first example and the second one is that the second example creates an instance if the static pointer is null. But a programmer cannot create the Android application object before the system decides to do it.
UPDATE
One more puzzling example where initialized static fields happen to be null.
Main.java:
enum MyEnum {
FIRST,SECOND;
private static String prefix="<", suffix=">";
String myName;
MyEnum() {
myName = makeMyName();
}
String makeMyName() {
return prefix + name() + suffix;
}
String getMyName() {
return myName;
}
}
public class Main {
public static void main(String args[]) {
System.out.println("first: "+MyEnum.FIRST+" second: "+MyEnum.SECOND);
System.out.println("first: "+MyEnum.FIRST.makeMyName()+" second: "+MyEnum.SECOND.makeMyName());
System.out.println("first: "+MyEnum.FIRST.getMyName()+" second: "+MyEnum.SECOND.getMyName());
}
}
And you get:
$ javac Main.java
$ java Main
first: FIRST second: SECOND
first: <FIRST> second: <SECOND>
first: nullFIRSTnull second: nullSECONDnull
Note that you cannot move the static variable declaration one line upper, the code will not compile.
Application Class:
import android.app.Application;
import android.content.Context;
public class MyApplication extends Application {
private static Context mContext;
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
}
public static Context getAppContext() {
return mContext;
}
}
Declare the Application in the AndroidManifest:
<application android:name=".MyApplication"
...
/>
Usage:
MyApplication.getAppContext()
You are trying to create a wrapper to get Application Context and there is a possibility that it might return "null" pointer.
As per my understanding, I guess its better approach to call- any of the 2
Context.getApplicationContext() or Activity.getApplication().
It is a good approach. I use it myself as well. I would only suggest to override onCreate to set the singleton instead of using a constructor.
And since you mentioned SQLiteOpenHelper: In onCreate () you can open the database as well.
Personally I think the documentation got it wrong in saying that There is normally no need to subclass Application. I think the opposite is true: You should always subclass Application.
I would use Application Context to get a System Service in the constructor. This eases testing & benefits from composition
public class MyActivity extends Activity {
private final NotificationManager notificationManager;
public MyActivity() {
this(MyApp.getContext().getSystemService(NOTIFICATION_SERVICE));
}
public MyActivity(NotificationManager notificationManager) {
this.notificationManager = notificationManager;
}
// onCreate etc
}
Test class would then use the overloaded constructor.
Android would use the default constructor.
I like it, but I would suggest a singleton instead:
package com.mobidrone;
import android.app.Application;
import android.content.Context;
public class ApplicationContext extends Application
{
private static ApplicationContext instance = null;
private ApplicationContext()
{
instance = this;
}
public static Context getInstance()
{
if (null == instance)
{
instance = new ApplicationContext();
}
return instance;
}
}
I'm using the same approach, I suggest to write the singleton a little better:
public static MyApp getInstance() {
if (instance == null) {
synchronized (MyApp.class) {
if (instance == null) {
instance = new MyApp ();
}
}
}
return instance;
}
but I'm not using everywhere, I use getContext() and getApplicationContext() where I can do it!
I know the original question was posted 13 years ago, and this is the Kotlin version of getting context everywhere.
class MyApplication : Application() {
companion object {
#JvmStatic
private var instance: MyApplication? = null
#JvmStatic
public final fun getContext(): Context? {
return instance
}
}
override fun onCreate() {
instance = this
super.onCreate()
}
}