Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proguard shrinking causes Null Pointer Exception

There is a video activity in my android app. In debug build when proguard is disabled all works like a charm. But in release build when proguard is enabled and the video activity starts I get a NPE.

Part of my gradle file:

buildTypes {
    debug {
        applicationIdSuffix '.dev'
        versionNameSuffix '-dev'
        minifyEnabled false
        shrinkResources false
    }
    release {
        minifyEnabled true
        shrinkResources true
        debuggable false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}

Exception:

java.lang.RuntimeException: Unable to start activity ComponentInfo{ua.com.tv24.news/ua.com.tv24.news.ui.activities.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
        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 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
        at ua.com.tv24.news.ui.fragments.a.b.a(Unknown Source)
        at android.support.v4.app.Fragment.i(Unknown Source)
        at android.support.v4.app.u.a(Unknown Source)
        at android.support.v4.app.u.a(Unknown Source)
        at android.support.v4.app.u.a(Unknown Source)
        at android.support.v4.app.u.j(Unknown Source)
        at android.support.v4.app.p.onCreate(Unknown Source)
        at android.support.v7.app.ActionBarActivity.onCreate(Unknown Source)
        at ua.com.tv24.news.ui.activities.a.onCreate(Unknown Source)
        at ua.com.tv24.news.ui.activities.b.onCreate(Unknown Source)
        at ua.com.tv24.news.ui.activities.MainActivity.onCreate(Unknown Source)
        at android.app.Activity.performCreate(Activity.java:5933)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
            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)

And my Activity:

 package ua.com.tv24.news.ui.activities;

import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.FrameLayout;

import com.google.android.libraries.mediaframework.exoplayerextensions.Video;
import com.google.android.libraries.mediaframework.layeredvideo.PlaybackControlLayer;
import com.google.googlemediaframework.adplayer.ImaPlayer;

import de.greenrobot.event.EventBus;
import ua.com.tv24.news.R;
import ua.com.tv24.news.events.ui.VideoPreparedEvent;

public class DashVideoActivity extends ActionBarActivity implements PlaybackControlLayer.FullscreenCallback {
    private ImaPlayer imaPlayer;
    private FrameLayout videoPlayerContainer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);

        setContentView(R.layout.activity_dash_video);
        videoPlayerContainer = (FrameLayout) findViewById(R.id.video_frame);

        Bundle bundle = getIntent().getExtras();
        String videoUrl = bundle.getString(VideoActivity.VIDEO_URL_EXTRA);
        String appName = getString(R.string.app_name);

        //TODO get url and name from extras
        VideoItem video = new VideoItem(appName, new Video(videoUrl, Video.VideoType.DASH, ""),
                null);

        createImaPlayer(video);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (imaPlayer != null) {
            imaPlayer.play();
        }
    }

    @Override
    protected void onPause() {
        if (imaPlayer != null) {
            imaPlayer.pause();
        }
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        if (imaPlayer != null) {
            imaPlayer.release();
        }
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    public void createImaPlayer(VideoItem videoListItem) {
        if (imaPlayer != null) {
            imaPlayer.release();
        }

        // If there was previously a video player in the container, remove it.
        videoPlayerContainer.removeAllViews();

        String adTagUrl = videoListItem.adUrl;
        String videoTitle = videoListItem.title;

        imaPlayer = new ImaPlayer(this,
                videoPlayerContainer,
                videoListItem.video,
                videoTitle,
                adTagUrl);
        imaPlayer.setFullscreenCallback(this);

        Resources res = getResources();

        Drawable logo = res.getDrawable(R.drawable.launcher);
        imaPlayer.setLogoImage(logo);

        imaPlayer.play();
    }

    @Override
    public void onGoToFullscreen() {
    }

    @Override
    public void onReturnFromFullscreen() {
    }

    public static class VideoItem implements Parcelable {

        /**
         * The title of the video.
         */
        public final String title;

        /**
         * The actual content video (contains its URL, media type - either DASH or mp4,
         * and an optional media type).
         */
        public final Video video;

        /**
         * The URL of the VAST document which represents the ad.
         */
        public final String adUrl;

        /**
         * @param title The title of the video.
         * @param video The actual content video (contains its URL, media type - either DASH or mp4,
         *              and an optional media type).
         * @param adUrl The URL of the VAST document which represents the ad.
         */
        public VideoItem(String title, Video video, String adUrl) {
            this.title = title;
            this.video = video;
            this.adUrl = adUrl;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {

        }
    }

    public void onEventMainThread(VideoPreparedEvent event) {
        View progress = findViewById(R.id.videoLoaderBar);
        if (progress != null) {
            progress.setVisibility(View.INVISIBLE);
        }
    }
}

Also my proguard rules:

-dontwarn com.google.android.gms.**

# Picasso 
-dontwarn com.squareup.okhttp.**

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
    public static final ** CREATOR;
}

#okhttp
-keepnames class com.levelup.http.okhttp.** { *; }
-keepnames interface com.levelup.http.okhttp.** { *; }
-keepnames class com.squareup.okhttp.** { *; }
-keepnames interface com.squareup.okhttp.** { *; }

-dontwarn com.squareup.okhttp.internal.http.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

#retrofit
-keepattributes Signature
-keepattributes *Annotation*

-keep class com.google.gson.** { *; }
-keep class com.google.inject.** { *; }
-keep class org.apache.http.* { *; }
-keep class org.apache.james.mime4j.* { *; }
-keep class javax.inject.** { *; }
-dontwarn rx.*
-keep class com.example.testobfuscation.** { *; }
-keepattributes Signature
-keep class sun.misc.Unsafe { *; }

-keep class retrofit.** { *; }
-keep interface retrofit.** { *; }
-keepclasseswithmembers class * {
    @retrofit.http.* <methods>;
}
-keepclasseswithmembers class * {
    @ua.* <methods>;
}

-dontwarn retrofit.appengine.**

-keep class ua.com.tv24.news.models.** { *; }
-keepattributes InnerClasses

#xml parser
-keep interface org.simpleframework.xml.** { *; }
-keep class org.simpleframework.xml.** { *; }

#eventBus
-keepclassmembers class ** {
    public void onEvent(**);
}
-keepclassmembers class ** {
    public void onEventMainThread(**);
}

#support v7
-keep class android.support.v7.** { *; }

#unusage classes
-dontwarn retrofit.appengine.UrlFetchClient
-dontwarn retrofit.RxSupport$1
-dontwarn com.google.ads.a.a
-dontwarn com.google.ads.a.c
-dontwarn com.google.ads.a.d
-dontwarn com.google.ads.a.f
-dontwarn com.google.android.exoplayer.hls.HlsMediaPlaylistParser
-dontwarn okio.DeflaterSink
-dontwarn org.simpleframework.xml.stream.StreamProvider
-dontwarn okio.Okio
-dontwarn org.simpleframework.xml.stream.StreamReader
-dontwarn org.simpleframework.xml.stream.StreamReader$Entry
-dontwarn org.simpleframework.xml.stream.StreamReader$Start
-dontwarn org.simpleframework.xml.stream.StreamReader$Text
-dontwarn retrofit.RestMethodInfo$RxSupport
-dontwarn retrofit.RxSupport
-dontwarn retrofit.RxSupport$2
like image 453
Ihor DIM Avatar asked Apr 16 '15 06:04

Ihor DIM


People also ask

How do I fix null pointer exceptions?

NullPointerException is thrown when a reference variable is accessed (or de-referenced) and is not pointing to any object. This error can be resolved by using a try-catch block or an if-else condition to check if a reference variable is null before dereferencing it.

What is ProGuard obfuscation?

You can obfuscate Android code to provide security against reverse engineering. You can use the Android ProGuard tool to obfuscate, shrink, and optimize your code. Obfuscated code can be more difficult for other people to reverse engineer.

What is ProGuard Android optimize txt?

Proguard is a tool which shrinks, optimizes, and obfuscates code. It detects and removes unused classes, fields, methods and attributes from APK. It optimizes bytecode and removes unused instructions.

What is ProGuard optimization?

ProGuard is an open source command-line tool that shrinks, optimizes and obfuscates Java code. It is able to optimize bytecode as well as detect and remove unused instructions.


1 Answers

Taker care that you excluded classes and methods from ProGuard processing:

# Hide warnings about references to newer platforms in the library
-dontwarn android.support.v7.**
# don't process support library
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }

The error occurs usually, if Reflection is involved because Proguard can't resolve the dependencies in this case.

I just see you missed the interfaces in your ProGuard file (as per exception):

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ...
like image 171
Trinimon Avatar answered Oct 13 '22 20:10

Trinimon