Getting string resource from xml file outside onCreate method - android

I am trying to use a String from the string.xml file as a key in a key-value pair. However when I try to declare the variable before the onCreate() method, the program crashes. So if I use the following code I get an error:
public class MainActivity extends ActionBarActivity {
String MAX_SQUAT = getResources().getString(R.string.max_squat);
protected void onCreate(Bundle savedInstanceState) {
//blah blah blah
}
}
Whereas when I declare MAX_SQUAT inside the onCreate() method, there is no problem. I want to declare it outside of onCreate() method so I don't need to define it in other methods

You need a Context to get resources (as you can see in the Docs getResources() is a method of Context). Since the Context isn't available before onCreate(), you can't do this.
You can declare the variable before onCreate() but you can't initialize it until after onCreate() has been called.
Ex.
public class MainActivity extends ActionBarActivity {
String MAX_SQUAT;
protected void onCreate(Bundle savedInstanceState) {
// super call, set content view
// now you can get the string from strings.xml safely
MAX_SQUAT = getResources().getString(R.string.max_squat);
}
Declaring it as a member variable this way but initializing it in onCreate() will allow you to use it throughout the class and keep it from crashing.

Related

Can you use a constructor in Child Activity to change Parent Activity String variable?

I have a Parent Activity class that all my Child Activity classes extend from.
This parent activity has a field called 'activity_Id' that is a String and defaults to be null.
In the onCreate of the Parent Activity, I need to check if that field has a value, which it would only get from the Child Activity if it does I do some other logic in the onCreate of the parent activity.
Note, that each activity has a unique 'activity_Id' that it is used to alter the other logic that is being done.
Here is the ParentActivity:
public class ParentActivity extends Activity{
protected String activity_Id = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(activity_Id != null)
//DO OTHER LOGIC UNIQUE TO THIS STRING ID
}
}
Here is the ChildActivity:
public class ChildActivity extends ParentActivity{
public ChildActivity(){
super();
activity_Id = "Foo123";
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
This activity_Id String is predetermined but does not match the Activities name so I can not do
this.getClass().getName()
in my ParentActivity class.
This seems like the cleanliness way BUT there seems to be some taboo around using constructors in activities so I just want to make sure I do not break anything. Or if someone can think of a cleaner way to do it?
This can be done with abstract class because constructor don't construct an activity directly.
Try it like this
public abstract class ParentActivity extends Activity{
protected abstract String activityId();
.....
}
Then in child activity override activityId() with required value. And now you can compare activityId() in ParentActivity onCreate(...) method.

Android: Can I get the ID of the layout of an activity in code outside of this activity

I have a plain class (not an activity), which has a reference to an activity. Is it possible and how, to obtain the ID of the layout file which is used as content view by that activity?
As wsanville pointed out, you can just pass the int you're using for the layout to the constructor of the non-activity class you have. I'm assuming you're constructing said class in the onCreate method of the activity. So:
public void onCreate(bundle icicle){
...other stuff...
setContentView(R.id.layout_id);
OtherClass myClass = new OtherClass(R.id.layout_id);
...other stuff...
}
There is unfortunently no method I can find on the Activity documentation that is a "get" version of the setContentView method.

Android : Passing a value between activities

In my Android application I have to use common string value for all activities. "commonValue" is the common string value that I want to use in all activities. Relevant code of the main activity like this :
public class TestActivity extends Activity {
public String commonValue;//THE COMMON STRING FOR ALL ACTIVITIES
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
commonValue = "DemoValue";
}
}
In my next activity I created an object of "TestActivity" class and tried to assign "testValue" string to another string named "str"
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testlist);
TestActivity obj = new TestActivity();//OBJECT OF MAIN ACTIVITY
String str = obj.commonValue;
}
but the "str" value in second activity does not equal to the value assigned in my first activity. Why is that & How can I do this?
Thanks!
Put your value in string.xml
<string name="common_value">DemoValue</string>
and use in any activity like this..
String common_value = getApplicationContext().getString(R.string.common_value);
Start using SharedPreferences in your app.
In your first activity you would do
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("commonValue", "DemoValue");
editor.commit();
In your second activity
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
String str = settings.getString("commonValue", null);
Try this -
TestActivity.java
public class TestActivity extends Activity {
public static String commonValue;//THE COMMON STRING FOR ALL ACTIVITIES
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
commonValue = "DemoValue";
}
}
another activity
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.testlist);
String str = TestActivity.commonValue;
}
If the value is always the same you can create a public static final variable and access it via TestActivity.COMMON_VALUE.
If you want to pass around a value between to Activities you should use Intents and add an extra with the value you want to pass.
As Sana has suggested, use SharedPreferences.
Alternatively, use a global constant class. If you want to stick with what you have, then you could try:
String str = TestActivity.this.commonValue;
Your existing code is creating a new instance of the activity, so it's not going to have the value you had set.
To pass data between activities use Bundle. and methods,
intent.putExtra()
and If you want to set data to be global to your app, then create an application class, and save the data there.
We have an Application file for each app you can declare the variable there and as the Application file can get from any activity so using the public getter setter and can get/set that
there are vaious oter metjod you can sue as mention on developer.android http://developer.android.com/resources/faq/framework.html
Singleton class
A public static field/method
A HashMap of WeakReferences to Objects (almost same as my above solution )
Persistent Objects
take a look on them as well
The reason why commonValue doesn't equal what you set in TestActivity onCreate method is because that function hasn't been called yet.
The solution for this is already mentioned by others. Like putting the value in a bundle.

on Create and on Start method not called

Actually i have created an singleton class. Now my singleton class extends Activity, and i have write onCreate() and onStart() method on this class. But it is never called.The code i have used is shown below. If anyone knows help me to solve these out.
Code
public class cycleManager
{
private static CycleManager m_cycleManagerObj;
private CycleManager()
{
// Initialise Variable
onInitialization();
readData(this); // show error when call from here
}
public static synchronized CycleManager getSingletonObject()
{
if (m_cycleManagerObj == null)
{
m_cycleManagerObj = new CycleManager();
}
return m_cycleManagerObj;
}
public Object clone() throws CloneNotSupportedException
{
throw new CloneNotSupportedException();
}
public void writeData(Context c)
{
SharedPreferences preferencesWrite = c.getSharedPreferences("myPreferences", 0);
SharedPreferences.Editor editor = preferencesWrite.edit();
// work to be done
}
public void readData(Context c)
{
SharedPreferences preferencesRead = c.getSharedPreferences("myPreferences", 0);
// work to be done
}
}
The thing is Android manages activities in its own manner: from calling a constructor to calling all lifecycle methods. So if you declare your Activity's constructor as private then Android will not be able to manage this activity.
Why do you need singleton Activity-class? Consider different launch modes
check your activity in the AndroidManifest.xml.
<activity
android:configChanges="orientation|keyboardHidden"
android:name=".ActivityName">
They are not public method.They are protected method.You should override existing method.try like the following.
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
The key here is that Android is supposed to be managing your activity lifecycle, not you.
onCreate and onStart (along with onPause, onDestroy and all the other android activity lifecycle functions) are called by the looper on Android's main thread.
How did you start this activity? Was it declared in your manifest as your main activity and launcher? Did you call startActivity and pass the class name?
The fact that you are creating a singleton instance of your activity, and that its constructor is private, suggests to me that Android would be unable to start this activity when you want it to, though some function for passing an existing activity to be managed may exist, and I've just never seen it.
If onCreate and onStart are never being called, it means Android doesn't know it is supposed to be running your activity.
You get an error because your class is not a subclass of Context. Add Context attribute to getSingletonObject(Context context) method and pass it to CycleManager(Context context) constructor.

Android: How to set static value before onCreate is called

I want to have an "option" set before the Activity is created or at least before it starts. If there is a way to do this via the AndroidManifest? Consider this example where we have a global config class that is used in onCreate to instantiate an object (not fully OO for brevity)
public class Global {
public static boolean visible = false;
}
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
MyObject obj = new MyObject(Global.visible);
}
}
Obviously in this case "visible" would be "false". If this were some sort of API library, we would like to provide the option for users to set "visible" to "true".
Update 1
The objective is to have the global class in a pre-compiled library and have its value set by a developer utilizing the library. I am looking for easiest way for the developer to do this when they create their application; I think the manifest is the probably the way to go but I don't know how to inject the value for "visible" via the xml. The answers below using preferences are good but only cover the users point-of-view.
Update 2
IMHO using resources works best here.
<bool name="visible">true</bool>
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
Resource res = getResource();
MyObject obj = new MyObject(res.getBoolean(R.bool.visible));
}
}
I think using SharedPreferences would do what you are looking for, using Global.visible as the default value. Then if the user changes it to true, it will use that value.
boolean makeVisible = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
"MyVisiblePreference",
Global.visible);
MyObject obj = new MyObject(makeVisible);
To allow the preference to be updatable without re-compiling or setting (through a Preferences activity), you can load the default preference from resources:
<bool name="MyVisiblePreference">true</bool>
And reference it similarly with:
boolean makeVisible = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
"MyVisiblePreference",
getResources().getBoolean(R.bool.MyVisiblePreference));
If the developer does not set the preference to false, it will default to true (based upon the resources value).
For simple objects you can create them like this: (Based off of your code example)
public static boolean visible = false;
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
MyObject obj = new MyObject(Global.visible);
}
}
For a more complex object you can initialize it with a static initializer like this:
public static boolean visible;
static {
visible = false;
}
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// here is where we want the most up-to-date value of visible
MyObject obj = new MyObject(Global.visible);
}
}
You can subclass android.app.Application, this class has method onCreate that you can override. Your subclass have to be defined in AndroidManifest.xml in <application name="YourApplication">. onCreate of application is called before all other components in your application are created (before any Activity or Service).

Categories

Resources