0
votes

I just wrote a simple Android app with a LinearLayout only. I use this LinearLayout as property of class and as a local object of method (for example in onCreate method).

First case: LinearLayout as a property

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    LinearLayout root = new LinearLayout(getApplicationContext());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(root);
    }
}

Second case: LinearLayout as a object of method

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout root = new LinearLayout(getApplicationContext());
        setContentView(root);
    }
}

In both cases, there is no error. However, when I run on simulator or device, the first case ran to error as below. Why? I think this issue is caused by getApplicationContext method. The context of this method hasn't initialized yet until the onCreate method is called. Is this true?

enter image description here

E/AndroidRuntime: FATAL EXCEPTION: main Process: localglobal, PID: 6701 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{localglobal/localglobal.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) at android.app.ActivityThread.access$800(ActivityThread.java:144) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5221) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:105) at localglobal.MainActivity.(MainActivity.java:9) at java.lang.reflect.Constructor.newInstance(Native Method) at java.lang.Class.newInstance(Class.java:1572) at android.app.Instrumentation.newActivity(Instrumentation.java:1065) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)  at android.app.ActivityThread.access$800(ActivityThread.java:144)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:135)  at android.app.ActivityThread.main(ActivityThread.java:5221)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

1
post stack trace hereAbdul Kawee
I think this issue is caused by getApplicationContext method. The context of this method hasn't initialized yet until the onCreate method is called. Is this true? yes it is trueEpicPandaForce
Did you try setting layout params for LinearLayout? Also use MainActivity.this instead of getApplicationContext() and try.Ümañg ßürmån

1 Answers

0
votes

When a Context object is first initialized, it isn't ready to be used as a Context yet, and most of its methods will return null. The Activity class is an extension of the Context class, so it follows the same rules.

When you have:

LinearLayout root = new LinearLayout(getApplicationContext());

as a global variable, Java will attempt to initialize your LinearLayout while your MainActivity is initializing, before the Context has been attached or prepared. getApplicationContext() is likely returning null, although even passing this would cause errors, since Views use the Context during initialization to call getResources(), which will also be null at that point.

That's why Android provides the onCreate() method. This method is only called once the Context has been attached and is ready for use.

If you want a global LinearLayout variable, do this:

public class MainActivity extends AppCompatActivity {
    private LinearLayout root;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        root = new LinearLayout(this);
        setContentView(root);
    }
}

However, this isn't the way Android is meant to really work. Instead, you should create a layout XML (under /res/layouts/, Android Studio should have done this for you anyway), where you define your layout in XML, and give your Views ids. Then in your Activity:

public class MainActivity extends AppCompatActivity {
    private LinearLayout root;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.your_layout_name);
        root = findViewById(R.id.whatever_id_you_gave_your_linearlayout_in_xml);
    }
}

Your layout XML might look something like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/whatever_id_you_gave_your_linearlayout_in_xml"
    android:orientation="vertical">

    <TextView
        android:id="@+id/some_other_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
     />

     <Button
        android:id="@+id/a_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
     />

</LinearLayout>