0

I have 2 Activities, SignIn and ChooseLanguage. On choosing a particular language, the language chosen is saved via shared preferences and the application goes to the SignIn activity via Intent. All this is working perfectly fine. There is a loadLocale() method in the ChooseLanguage class which i want to call from the SignIn class. This however gives a null pointer exception. NOTE: The language preference is saved correctly, i have opened it and seen it myself. Where am i going wrong?

In ChooseLanguage Activity:

public void loadLocale(){
        Log.i("TAG","CAME HERE");
        SharedPreferences prefs = getSharedPreferences("LanguageSettings", Activity.MODE_PRIVATE);

        String preferredLanguage = prefs.getString("PreferredLang","");
        setLocale(preferredLanguage);
    }

In SignIn Activity

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ChooseLanguage chooseLanguage = new ChooseLanguage();
        chooseLanguage.loadLocale();
        setContentView(R.layout.sign_in);
        .
        .
        .
}

My Log

2019-06-13 11:58:35.302 10533-10533/com.example.gofresh I/TAG: CAME HERE
2019-06-13 11:58:35.304 10533-10533/com.example.gofresh E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.gofresh, PID: 10533
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.gofresh/com.example.gofresh.SignIn}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3037)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3172)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1906)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6863)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference
        at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:174)
        at com.example.gofresh.ChooseLanguage.loadLocale(ChooseLanguage.java:103)
        at com.example.gofresh.SignIn.onCreate(SignIn.java:64)
        at android.app.Activity.performCreate(Activity.java:7149)
        at android.app.Activity.performCreate(Activity.java:7140)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1288)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3017)

The setLocale() method added here

private void setLocale(String preferredLanguage){
        Locale locale = new Locale(preferredLanguage);
        Locale.setDefault(locale);
        Configuration configuration = new Configuration();
        configuration.locale = locale;
        getBaseContext().getResources().updateConfiguration(configuration, getBaseContext().getResources().getDisplayMetrics());
        if(!preferredLanguage.equals(""))
             onConfigurationChanged(configuration);
        SharedPreferences.Editor editor = getSharedPreferences("LanguageSettings",MODE_PRIVATE).edit();
        editor.putString("PreferredLang",preferredLanguage);
        editor.apply();
    }


@Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        chooseLanguage.setText(R.string.chooseYourLanguage);
        okButton.setText(R.string.ok);
        super.onConfigurationChanged(newConfig);

    }
CS Learner
  • 231
  • 2
  • 11
  • You are calling `getSharedPreferences` on an object that does not exist. Use `context.getSharedPreferences` – christoandrew Jun 13 '19 at 06:43
  • Tried that, created a global variable Context context, tried the above method, it still shows the same error. I don't understand which object doesn't exist. Haven't i defined chooselanguage = new ChooseLanguage(); ? – CS Learner Jun 13 '19 at 06:47
  • You can pass the context as a parameter to the `loadLocale(Context context)` and use `context. getSharedPreferences` and then you can call the method like `loadLocale(getActivity().getApplicationContext())` – christoandrew Jun 13 '19 at 06:52
  • @christoandrew I have edited my question and added my setLocale() method, what changes should i be making in that as if i making that method static too, it gives error for Non Static methods getBasecContext and OnConfigurationchanged cannot be referenced from static context. i tried passing context as a parameter in setLocale(preferredLanguage,context) and made getBaseContext() and context. but cannot understand what to do with onConfigurationChanged method – CS Learner Jun 13 '19 at 07:11

1 Answers1

1

You should never instantiate activities yourself. Leave that to the OS. Or else the Context won't be initialized and thus provoking that NullPointetException. (Context is null, can't get SharedPrefs, then SharedPrefs is null)

Make it a method of the current activity or make it a static method passing along the context like so:

public static void setPreferredLocale(Context ctx) {
    SharedPreferences prefs = ctx.getSharedPreferences("LanguageSettings", Activity.MODE_PRIVATE);
    String preferredLanguage = prefs.getString("PreferredLang","");
    setLocale(preferredLanguage);
}

Then, from any other Activity call it like

ChooseLanguage.setPreferredLocale(this)

Some random IT boy
  • 7,569
  • 2
  • 21
  • 47
  • Tried this, using SharedPreferences.getSharedPreferences(ctx,"LanguageSettings", Activity.MODE_PRIVATE); it gives the error cannot resolve method getSharedPreferences. If i remove the SharedPrefererences prefix, it gives an error Non static method getSharedPreferences cannot be referenced from a static context – CS Learner Jun 13 '19 at 06:55
  • I was editing my answer, check now. Asap I get on my laptop Ill give you the double checked version since im on my phone – Some random IT boy Jun 13 '19 at 06:56
  • I have added my setLocale() method, what changes should i be making in that as if i making that method static too, it gives error for Non Static methods getBasecContext and OnConfigurationchanged cannot be referenced from static context. i tried passing context as a parameter in setLocale(preferredLanguage,context) and made getBaseContext() and context. but cannot understand what to do with onConfigurationChanged method – CS Learner Jun 13 '19 at 07:06
  • The compiler is complaining that you're trying to call non-static methods from inside a static method. There's not much you can do about it with the onConfigurationChanged hook. You can still make the `setLocale` method `static` and it would get rid of the compiler error. – Some random IT boy Jun 13 '19 at 08:10
  • Btw; don't call yourself `onConfigurationChanged` that is something Android handles by itself (hence why you're overriding it) and you should not interefere with that. As soon as the config changes are propagated you'll get that callback in the Activity. – Some random IT boy Jun 13 '19 at 08:12
  • I am calling it beacause as soon as user selects a language, i want to display it on the screen instantaneously without calling recreate() or refreshing the activity. Secondly, what i found about calling onConfigurationChanged from a static method was to use new ChooseLanguage.onConfigurationChanged(configuration). This removes the error over here but on running the application, it gives another null pointer exception, this time for the instance variables inside the onConfigurationChanged overridden method which were instantiased in the onCreate Method and declared globally. Stuck again! – CS Learner Jun 13 '19 at 08:23
  • In that case I think you need to invalidate the inflated layout by the Activity so the visual changes take effect. Regarding the second NullPointerException that makes for another new answer with all it's corresponding information so other people may also be able to help you out. – Some random IT boy Jun 13 '19 at 11:49
  • Theoretically you wouldn't inmediately call the `onConfigChanges`, Android would do that for you. You could really mess up the state of the Activity by calling already implemented methods without really needing to. (super.onConfigurationChanged). The issue is that you're trying to call an `instance` method from a static context which doesn't really belong to any instance but rather the class. So any instances of the ChooseLanguage Activity won't really get updated because you're not referencing any of them to receive any updates. To get around that you could try using a LocalBroadcasts – Some random IT boy Jun 13 '19 at 11:53