From several classes in my app I want to get String global values without using Context.
If I declare this variables in Application class, SharedPreferences or Strings.xml, then I must use Context for get/set it values.
Using Singleton is not a good practice as I understand from this post.
Is there any good way for using global variables without using context?
Create a global class or store the string in a place that "makes sense". For instance if you have the class Shoes you could do this:
public class Shoes {
public static class BRAND {
public static final String NIKE = "nike";
public static final String REBOK = "rebok";
public static final String ADDIDAS = "addidas";
}
private String brand;
public Shoes() {}
public void setBrand(String brand) {
this.brand = brand;
}
public String getBrand() {
return this.brand;
}
}
Now you can do this:
public static void main(String[] args) {
Shoes myShoes = new Shoes();
myShoes.setBrand(Shoes.BRAND.NIKE);
}
You will find there are many things like this in Android. It would be even better if you used enums instead. Hope this helps.
UPDATE
If you would like to use setters and getters then there are 2 solutions:
The first you would need an instance of the object and since you only want a single instance a singleton design pattern would be required. Really if you synchronize correctly and the design makes sense they can be very good and useful. In your situation I don't think it would be worth the work.
You can take advantage of the static initializer and static methods. You could just remove the final declaration and do what you want with the Strings, like this:
public class Shoes {
public static class BRAND {
public static String NIKE;
public static String REBOK;
public static String ADDIDAS;
static {
NIKE = "nike";
REBOK = "rebok";
ADDIDAS = "addidas";
}
}
private String brand;
public Shoes() {}
public void setBrand(String brand) {
this.brand = brand;
}
public String getBrand() {
return this.brand;
}
}
Or use good encapsulation practices and do this:
public class Shoes {
public static class BRAND {
private static String NIKE;
private static String REBOK;
private static String ADDIDAS;
static {
NIKE = "nike";
REBOK = "rebok";
ADDIDAS = "addidas";
}
public static String getNIKE() {
return NIKE;
}
public static void setNIKE(String name) {
NIKE = name;
}
public static String getREBOK() {
return REBOK;
}
public static void setREBOK(String name) {
REBOK = name;
}
public static String getADDIDAS() {
return ADDIDAS;
}
public static void setADDIDAS(String name) {
ADDIDAS = name;
}
}
private String brand;
public Shoes() {}
public void setBrand(String brand) {
this.brand = brand;
}
public String getBrand() {
return this.brand;
}
}
However I must note: If you are doing this because you cannot get a Context then you are missing something. A context can be obtained from anywhere - objects instantiated by the system are given a context as a parameter. If you have your own custom object you can just pass the ApplicationContext as a parameter or the class using the object itself (this).
Store the values in your strings.xml file. Then call it like this.
String yourString = Context.getResources().getString(R.string.your_string);
Related
I have a stringDef/ TypeDef class as follows
public class Codes {
public static final String Code_1 = "Code1";
public static final String Code_2 = "Code2";
public static final String Code_3 = "Code3";
#Retention(RetentionPolicy.SOURCE) #StringDef({
Code_1, Code_2, Code_3 })
public #interface CodesMessageDef {
}
}
I would like to set values of Code_1,2,3 from R.String.code_1 rather than manually entering.
Is there any way to achieve this usecase.
Thanks in advance.........
You can read this answer for how to get application context from a static method. Note that using this to get the context is not a memory leak because you are using an application context.
Now you can do:
public static final String Code_1 = MyApplication.getAppContext().getString(R.id.code1);
public static final String Code_2 = MyApplication.getAppContext().getString(R.id.code2);
public static final String Code_3 = MyApplication.getAppContext().getString(R.id.code3);
I guess it should work.
I'm learning about MVC. My project has tons of variables. So I made a new class for them called MainVariables.
public class MainVariables {
private String mPictureDirectory;
private String mNameOfThePictureFile;
private String mFullPathPicture;
private double mLongitude;
private double mLatitude;
private String mAddress;
private String mCity;
private String mState;
private String mCountry;
private String mPostalCode;
private String mKnownName;
private String mDescription;
private String mSolicitationType;
...
...
The rest is composed by automatic getters and setters for each variable.
I'm having a problem accessing and casting those variables across my application.
I tried accessing it by casting the following in other files:
private MainVariables mMainVariables;
The above code throws the error Attempt to invoke virtual method on a null object reference
Then I tried the following:
private MainVariables mMainVariables = new MainVariables();
Now, this does work. Only in the file it's using though. For Example, I set variables from within the "SolicitationFragment" and when I try to access it on "PostFragment", I get an empty result.
That's because I'm having to initialize MainVariables on each file.
How can I get around this and be able to access my variables globally?
Make the variables static, or final if you're not going to change them. This way you don't have to create a new instance and can call MainVariables.mPictureDirectory immediately
public class MainVariables {
public static String mPictureDirectory;
}
Another option is a singleton pattern, this way you create only one instance of an object and still can use getters and setters
public class MainVariables {
private static MainVariables mInstance = null;
private String mString;
private MainVariables(){
mString = "Hello";
}
public static MainVariables getInstance(){
if(mInstance == null)
{
synchronized (MainVariables.class) {
if (mInstance== null) {
mInstance= new MainVariables();
}
}
return mInstance;
}
public String getString(){
return this.mString;
}
public void setString(String value){
mString = value;
}
}
In your MainActivity you can declare a field
MainVariables mainVariables = MainVariables.getInstance()
and call
mainVariables.[METHOD] from basically anywhere in your MainActivity
Create a class extending your Application class and create a method to get instance of MainVariables:
AppController.java
public class AppController extends Application {
private MainVariables mMainVariables;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public MainVariables getMainVariables() {
if (mMainVariables == null) {
mMainVariables = new MainVariables();
}
return mMainVariables;
}
}
MainVariables.java
public class MainVariables {
private String string;
public String getString(){
return this.string;
}
public void setString(String string){
this.string = string;
}
}
USE:
// SET VALUE
AppController.getInstance().getMainVariables().setString("Hello Android");
// GET VALUE
String str = AppController.getInstance().getMainVariables().getString();
FYI, You have to add AppController class under application name in your AndroidManifest.xml file.
<application
android:name=".AppController">
</application>
Hope this will help~
I need to start an activity from 2 different screens that have two different models but, both models have some shared information which is the one that I need in the new activity. The problem is that I cannot make those models to extend from the same parent, as one of the models already extends one parent. I have thought about creating an interface that contains the shared methods but, if I do that, then how can I put that interface in the bundle required to start the next activity?
I add some simplified code in order to clarify my situation:
public class A extends Model implements CustomInterface {
String name;
String address;
public String getName(){
return name;
}
public String getAddress() {
return address;
}
}
public class B implements CustomInterface {
String name;
public String getName() {
return name;
}
}
public interface CustomInterface {
String getName();
}
My problem is that I need to start an activity with a bundle with the shared information between both models. So, I would like to put CustomInterface in a bundle. How could I do that?
Thanks in advance.
So, I would like to put CustomInterface in a bundle
you could let CustomInterface extend Parcelable. E.g.
public interface CustomInterface extends Parcelable {
String getName();
}
this way the classes implementing CustomInterface will have to implements the method defined in the Parcelable interface. If implemented correctly, you will be able to pass those objects around without problems
Create a singleton class, then you can share data without passing it:
public class MySingleton
{
private static MySingleton instance;
public String customVar;
public static MySingleton getInstance()
{
if (instance == null)
{
// Create the instance
instance = new MySingleton();
}
// Return the instance
return instance;
}
private MySingleton()
{
// Constructor hidden because this is a singleton
}
public void getSomeData()
{
return something;
}
public void getSomeOtherData()
{
return somethingelse;
}
}
Then in your classes:
public class A extends Model {
String name;
String address;
public String getName(){
return name;
}
public String getAddress() {
return address;
}
public String doSomethingWithSharedData(){
MySingleton model = MySingleton.getInstance();
String somedata = model.getSomeData();
}
}
public class B {
String name;
public String getName() {
return name;
}
public String doSomethingDifferentWithSharedData(){
MySingleton model = MySingleton.getInstance();
String somedata = model.getSomeOtherData();
}
}
i have the following class which i intent to pass from one activity to another:
public class Ad extends ListItem implements parcelable{
private String _type;
private String _recordID;
private String _line1;
private String _line2;
private String _line3;
private String _line4;
private String _url;
private IOnUiNeedToUpdateListener _listener;
private boolean _notActive = false;
private String _alertText;
private Double _longitude;
private Double _latitude;
}
i want to pass an array of such objects from one activity to another. however, i do not need to pass all fields.
is it possible to create a parcel only from the desired fields and send it?
It's your code that writes to Parcel and your code that reads from Parcel. So basically yes. You can write whatever you want. Content of all members, content of some, no members, but other values you use to restore state of the object etc, etc.
Try design your class like this..
public class Form implements Parcelable {
private String formdata1;
private String formdata2;
private String formdata3;
private String formdata4;
public Form() {
}
public Form(Parcel in) {
setFormdata1(in.readString());
setFormdata2(in.readString());
setFormdata3(in.readString());
setFormdata4(in.readString());
}
public String getFormdata1() {
return formdata1;
}
public void setFormdata1(String formdata1) {
this.formdata1 = formdata1;
}
public String getFormdata2() {
return formdata2;
}
public void setFormdata2(String formdata2) {
this.formdata2 = formdata2;
}
public String getFormdata3() {
return formdata3;
}
public void setFormdata3(String formdata3) {
this.formdata3 = formdata3;
}
public String getFormdata4() {
return formdata4;
}
public void setFormdata4(String formdata4) {
this.formdata4 = formdata4;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel in, int arg1) {
in.writeString(getFormdata1());
in.writeString(getFormdata2());
in.writeString(getFormdata3());
in.writeString(getFormdata4());
}
public static final Parcelable.Creator<Form> CREATOR = new Parcelable.Creator<Form>() {
#Override
public Form createFromParcel(Parcel in) {
return new Form(in);
}
#Override
public Form[] newArray(int size) {
return new Form[size];
}
};
}
I am setting global variables in a class which extends from Application. Just getting confused with the basics. The the following code is working but is it a right way to do it ?
public class GlobalMV extends Application{
private static final String TAG = "Global";
private String userid, pwd, name, station;
#Override public void onCreate ()
{
Thread.setDefaultUncaughtExceptionHandler(
new UncaughtExceptionHandler(){
#Override
public void uncaughtException(Thread arg0, Throwable arg1) {
Functions.CustomToastLong(getApplicationContext(), arg0.toString() + arg1.toString());
}
}
);
super.onCreate();
}
public GlobalMV(){
userid ="000000";
pwd="";
}
Is onCreate() and constructor both can be there ?
looks fine, you can also write:
private String userid="000000";
private String pwd;
private String name;
private String station;
ale remove c-tor