Access Application Context from class that doesn't extend Activity/Service - android

I handle login for my application in a class that extends application. The application then maintains an object of this class at all times. This means that I can access that specific object from any class that extends activity or service by calling
LoginModeller lm = ((LoginModeller)getApplicationContext());
However, I now need to access the object from a class that does not extend activity or service (It extends nothing). Is there some way to access the application context from a class like this, or I do have to re-factor my LoginModeller as a singleton or something?

Who creates this object? In your constructor you can pass in a Context and store it as an instance variable:
private final Context context;
public MyObject(Context context) {
this.context = context;
...

I don't know if you are using DI with roboguice but I am :)
From my point of view, the cleanest way to do this is using a staticInjection. Here's how.

Related

Android Studio context returning null

I have a class that's inputting some data into SharedPreferences.
private static Context context;
context = MainActivity.getContext();
sp = (SharedPreferences) context.getSharedPreferences("currentData", Context.MODE_PRIVATE).edit();
SharedPreferences.Editor editor = sp.edit();
editor.putString("name", placeName);
editor.apply()
I set the context using a method in my MainActivity class:
public static Context getContext(){
return context;
}
However I keep getting a null object reference. Tried multiple solutions from stack overflow and can't overcome the issue.
Why is context returning null?
This is because MainActivity.getContext() is null try passing the context from MainActivity to your class.
public Context context;
public YourClass(Context context) {
this.context= context;
}
In MainActivity init it like this:-
YourClass yours = new YourClass(MainActivity.this);
And also avoid using static contexts it might cause memory leaks !!
Context is an abstract class whose implementation is provided by the
Android system
Context is provided to any Activity by the android system during runtime (Activity indirectly extends Context). You are trying to get Context from MainActivity class via static method, which will not work and will always return null:
context = MainActivity.getContext();
You should always get Context from an instance of Activity, not the class itself. You can do this easily by passing an instance of your current Activity to the constructor of your class. Then, you call getContext() on an INSTANCE of that Activity, not the Activity class itself.
Also, wanted to mention that your code is mostly anti-pattern. You should never store Context in static variables. I'd recommend you read more about Activity lifecycle in android and Context - these are fundamental knowledge.
You can get context statically throughout the application
please try below code:
In the Android Manifest file, declare the following.
<application android:name="com.xyz.MyApplication">
</application>
Use this class
public class MyApplication extends Application {
private static Context context;
public void onCreate() {
super.onCreate();
MyApplication.context = getApplicationContext();
}
public static Context getAppContext() {
return MyApplication.context;
}
}
Now you can call MyApplication.getAppContext() to get your application context statically.
You are getting the context from a static method in the class, that mean that method is called before the class is actually initialized. If there is no actual instance of the activity or if the OS haven't provide with context to the activity, then is null. The Activity has access to the contexto but after the Android underlining management initialized it, the class won't have the context by it self because it is there, if you notice Activities are never instantiated using the constructor because Android does it for you.
If you want to use a static method to having a nice syntax then the static method should be inside the class that use the shared preferences and should be passed from the activity, during any method of the Activity life cycle or when the user interacts with the ui (those listeners are set on the Activity life cycle).
class MyPreferences {
static void save(String toSave, Contex context) {
//TODO your operation here
}
}
And your activity:
public class MainActivity extends AppCompatActivity {
//Below is pseudo code, be careful on doing this precisely in the activity
#Override
onCreate() {
//TODO call super and setContentView
MyPreferences.save("foo", this);
}
}
It seems your problem is you are trying to make the other class to use the Activity, but in Android is the Activity that uses other classes

How to run a service from a class?

I have a class like this :
public class ExpandableListAdapter extends BaseExpandableListAdapter {
I want to run a service from this class. But as I know, services can only be run from Activitys . So what is the solution?
How can I start a service and control it from another class?
But as I know, services can only be runned from Activitys
That's not true. In order to run the service you just need a context, that is usually a reference to your activity.
So, inside ExpandableListAdapter you just make sure that the constructor receives an instance of your activity:
public ExpandableListAdapter(Context context){
mContext = context;
}
// somewhere else
mContext.startService(theIntent);
Most adapters have a context so you can make a call to getContext() which will give you a context back. This adapter does not have a context so you should have a custom constructor that takes a context and calls its super. Using the context you passed in you can call startService(Intent intent) just like you would in an activity.

How can i reach getResources() and Context except Activity class?

I know this question is general but I am always face to face this problem.
My question is I can reach getResource() or getContext() in Activity but when I want to use a class without activity
example:
public class MapOverlay extends ItemizedOverlay
I can not reach getResources() or Context.
How can I do that anybody know any trick?
I usually do it the following way:
Create a class that extends Application, say MyApp.
Declare a private static Context context field
Declare a (static) getter for the context field
Initialize the field in onCreate(): context = this
Now context is available across all application via MyApp.context()
ItemizedOverlay in not extending android.content.Context.
You can create the construcor like
private Context mContext;
public MapOverlay(Context context){
this.mContext=context;
}
and then use the mContext field to call getResource() or getContext() methods.
Just expose a public method inside your MapOverlay that takes a Context.
public void setContext(Context context) {
mContext = context;
}

How to obtain AssetManager without reference to Context?

I have a class that needs to obtain a reference to it's application's AssetManager. This class does not extend any sort of android UI class, so it doesn't have a getContext() method, or anything similar. Is there some sort of static Context.getCurrentApplicationContext() type of method?
To clarify: my class is intended to be used like a library, for other applications. It has no associated AndroidManifest.xml or control over the context which is calling it.
Create a subclass of Application, for instance public class App extends Application {
Set the android:name attribute of your <application> tag in the AndroidManifest.xml to point to your new class, e.g. android:name=".App"
In the onCreate() method of your app instance, save your context (e.g. this) to a static field named app and create a static method that returns this field, e.g. getApp():
This is how it should look:
public class App extends Application{
private static Context mContext;
#Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getContext(){
return mContext;
}
}
Now you can use: App.getContext() whenever you want to get a context, and then getAssetManager() (or App.getContext().getAssetManager()).
I am not sure of the best answer to the OP question. However, I do know that you have to be very careful when using a static context as suggested in Android developer resources:
In the onCreate() method of your app instance, save your context (e.g. this) to a static field named app and create a static method that returns this field, e.g. getApp():
Using static contexts can leak to leaked memory issues, especially if the static context is used for references to views.

Accessing Drawable resources from a non context class

I'm defining a class that sets a Drawable attribute in an object. The problem is that I can't access the getResource().getDrawable(int resourceId) method unless I have some Context.
What I did was to send to that class an activity instance (let's call it "act") and then I did:
act.getResources().getDrawable(R.drawable.whellchair)
but, when executing that line it throws a NullPointerException.
When idea how to accomplish this?
I found the problem!
I'm using a singleton and I put the line accessing the "act" in a static method... how fool of me ...
Sorry and thank you Juhani for the comment :)
Pass that the application context to the constructor of your class. In the main application class you just get the context by invoking the getApplication() method if you need the a lifetime aware context or getApplicationContext() if you need a the context which is tied to the current process.
Example:
private Context ctx = getApplication();
... some code ...
MyClass myClass = new MyClass(ctx);
Your classes' constructor of course has to handle the context accordingly (i.e. setting a private member of type Context to the passed value) like this.
private Context ctx = null;
public MyClass(ctx) {
this.ctx = ctx;
}
Then you can use the context for whatever you need.

Categories

Resources