In android, I want to use a string-array resource to create a public static final String in one of my classes. However, it seems I must call getResources() on a Context and I can't find any context at the class level. Is this possible?
public class DBAdapter {
Resources res = getResources();
public static final String[] gradeTypes = res.getStringArray(R.array.gradeTypes);
...
You can't do that. If you need the Context, you can pass it with constructor:
public class DBAdapter{
private Context mContext;
public DBAdapter(Context mContext) {
this.mContext = mContext;
}
}
But anyway you won't have a chance to use it at the gradeTypes initialization. Why do you need to declare it as final? If you want to use this array at inner classes, you can do it without final modifier.
Related
I have a Main class and another two classes named WebServicesClass and DynamicHeightAdpater.
I am creating an instance of DynamicHeightAdpater in WebServicesClass for which I need the context of MainActivity but I am not sure how to point it. The way by which I am calling throws a NullPointerException.
CODE :
MainActivity :
static Context context;
context = this.context;
WebServicesClass :
new DynamicHeightAdapter(MainActivity.context, 1, rowItems);
But it throws a null pointer exception and I am sure that it is due to the context cause I tried to print it and it threw NullPointer.
I would suggest you to take a look at the Android application class. You can store context there and retrieve it, when needed:
public class TestApplication extends Application {
private static Context mAppContext;
#Override
public void onCreate() {
super.onCreate();
mAppContext = getApplicationContext();
}
/**
* Returns the application's context. Useful for classes that need a Context
* but don't inherently have one.
*
* #return application context
*/
public static Context getAppContext() {
return mAppContext;
}
I suggest passing the Context to the WebServicesClass object in it's constructor, and having a member variable to keep it... something like
public class WebServicesClass
{
private Context mContext;
...
public WebServicesClass(Context c) // constructor
{
mContext = c;
}
void someOtherFunction()
{
new DynamicHeightAdapter(mContext, 1, rowItems);
}
}
I'd like to get my string-array without extending Activity in my custom class. Is there a way to do this?
String[] foo_array = getResources().getStringArray(R.array.foo_array); will not work without extending Activity, so I need a work-around.
Pass the context to the constructor of custom class and use the same
new CustomClass(ActivityName.this);
Then
Context mContext;
public CustomClass(Context context)
{
mContext = context;
}
use the context
String[] foo_array = mContext.getResources().getStringArray(R.array.foo_array);
Also keep in mind
Do not keep long-lived references to a context-activity (a reference to an activity should have the same life cycle as the activity itself)
http://android-developers.blogspot.in/2009/01/avoiding-memory-leaks.html
Also check this
android getResources() from non-Activity class
Edit:
Change this
public class CustomClass(Context context)
{
}
To
public class CustomClass
{
Context mContext;
public CustomClass(Context context) // constructor
{
mContext = context;
}
}
try this,
Context context=getApplicationContext();
String[] foo_array = context.getResources().getStringArray(R.array.foo_array);
And, do not use Activity Context as that is tied to the Activity life cycle.
Update,
getApplicationContext() is from Context class. That means any thing extended Context have this method. This also means you will be able to use this from service or from other resources.
But, if you custom class do not extend Activity/context, you have to pass Context as parameter to use getApplicationContext()
if you declare your activity like this
myMethod(Activity activity) //this is bad
Bud if it is like following,
myMethod(Context context) //this is ok
but from above declaration do not pass Activity or Service Context as they have own life cycle. instead you will use getApplicationContext()
You need pass the Activity context to the Custom class.
private Context context;
public CustomClass(Context context)
{
this.context=context;
}
if you use numberpicker and pass String from sring xml then use this
np_Basic_Hight.setMinValue(0);
np_Basic_Hight.setMaxValue(71);
np_Basic_Hight.setDisplayedValues(getContext().getResources().getStringArray(R.array.hieght));
Android documentation for Application states:
There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality [i.e. maintain global application state] 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.
My request is: Can you explain, and provide code sample that implements the above suggestion for maintaining global state.
Note that there is already a suggestion that recommends subclassing Application:
How to declare global variables in Android?
Thank you.
Correction to StinePike's answer regarding context in the ApplicationState. In the code posted the context passed in to the application state is held on to. If the context passed in is an activity or similar unit then the activity would be leaked and prevented from being garbage collected.
The android documentation for the Application class states you should "internally use Context.getApplicationContext() when first constructing the singleton."
public class ApplicationState {
private Context applicationContext;
private static ApplicationState instance;
private ApplicationState(Context context) {
this.applicationContext = context.getApplicationContext();
}
public static ApplicationState getInstance(Context context) {
if(instance == null) {
instance = new ApplicationState(context);
}
return instance;
}
}
If I am not wrong your are trying to save global variables without extending Application. If so you can do two things
if you don't need any context then you ca simply use a class with static members like this
public class ApplicationState {
public static boolean get() {
return b;
}
public static void set(boolean a) {
b = a;
}
private static boolean b;
}
And if you need a context but you don't want to extend Application you can use
Public class ApplicationState {
private Context context;
private static ApplicationState instance;
private ApplicationState(Context context) {
this.context = context;
public static ApplicationState getInstance(Context context) {
if (instance == null) {
instance = new ApplicationState(context);
}
return instance;
}
public void someMethod(){}
}
So you can call some method like this
ApplicationState.getInstance(context).somemethod();
VPAdapter.java
public class VPAdapter extends PagerAdapter
{
public static String[] titles;
public final Context context;
public int[] scrollPosition;
JSONArray categories = null;
JSONArray newstype = null;
JSONObject json;
DatabaseHandler db = new DatabaseHandler(context)//error:The blank final field context may not have been initialized
...
}
DatabaseHandler.java
public class DatabaseHandler extends SQLiteOpenHelper {
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
On VPAdapter.java I wanted to access DatabaseHandler anywhere, but there is problem with the constructor. What is the proper way I should write them?
You cannot pass a variable that was not initialize.
On your second line of the function you declare the context variable but you don't assign any value to it.
The last line should be written in the constructor of VPAdapter. The constructor should get a context variable. When you call your constructor you probably want to use the application context, but you might send also an activity (Activity inherit from context) but this is usually not recommended (But it really depends on your code)
Because your Context is null first initialize your context than you can pass that context to your database handler constructor.
Context context = getApplicationContext();
Or try below code
For example initialize your Context with your activity context.
Create constructor of your APAdapter class and call that constructor from your activity. Same way as you create for database handler.
public APAdapter(Context context) {
this.context = context;
}
than pass that context to your database handler.
In my java class I want to use a string resource from strings.xml.
for that I have to use like below,
getString(R.string.address)
if my class is an activity then its taking. But my class is a simple java class , how can I use there?
Is it possible?
Thank you
A class does not have a context and to use a string resource a context is needed. So just call the class from an activity and give a parameter context and within your class constructor just use that context to get the string resource.
In your custom class you need to import the R namespace for the project to get the resource Id.
import com.myrandomapp.R;
Then to get the actual string
context.getString(R.string.COOL_STRING)
You can pass the context of the Activity class to the java class and access the resources.
From your Activity Class
Helper helper = new Helper(this);
Your Java class
public class Helper {
Helper(Context c){
c.getString(R.string.address);
}
}
You can create a static Application Context in your custom Application class
public class App extends Application{
private static Context mContext;
#Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
}
public static Context getContext(){
return mContext;
}
}
Then you just need to call App.getContext().getResources() to get any resource values.
Just remember that this Context is Application type, so there are things that this Context is not good to use. Read this for further info.
You could done if you add this line:
// this is the object itself, and idString is the ID String bound to the literal.
this.getString(R.string.idString)
I hope this comment helps you!
Brs.