Different Application class per build variant crashes on some devices - android

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"]
}

I don't know what is the reason for the issues. But we are doing a different approach:
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() {}
}
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
}
}
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.

Related

Android application with camera2 library crash on start for SDK19

I use androidx.camera.camera2 library in my application. This library for SDK 21 and greater. But i want allow users start application for SDK 19 without camera2 support. I check SDK version in my code, but application crash on start. Can i exclude camera2 from dependencies for old SDK?
05-30 12:13:42.318 2000-2000/com.myapp.android E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.android, PID: 2000
java.lang.NoClassDefFoundError: android.util.Size
at androidx.camera.camera2.impl.Camera2DeviceSurfaceManager.<clinit>(Camera2DeviceSurfaceManager.java:53)
at androidx.camera.camera2.Camera2AppConfig.create(Camera2AppConfig.java:58)
at androidx.camera.camera2.impl.Camera2Initializer.onCreate(Camera2Initializer.java:44)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1591)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1562)
at android.app.ActivityThread.installProvider(ActivityThread.java:4790)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4385)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4325)
at android.app.ActivityThread.access$1500(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
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:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
I recently stumbled into the same issue.
Diving deep into the CameraX code I found that CameraX is initialized in app startup through a content provider. Here is the content provider code where CameraX is being initialized.
public final class Camera2Initializer extends ContentProvider {
private static final String TAG = "Camera2Initializer";
#Override
public boolean onCreate() {
Log.d(TAG, "CameraX initializing with Camera2 ...");
CameraX.init(getContext(), Camera2AppConfig.create(getContext()));
return false;
}
}
Im not very familiar with content providers but my first taught was, this is add at the manifest level? And indeed I was right.
Looking at there manifest I found this
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="androidx.camera.camera2">
<application>
<provider
android:name=".Camera2Initializer"
android:authorities="${applicationId}.camerax-init"
android:exported="false"
android:initOrder="100"
android:multiprocess="true" />
</application>
</manifest>
There manifest gets merged into ours which will include this content provider which in the other hand initializes CameraX, we want to avoid this. So one possible way of doing so is creating our own empty content provider and adding it to our manifest with the same name. This will override there content provider.
You can look into
https://developer.android.com/studio/build/manifest-merge
for more detail about manifest merging.
So now with there content provider overriden hopefully you can call
CameraX.init(getContext(), Camera2AppConfig.create(getContext()));
only when the feature gets called and not on app startup.
Im hoping this gets fixed in later versions and allows us to initialize cameraX when we want to.

Rare Android Unable to Instantiate Application Exception

I'm seeing the following exception under Crashes in the dev console from time to time.
Whats puzzling about it is that google maps shows up in the call stack as if its calling or creating my app class - very confusing. Whats further weird is the "MyApp-2.apk" in the call stack - where it appends the "-2".
I do include the android.maps.jar file in the libs.
I would like to know how to recreate this if possible and how to prevent this from happening?
java.lang.RuntimeException: Unable to instantiate application com.MyApp.MyCustomApp:
java.lang.ClassNotFoundException: Didn't find class "com.MyApp.MyCustomApp"
on path: /system/framework/com.google.android.maps.jar:/data/app/com.MyApp-2.apk
at android.app.LoadedApk.makeApplication(LoadedApk.java:503)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4405)
at android.app.ActivityThread.access$1400(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1327)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5059)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.MyApp.MyCustomApp" on path: /system/framework/com.google.android.maps.jar:/data/app/com.MyApp-2.apk
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
at android.app.Instrumentation.newApplication(Instrumentation.java:967)
at android.app.LoadedApk.makeApplication(LoadedApk.java:498)
... 11 more
Manifest Application Tag:
<application
android:name=".MyApp"
android:hardwareAccelerated="true"
android:icon="#drawable/app_icon"
android:label="#string/app_name"
android:theme="#style/AppBaseTheme" >
I'm using these JARS: android-support-v4-r2-googlemaps.jar + android-support-v4.jar
The prime reason why a Class within your application would be present on your test devices but missing at runtime on some others would be if your class has a dependency on some external feature which is missing on those devices. For example, if you used some Google API which is not part of AOSP and so missing on a plain AOSP build, or a vendor build which does not license these, then your class will be pruned at install time as its dependencies cannot be resolved.
A common reason for your app finding its way into such circumstances might be someone running an inconsistently assembled "custom ROM" on their device.

The application crashes when using a class inherited from com.activeandroid.app.Application

I use my library Projects ActiveAndroid for which you want to create a class:
import com.activeandroid.app.Application;
public class App extends Application {
#Override
public void onCreate()
{
super.onCreate();
}
}
on the emulator everything works fine, the data stored in the database and so on. but when you start the phone, the application crashes. and immediately.
Error:
01-29 12:55:19.027 14098-14098/com.skip.client.customer E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.skip.client.customer, PID: 14098
java.lang.NoClassDefFoundError: android.support.v4.app.ActivityCompat21$SharedElementCallbackImpl
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:305)
at com.activeandroid.ReflectionUtils.getModelClasses(ReflectionUtils.java:83)
at com.activeandroid.DatabaseHelper.onCreate(DatabaseHelper.java:46)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.activeandroid.Registry.openDatabase(Registry.java:149)
at com.activeandroid.Registry.initialize(Registry.java:107)
at com.activeandroid.ActiveAndroid.initialize(ActiveAndroid.java:8)
at com.activeandroid.app.Application.onCreate(Application.java:9)
at com.skip.client.customer.App.onCreate(App.java:12)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4473)
at android.app.ActivityThread.access$1500(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5146)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
It looks like getModelClasses() in active android is trying to find a java class in your code that matches the model classes you would have specified in your AndroidManifest.xml. Can you please post your manifest? Specifically, I'm looking for a line like this:
<meta-data
android:name="AA_MODELS"
android:value="
com.example.myapp.Book,
com.example.myapp.Chapter,
com.example.myapp.Library
"/>
If classes Book, Chapter, and Library are not defined in your code, then you'd get the no-class-def-found exception.
Also, I'd recommend changing your app to have your custom app class derive from android.app.Application instead of from the ActiveAndroid app base class. And then explicitly initialize ActiveAndroid. This will allow you to have your own exception handling around ActiveAndroid.initialize() and then explore why your exception is being thrown. You can also use the debugger to step into the initialize() method and see where the exception is coming from.
import com.activeandroid.ActiveAndroid;
public class App extends android.app.Application {
#Override
public void onCreate()
{
super.onCreate();
// add your own exception handling around this. Not that you can do much
// in your app without a database, but at least you'd be able to log a
// meaningful error to the log so you can know details about the exception
// being thrown.
ActiveAndroid.initialize(this);
}
}

NoClassDefFoundError when trying to build google api client

today i added the google play services library to my project. I have followed the instructions which are given on http://developer.android.com/google/play-services/setup.html#ensure
Screenshot of my Settings: https://drive.google.com/file/d/0Bwe9sI6XZ6rcZGZzdmlaQjVheDA/edit?usp=sharing
The problem is when I try to execute the following code, a noclassdeffounderror exception raises.
public class MainActivity extends Activity {
private GoogleApiClient mGoogleClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
mGoogleClient = new GoogleApiClient.Builder(this)
.addApi(Games.API)
.addScope(Games.SCOPE_GAMES)
.setGravityForPopups(Gravity.TOP | Gravity.CENTER_HORIZONTAL)
.build();
In the logcat the exception looks like
threadid=1: thread exiting with uncaught exception (group=0x40d02930)
FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: com.google.android.gms.common.api.GoogleApiClient$Builder
at com.gmail.mhofer4991.at.taptorotate.MainActivity.onCreate(MainActivity.java:104)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2147)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$600(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5074)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Force finishing activity com.example.taptorotate/com.gmail.mhofer4991.at.taptorotate.MainActivity
I also have cleaned and rebuilt the project.
It's driving me crazy that i cannot solve the problem. I know there are already other threads with the same topic and I also tried some solutions which were suggested there but none of them worked for me. Please help me out!
I also had same problem,
java.lang.NoClassDefFoundError:
com.google.android.gms.common.api.GoogleApiClient$Builder
I was using the below dependency on the application build.gradle file.
compile 'com.google.android.gms:play-services:7.8.0'
I changed it to
compile 'com.google.android.gms:play-services-plus:7.8.0'
I updated the Google Play Services (Rev 26) and Google Repository(Rev 20).
After that the exception doesn't occur.
Try to use individual APIs and corresponding build.gradle descriptions as mensioned in the following page,
https://developers.google.com/android/guides/setup#ensure
Try to add obfuscation rules for the Google API's if you have minifyEnabled or ProGuard set to true:
ProGuard Configuration
tryin to work with an implementation of Google Drive in Android i´ve found this error message pointing some classes like:
java.lang.ClassNotFoundException: com.google.android.gms.common.api.Scope
Caused by: java.lang.ClassNotFoundException: Didn't find class
I have found that the real problem is the limit of 64K references when we add dependencies related to GoogleApiClient, so adding multidex support solved my problem:
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
...
...
multiDexEnabled true
}
...
...

java.lang.NoClassDefFoundError on an Activity

I receive a crash report from my production app, which tells me that there is an NoClassDefFound Exception on one of my activity.
The exception is thrown on this line:
final Intent i = new Intent(MainActivity.this, SomeActivity.class);
Where it claims that "SomeActivity" class is not found.
There is only one instance reported out of thousands of users. (On a Samsung Note Mini)
Which means it shouldn't be a compilation or wrong lib included issue.
Is there any clues for me to continue my investigation?
p/s: The activity is definitely defined in manifest. Else it won't even works on other user's phones.
Stack:
java.lang.NoClassDefFoundError: com.sensored.SomeActivity
at com.sensored.MainActivity$2.onItemClicked(MainActivity.java:920)
at com.sensored.adapter.SomeListAdapter$2.onClick(SomeListAdapter.java:115)
at android.view.View.performClick(View.java:2485)
at android.view.View$PerformClick.run(View.java:9080)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3697)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:853)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
at dalvik.system.NativeStart.main(Native Method)
1) Keep all activities under same package[say com.compname.proj.views].
2) Ensure in manifest, package attribute is set to the above package[i.e com.compname.proj.views].
3) In manifest, under all activity tag, make sure android:name attribute has values matching to below pattern:
android:name=".<your activity class name>"
Ex: android:name=".SomeActivity"
My point is not to use package name + activity class name for manifest activity declaration.

Categories

Resources