Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different Application class per build variant crashes on some devices

I've modified my build.gradle to use different Application classes based on build-variant (debug / release).

I've added two WrapperApplication classes one in folder "debug", and the second in folder "release", both classes extend some base Application class.

In AndroidManifest I point to com.my.package.WrapperApplication and it indeed uses the correct one. When releasing a test apk to Play, I got a pre-launch report that my new version crashed on 2 of the 13 devices tested (Moto G and Moto X).

Would love to know why is it crashing, and if something is wrong in the build, how is it working for me and for the other 11 test devices tested.

Here's the stack I received:

 FATAL EXCEPTION: main
 Process: com.my.package, PID: 16348
 java.lang.RuntimeException: Unable to instantiate application com.my.package.WrapperApplication: java.lang.IllegalStateException: Unable to get package info for com.my.package; is package not installed?
    at android.app.LoadedApk.makeApplication(LoadedApk.java:516)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4398)
    at android.app.ActivityThread.access$1500(ActivityThread.java:139)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1270)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5102)
    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:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.IllegalStateException: Unable to get package info for com.my.package; is package not installed?
    at android.app.LoadedApk.initializeJavaContextClassLoader(LoadedApk.java:376)
    at android.app.LoadedApk.getClassLoader(LoadedApk.java:329)
    at android.app.LoadedApk.makeApplication(LoadedApk.java:508)
    ... 11 more

Thanks.

EDIT:

Previously we used the following method, but using the variant-specific folders is cleaner for our build system, so we'd love to switch to it.

Previous method:

AndroidManifest:

<application
    android:name="${application}"
    ... />

build.gradle:

debug {
    manifestPlaceholders = [application:".Application1"]
}
release {
    manifestPlaceholders = [application: ".Application2"]
}
like image 961
marmor Avatar asked May 30 '16 13:05

marmor


1 Answers

I don't know what is the reason for the issues. But we are doing a different approach:

  1. We have base Application with common functionality and it also contains protected methods for future behaviour modification:

    public class MyApp extends application {
        public void onCreate() {
            super.onCreate();
            initLogging();
        }
    
        protected void initLogging() {}
    }
    
  2. We create another app in flavour or build configuration source folder and override behaviour:

    public class DebugMyApp extends MyApp {
        @Override
        protected void initLogging() {
            //init Stetho
        }
    }
    
  3. We also create another AndroidManifest.xml in flavour or build configuration source folder where we override application name:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
        package="com.philips.pins.ugrow"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    ​
        <application
            android:name=".DebugMyApp"
            android:label="@string/app_name"
            tools:replace="android:name,android:label">
    
            <activity android:name="net.hockeyapp.android.UpdateActivity"/>
        </application>        ​
    </manifest>
    

Sure extension of the app is not necessary and you can define two different app classes but just correctly define them in manifest files.

like image 59
Eugen Martynov Avatar answered Sep 30 '22 15:09

Eugen Martynov