null reference to a Singleton object - android

I am trying to create a global variable where it can be accessed from any any where including Activity, Fragment and other custom classes.
public class Global extends Application {
private static Global sInstance;
private String mSharedInfoFileName; //can be any custom object
public static Global getInstance() { return sInstance; }
#Override
public void onCreate() {
super.onCreate();
sInstance = this;
initialize();
}
private void initialize() { mSharedInfoFileName = "globalInfo"; }
public String getFileName() { return mSharedInfoFileName; }
private Global() { }
}
and try to use it like this
public class MyFragment extends android.support.v4.app.Fragment {
String s = Global.getInstance().getFileName();
}
even after declaring it in class scope still gave same error
private static Global mGlobal = Global.getInstance();
which give me Attempt to invoice... .Global.getFileName()' on a null object reference. What am I missing?
Thank you

Change this method to static :
public static String getFileName() {
return mSharedInfoFileName;
}
and call it like below:
Global.getFileName();
The mSharedInfoFileName variable has to be static too :
private static String mSharedInfoFileName;

Related

Java.lang.NullPointerException in JUnit test with class App.getContext().getString

I'm trying to test a method that is in a static context in my class and I want to test it in Junit class but I got a null pointer exception.
My App class :
public class App extends MultiDexApplication {
private static Context mContext;
#Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getContext() {
return mContext;
}
}
My Method :
public class ColleagueChoice {
static ColleagueApiService apiService = DI.getColleagueApiService();
static List<Colleague> colleagueList = apiService.getColleagues();
static String isEatingAt = App.getContext().getResources().getString(R.string.is_eating_at);
static String isJoining = App.getContext().getResources().getString(R.string.is_joining);
static String notDecided = App.getContext().getString(R.string.has_not_decided_yet);
public static List<Colleague> setScarlettAndHughChoice() {
Colleague scarlett = colleagueList.get(0);
Colleague hugh = colleagueList.get(1);
scarlett.setColleagueIsJoining(isJoining);
hugh.setColleagueIsJoining(isJoining);
List<Colleague> colleagueChoiceList = new ArrayList<>();
colleagueChoiceList.add(scarlett);
colleagueChoiceList.add(hugh);
return colleagueChoiceList;
}
So I'm getting this error at line :
static String isEatingAt = App.getContext().getResources().getString(R.string.is_eating_at);
UP!
Simply remove the App class because this is not very good to put getString in a logic code like services. I just add an enum to my model Colleague and then use: holder.itemView.getContext().getString()
in my adapter with a switch condition.

Attempt to invoke virtual method on a null object reference - Global Variables Class

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~

Android Thread Synchronization - synchronized keyword doesn't work?

I'm using a singleton class SingletonA for my resources and I have a service ServiceS who uses the resources.
public class SingletonA {
private static SingletonA ourInstance = new SingletonA();
public static SingletonA getInstance() { return ourInstance; }
private SingletonA () {}
String resources;
synchronized public void importSomething() {
resources = "I have some value now";
}
}
public class ServiceS extends Handler {
private static ServiceS ourInstance = new ServiceS();
public static ServiceS getInstance() { return ourInstance; }
private ServiceS () {}
SingletonA sa = SingletonA.getInstance();
public void printResources() {
println(sa.resources);
}
}
public class MyActivity extends Activity {
SingletonA sa = SingletonA.getInstance();
#override
protected void onCreateBundle savedInstanceState) {
super.onCreate(savedInstanceState);
sa.importSomthing();
ServiceS.printResources();
}
}
-> In ServicesS class, sa value is null -> sa.printResources() causes NPE
However, since I add one more sa = SingletonA.getInstance(); into ServiceS.printResources() like this:
public void printResources() {
sa = SingletonA.getInstance();
println(sa);
}
-> It worked: sa != null and resources = "I have some value now".
Can someone explain for me why sa in ServiceS still null ? Thanks,
As the comment of Buddy:
it's due to static initialization order. The static ServiceS.ourService is initialized before SingletonA.ourInstance.
See here for more information on static initialization order. But the easy solution would be to just call SingletonA.getInstance() when necessary (vs caching in a member variable). Or to lazily initialize ServiceS.ourInstance inside getInstance

The static reference of My Android Launcher Activity become null

In my Android Application, I store the Launcher activity (called MainActivity) in a static variable inside the MainActivity class;
And I am using this static Activity reference to get the application resource, preference and others;
But sometimes, I found that the app is crashed because the object reference is null;
Is there any reason causing the object reference become NULL?
How to prevent this kind of NullPointerException?
My Codes:
MainActivity:
public class MainActivity extends Activity {
private static MainActivity sInstance = null;
public static MainActivity getInstance() {
return sInstance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sInstance = this;
// other code
}
}
Helper.java:
public static int getColor(int resID) {
return MainActivity.getInstance().getColor(resID);
}
//For this type of issue, please use application class object. If you used Activity class then when //activity destroys then it will become null. So you got the null pointer exception.
public class MyApplication extends Application {
public static MyApplication myApplication = null;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
myApplication = (MyApplication) getApplicationContext();
}
public static MyApplication getInstance() {
return myApplication;
}
}
//Your method looks like this
public static int getColor(int resID) {
return MyApplication.getInstance().getResources().getColor(resID);
}

sending string value from classes extending BaseAdapter to Overlay

i am writing a code where i get a string value in a class that extends BaseAdapter. I want this value to be used in another class that extends an Overlay. If my class extends an Activity i can use intent,putstring() and getString, but is to be used for these above specified classes..Can anyone tell me how can i do this. Thanks in advance.
You can either make your variable global or make a singleton FileHelper class that contains values you want to pass between classes.
MyClass:
public String myString = "Hello";
and if you want to use it in
OtherClass:
String myString = MyClass.myString;
If your the FileHelper use this:
public class FileHelper {
private static FileHelper instance;
private String myString;
private FileHelper() {
}
public static FileHelper getInstance() {
if (instance == null) {
instance = new FileHelper();
}
return instance;
}
public void setMyString(String s){
myString = s;
}
public String getMyString(){
return myString();
}
}
You can use the FileHelper with this:
private static FileHelper fileHelper = FileHelper.getInstance();
fileHelper.setString("hello");
String myString = fileHelper.getMyString();

Categories

Resources