Search code examples
androidstringandroid-activity

Android - referencing a string in strings.xml in a .java file


i have this code in MainActivity.java:

String passName = new String(getString(R.string.name)); 

where name is a string in strings.xml:

<string name="name">My name</string>

it does not give me an error, but the app keeps crashing, how can i do this properly?

basically i want to save my name as a string variable in MainActivity.java, but store the actual text in strings.xml

i originally had:

String passName = new String("my name");

and i was able to successfully pass it to the second activity, but i want the text to be stored in strings.xml, not the .java file

edit: i have provided more of my code for context:

public class MainActivity extends AppCompatActivity {

    Button button;
    //code that will eventually point to my name in strings.xml
    String passName = new String("my name");

    //String passName = getResources().getString(R.string.name);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //code that senses when the button is clicked
        button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
            //code that executes when the button is clicked

                Toast.makeText(getApplicationContext(),"Moving to second activity...",Toast.LENGTH_SHORT).show();
                
                //code that passes my name to the second activity
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                intent.putExtra("key", passName);
                startActivity(intent);
            }

        });

    }

}

as for a crash log, there doesn't seem to be one. when i launch the app it opens and then immediately closes again.

the message it gives me is this:

01/19 15:21:11: Launching 'app' on Pixel 4 XL API 30 (test).
Install successfully finished in 388 ms.
$ adb shell am start -n "my.name.n0000.lab_n0000/my.name.n0000.lab_n0000.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER

edit: i have added the proper logcat dialogue:

2023-01-19 15:32:41.587 7562-7562/my.name.n00000.lab_n00000 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: my.name.n00000.lab_n00000, PID: 7562
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{my.name.n00000.lab_n00000/my.name.n00000.lab_n00000.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3365)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
        at android.content.ContextWrapper.getResources(ContextWrapper.java:97)
        at android.view.ContextThemeWrapper.getResourcesInternal(ContextThemeWrapper.java:134)
        at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:128)
        at androidx.appcompat.app.AppCompatActivity.getResources(AppCompatActivity.java:612)
        at my.name.n00000.lab_n00000.MainActivity.<init>(MainActivity.java:17)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 
2023-01-19 15:32:41.615 7562-7562/my.name.n00000.lab_n00000 I/Process: Sending signal. PID: 7562 SIG: 9

Solution

  • There is a lifecycle involved when creating activities. Some things should not be accessed before the onCreate method is called. So you should be able to declare passName prior and then inside onCreate, you can initialise it.

    public class MainActivity extends AppCompatActivity {
    
        Button button;
        String passName;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //code that senses when the button is clicked
            button = findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                //code that executes when the button is clicked
    
                    Toast.makeText(getApplicationContext(),"Moving to second activity...",Toast.LENGTH_SHORT).show();
                    
                    //code that passes my name to the second activity
                    Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                    intent.putExtra("key", passName);
                    startActivity(intent);
                }
    
            });
            passName = getResources().getString(R.string.name);
    
        }
    
    }
    

    You can read more about the activity lifecycle here

    And in particular in this paragraph, it talks about instantiating class scope variables.

    For example, your implementation of onCreate() might bind data to lists, associate the activity with a ViewModel, and instantiate some class-scope variables.