SlidingUpPanelLayout conflicting with Robolectric - android

I have a project that uses the SlidingUpPanelLayout but I needed to start writing automated tests using Robolectric. When I introduced Robolectric to the project my Espresso based tests failed to start up. I would get an java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation when the system would try and inflate the SlidingUpPanelLayout.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.marcthomas.testrobolectric/com.marcthomas.testrobolectric.MyActivity}: android.view.InflateException: Binary XML file line #11: Error inflating class com.sothree.slidinguppanel.SlidingUpPanelLayout
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
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: android.view.InflateException: Binary XML file line #11: Error inflating class com.sothree.slidinguppanel.SlidingUpPanelLayout
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290)
at android.app.Activity.setContentView(Activity.java:1929)
at com.marcthomas.testrobolectric.MyActivity.onCreate(MyActivity.java:14)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at com.google.android.apps.common.testing.testrunner.GoogleInstrumentation.callActivityOnCreate(GoogleInstrumentation.java:428)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
... 11 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:594)
... 23 more
Caused by: java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
at com.sothree.slidinguppanel.ViewDragHelper.<init>(ViewDragHelper.java:392)
at com.sothree.slidinguppanel.ViewDragHelper.create(ViewDragHelper.java:348)
at com.sothree.slidinguppanel.ViewDragHelper.create(ViewDragHelper.java:361)
at com.sothree.slidinguppanel.SlidingUpPanelLayout.<init>(SlidingUpPanelLayout.java:334)
at com.sothree.slidinguppanel.SlidingUpPanelLayout.<init>(SlidingUpPanelLayout.java:263)
... 26 more
If I remove the SlidingUpPanelLayout from my activity_my.xml layout file in the project the tests will run successfully again, so it does seem to be something to do with these two components somehow.
I have created a demo project on github that demonstrates this behaviour. Cloning the code and running ./gradlew connectedAndroidTest will reproduce this issue.

To fix this I needed to add
exclude module: 'support-v4'
to the list of excludes in the app module gradle file where androidTestCompile for robolectric is declared. See explanation below.
This error was down to a Gradle configuration error. The reason is that there are dependencies declared multiple times in the build and one of them needs to be excluded.
To work this out look at the last part of the exception.
ViewDragHelper was the culprit so if in your IDE (Android Studio) open the search for class name (Command-O in OS X) and enter ViewDragHelper. You will see that there are multiple Jars that are returned. You will need to exclude the one that you don’t want.
In this situation we had the android-19 sdk, support-v4-19 and support-v4-20 and library-2.0.1 (the slideuppanellayout library) to solve this I needed to exclude support-v4.
So in the build gradle file for the project where I included robolectric I needed to add the following to the list of excludes.
exclude module: 'support-v4'

Related

Ionic3 MainActivity ClassNotFoundException on Android 4.4 (Kitkat)

I have an app using Ionic 3 and Cordova-Android 6.4.0. The app works fine on Android API levels > 19 (Kitkat). But running the app on Android 4.4 causes the app to crash at startup with the following exception:
03-21 14:07:40.513 2408-2408/com.xxx.app.xxx E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xxx.app.xxx, PID: 2408
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.xxx.app.xxx/com.xxx.app.xxx.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "com.xxx.app.xxx.MainActivity" on path: DexPathList[[zip file "/data/app/com.xxx.app.xxx-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.xxx.app.xxx-2, /system/lib]]
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
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)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.xxx.app.xxx.MainActivity" on path: DexPathList[[zip file "/data/app/com.xxx.app.xxx-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.xxx.app.xxx-2, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 
at android.app.ActivityThread.access$800(ActivityThread.java:135) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
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've read about the multidex fix, but I can't apply it to my Ionic app because I can't change the generated Java code to add MultiDex.install(this);.
Does anyone have a solution for this?
The problem and solution are described here.
The java.lang.ClassNotFoundException comes from the fact that the app and its libraries exceed 65,536 methods, and as a result the Java classes are spread across more than one DEX file (Dalvik EXecutable) within the app's APK, i.e. classes.dex, classes2.dex etc. Java classes required to start the app may end up in classes2.dex within the app's APK (as opposed to classes.dex), which can then not be loaded by the Dalvik runtime in Android versions less than 5. From the Android web site:
When building each DEX file for a multidex app, the build tools perform complex decision-making to determine which classes are needed in the primary DEX file so that your app can start successfully. If any class that's required during startup is not provided in the primary DEX file, then your app crashes with the error java.lang.NoClassDefFoundError.
The solution is to identify every class that is referenced at app startup in a text file, as described in the link at the start of my post.
However, the list of required classes is long and hard to establish. I got as far as the classes below, but there are still more startup classes to discover. My solution is to say "Sorry, this app is only available for Android 5 and later".
com/mycompany/app/myapp/MainActivity.class
org/apache/cordova/CallbackMap.class
org/apache/cordova/ConfigXmlParser.class
org/apache/cordova/CordovaActivity$1.class
org/apache/cordova/CordovaActivity.class
org/apache/cordova/CordovaInterface.class
org/apache/cordova/CordovaInterfaceImpl.class
org/apache/cordova/CordovaPreferences.class
org/apache/cordova/CordovaWebViewEngine.class
org/apache/cordova/engine/SystemWebViewEngine.class
org/apache/cordova/LOG.class
org/apache/cordova/PluginEntry.class
org/json/JSONException.class
org/json/JSONObject.class

Firebase library not working in <= Lolypop devices

In my current project I'm using FCM for notifications. Its good and its working fine, but whenever I try to open the application in any device less than lolypop i.e. version 21 it crashes at the beginning.
I did check out a lot of SO posts, but never saw anyone has fixed it as an answer.
I'm using the latest version libraries as below
compile 'com.google.android.gms:play-services:9.8.0'
compile 'com.google.android.gms:play-services-auth:9.8.0'
compile 'com.google.firebase:firebase-core:9.8.0'
compile 'com.google.firebase:firebase-messaging:9.8.0'
Please help, I need to provide support atleast upto jellybean devices.
CRASH LOG:
FATAL EXCEPTION: main
Process: com.arpaul.geocare, PID: 3127
java.lang.RuntimeException: Unable to get provider com.google.firebase.provider.FirebaseInitProvider: java.lang.ClassNotFoundException: Didn't find class "com.google.firebase.provider.FirebaseInitProvider" on path: DexPathList[[zip file "/data/app/com.arpaul.geocare-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.arpaul.geocare-2, /vendor/lib, /system/lib]]
at android.app.ActivityThread.installProvider(ActivityThread.java:4793)
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)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.firebase.provider.FirebaseInitProvider" on path: DexPathList[[zip file "/data/app/com.arpaul.geocare-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.arpaul.geocare-2, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at android.app.ActivityThread.installProvider(ActivityThread.java:4778)
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
Your dependency on com.google.android.gms:play-services:9.8.0 is including ALL the Google Play Services APIs, most of which you don't need. This needlessly increases the size of your APK and build time. It is also probably causing the app to have more than 64K method references, which on older devices requires Multidex, as explained here.
Instead, you should remove the dependency for com.google.android.gms:play-services:9.8.0 and replace it with the specific APIs you need. Instructions for that are provided here in the section titled Selectively compiling APIs into your executable.

CAST - Error inflating class android.widget.ImageButton

I have been using ChromeCast in my application before and it was working great. Recently I added Google Cloud Messaging in my application too, and for that I had to update dependency files to
'com.google.android.gms:play-services-cast:8.3.0' and 'com.google.android.gms:play-services-gcm:8.3.0'. But now when client disconnects chromecast we get the following fatal exceptions and the application crashes.
11-23 12:42:49.415 22117-22117/com.jadoo.jadooplus E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.jadoo.jadooplus, PID: 22117
android.view.InflateException: Binary XML file line #36: Error inflating class android.widget.ImageButton
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:315)
at android.app.Dialog.setContentView(Dialog.java:512)
at android.support.v7.app.MediaRouteControllerDialog.onCreate(MediaRouteControllerDialog.java:178)
at android.app.Dialog.dispatchOnCreate(Dialog.java:396)
at android.app.Dialog.show(Dialog.java:268)
at android.support.v4.app.DialogFragment.onStart(DialogFragment.java:399)
at android.support.v4.app.Fragment.performStart(Fragment.java:1813)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:989)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:458)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
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)
preceded by an InvocationTargetException and Resources$NotFoundException.
Even now when I change the version anywhere below 7.5.x the code works great. Any ideas why ImageButton is not drawable. I've spent a day at following the stacktrace and today surfing the web, no luck. I haven't found anything useful on the topic.
I applologize for not posting stacktrace from other exception' stacktrace but I can't add more in formatted code.
Edit 1: I can't seem to add any more code here so here's a snapshot:
Edit 2:
I have already tried disabling Proguard, with no effect. The issue persists on a LG G2 d802, a range of Samsung Tabs and Nexus 7. Also I am not using CastCompanionLibrary.

Android Studio - Unable to resolve class L after upgrade

I've recently upgraded my tools and build.gradle to version 21 in Android Studio.
My apk now crashes on load and I get the following error:
Unable to resolve superclass of Lcom/mypackage/MyClass;
Link of class 'Lcom/mypackage/MyClass
Is anyone experiencing similar issues?
I've tried the following but no success:
Cleaning the project
Restarting android studio
Re-importing the project
More log details:
java.lang.RuntimeException: Unable to instantiate application com.mypackage.MyClass:
java.lang.ClassNotFoundException: Didn't find class "com.mypackage.MyClass" on path:
DexPathList[[zip file "/data/app/com.mypackage-1.apk"],nativeLibraryDirectories=[/data/app-
lib/com.mypackage-1, /vendor/lib, /system/lib]]
at android.app.LoadedApk.makeApplication(LoadedApk.java:507)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4301)
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:5001)
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.ClassNotFoundException: Didn't find class "com.mypackage.MyClass" on path:
DexPathList[[zip file "/data/app/com.mypackage-1.apk"],nativeLibraryDirectories=[/data/app-
lib/com.mypackage-1, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at android.app.Instrumentation.newApplication(Instrumentation.java:975)
at android.app.LoadedApk.makeApplication(LoadedApk.java:502)
            
I later found out that this was an issue relating to multi dexing.
I needed to run a script to generate the names of the files for my main-dex-list
The blog post below has a detailed outline of this: http://blog.osom.info/2014/10/generating-main-dex-list-file.html

Dagger code giving NoClassDefFoundError in Android instrumentation tests, but works in the normal application

I am using Dagger in an Android application.
It is working in the Application but when I run the instrumentation tests, I am getting a NoClassDefFoundError.
I am using Gradle and Espresso. This is happening WITHOUT progaurd.
This is strange since the "Module$$ModuleAdapter" getting loaded , but "Module$$ModuleAdapter$EndpointProvidesAdapter" is not.
I pulled the APK back off the device and used dexdump to verify that the class is indeed in the APK, "Module$$ModuleAdapter$EndpointProvidesAdapter".
Any ideas on what might be causing this?
java.lang.NoClassDefFoundError: Module$$ModuleAdapter$EndpointProvidesAdapter
at ...Module$$ModuleAdapter.getBindings(MslModule$$ModuleAdapter.java:33)
at ...Module$$ModuleAdapter.getBindings(MslModule$$ModuleAdapter.java:13)
at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:185)
at dagger.ObjectGraph$DaggerObjectGraph.access$000(ObjectGraph.java:138)
at dagger.ObjectGraph.create(ObjectGraph.java:129)
at ...Application.onCreate(...Application.java:21)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4344)
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)
Caused by: java.lang.ClassNotFoundException: Didn't find class ...Module$$ModuleAdapter$MslEndpointProvidesAdapter" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/....test-1.apk", zip file "/data/app/...-2.apk"],nativeLibraryDirectories=[/data/app-lib/....test-1, /data/app-lib/...-2, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
            at ...Module$$ModuleAdapter.getBindings(MslModule$$ModuleAdapter.java:33)
            at ...Module$$ModuleAdapter.getBindings(MslModule$$ModuleAdapter.java:13)
            at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:185)
            at dagger.ObjectGraph$DaggerObjectGraph.access$000(ObjectGraph.java:138)
            at dagger.ObjectGraph.create(ObjectGraph.java:129)
            at ...eApplication.onCreate(...Application.java:21)
            at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4344)
            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)
Double Espresso is now deprecated in favor of Espresso 2.0. It's possible that it worked for you because Jake's done a good job of enumerating transitive dependencies that you may need to exclude in order to get things working.
In my experience, using Espresso 2.0 with Dagger may require you to exclude javax.inject from your espresso dependencies:
androidTestCompile ('com.android.support.test.espresso:espresso-core:2.0') {
exclude group: 'javax.inject'
}
You may need to do this for all of the espresso dependencies that your project includes.
This seems to be more related to the way I was including Espresso than it is a Dagger issue...
androidTestCompile ('com.google.android.apps.common.testing:espresso:1.1' ){
exclude group: 'com.squareup.dagger'
}
Switching to Jake Wharton's "double-espresso" made the problem go away.
https://github.com/JakeWharton/double-espresso
I am still not sure why that would cause a NoClassDefFoundError on that Dagger generated class.

Categories

Resources