Android setContentView(View) throws NullPointerException related to appcompat-7 library

Viewed 429

I've been developing Android apps for a long time and I've faced with many problems which were resolved at the end of day, but in my last project I have a really weird problem which is related to appcompat-7 library I suspect.

A NullPointerException is thrown approximately with 10% frequency when setContentView(View) is called. I mean the exception is not thrown in each execution. There is an indeterministic behaviour.

Being not sure, I think I miss a key point about DecorView of Window.

The exception is thrown at line cfl.setDecorPadding(windowDecor.getPaddingLeft()... in method applyFixedSizeWindow of class AppCompatDelegateImplV9.

I also attached the exception's full stack trace at the end of the question.

I don't think it is relevant but it is useful to say that I use Android Studio 3.0.

All suggestions and comments are welcome.

Activity code:

public class MainActivity extends AppCompatActivity {
...

private static final int HIDE_NAVBAR_DELAY = 500;

private static void hideNavBarAndActionBar(final Window _window) {
    _window.getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LOW_PROFILE);
}

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

    final View view = LayoutInflater.from(this).inflate(R.layout.screen_splash, null, false);
    setContentView(view);

    final Window window = getWindow();

    // to hide bars after volume control popup or similar popup appears and disappers
    window.getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {
            if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                hideNavBarAndActionBar(window);
            }
        }
    });
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    //to hide of bars after activity window is focused (example case: resume activity by bringing ti from background to foreground)
    if(hasFocus) {
        final Window window = getWindow();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                hideNavBarAndActionBar(window);
            }
        }, HIDE_NAVBAR_DELAY);
    }
}
...

}

build.gradle for the module:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    aaptOptions {
        cruncherEnabled = false
    }
}

dependencies {
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.google.android.gms:play-services-ads:11.4.2'
    implementation 'com.google.android.gms:play-services-auth:11.4.2'
}

Stack trace of the exception:

FATAL EXCEPTION: main
  Process: my_package_name:my_process_name, PID: 25792
  java.lang.RuntimeException: Unable to start activity ComponentInfo{my_package_name/my_package_name.MainActivity}: java.lang.NullPointerException
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2200)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
      at android.app.ActivityThread.access$800(ActivityThread.java:139)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:136)
      at android.app.ActivityThread.main(ActivityThread.java:5105)
      at java.lang.reflect.Method.invokeNative(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:515)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
      at dalvik.system.NativeStart.main(Native Method)
   Caused by: java.lang.NullPointerException
      at android.support.v7.app.AppCompatDelegateImplV9.applyFixedSizeWindow(AppCompatDelegateImplV9.java:537)
      at android.support.v7.app.AppCompatDelegateImplV9.ensureSubDecor(AppCompatDelegateImplV9.java:331)
      at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:275)
      at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:144)
      at my_package_name.MainActivity.onCreate(MainActivity.java:68)
      at android.app.Activity.performCreate(Activity.java:5275)
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2164)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250) 
      at android.app.ActivityThread.access$800(ActivityThread.java:139) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1200) 
      at android.os.Handler.dispatchMessage(Handler.java:102) 
      at android.os.Looper.loop(Looper.java:136) 
      at android.app.ActivityThread.main(ActivityThread.java:5105) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:515) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608) 
      at dalvik.system.NativeStart.main(Native Method) 
2 Answers

I have test your code in my android studio 3 it's work fine this my gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.asb.test.testapplication"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

try current appcompat library "compile 'com.android.support:appcompat-v7:27.0.0'" and compileSdkVersion 27, targetSdkVersion 27 and rebuild project . Hope it would help you!

Related