I have an app written in Kotlin which contains an Activity that is a child of NativeActivity. It runs fine.
I cloned that app to create another one with similar functionality, and it deploys the APK just fine - but it crashes at runtime because ANativeActivty_OnCreate() is an unknown symbol.
I don't understand how it could even link and get packaged without that symbol being known, but also because it works fine in the original app. I'm at a loss for where to look for the cause of this issue. Has this happened to anyone else? What are some things I can try to resolve the problem?
Related
No comments about security concerns please, this is a very specific use case.
I am building an Android app that has two native libraries. We'll call them libFooA.so and libFooB.so. Now, libFooA.so is bundled inside the APK. However, it depends on libFooB.so, which is NOT bundled inside the APK. Instead, it is dynamically loaded from the internal storage at runtime using System.load().
Now, because libFooA.so depends on libFooB.so, I have to load libFooB.so first, (using System.load()) before I can load libFooA.so with System.loadLibrary(). Otherwise, I get this error:
dlopen failed: cannot locate symbol "SOMESYMBOL" referenced by "libFooA.so"...
Anyway so, this works perfectly on every single device running Android 6.0/7.0/8.0 that I have tested. However, it fails on every single KitKat device that I have tested. This led me to suspect that the issue was with Dalvik vs. ART. So I switched a KitKat device to ART through Developer Options and tried again, but it still fails. The perplexing thing is, the error that is thrown is exactly the same error that is thrown if I try to load libFooA.so before libFooB.so on a 6.0/7.0/8.0 device.
Additionally, the problem does not lie with System.load() itself on KitKat, as I have been able to successfully dynamically load and use native libs on KitKat before. The issue here is when trying to System.loadLibrary() a lib that depends on another lib which was loaded with System.load().
I have not yet been able to test on a Lollipop-based device, but I suspect it would work fine. Anyone know why KitKat is having an issue here? Is this a known bug with KitKat?
UPDATE: Fails on 4.4/5.0 ARM Android emulator. Works on 6.0 ARM Android emulator.
UPDATE 2: I think the answer lies on this page, could someone point me to which exact item causes the behavior change that lets this work on >= API 23?
My Android app is coming to the end. Debugging runs OK for many many times without any error. It runs just fine. It's the time for me to build a release and publish the app. I follow all the steps which can be found via Google easily. In fact the signed APK is installed OK and the app starts OK but if user interacts to navigate between screens of the app, it is crashed for no reason. Not all screen switching causes app crash, just some of them and I can notice that maybe it involves Reflection here. I design my own binding system to bind ViewModel behind with the Fragment and using Reflection is a must, no other way.
I totally believe that it is not any fault in my code because the app runs just fine in debug mode. And at the time of nearly completely losing all hope to publish the app, I found a signed version of the APK file in the debug folder (that signed version is generated only if you start debugging the app to run in some targeted device - even some emulator, building in Debug mode won't generate that file). It's very lucky for me that that signed apk works perfectly. I can deploy that APK to a new device and install normally, the app runs expectedly.
So it must be something wrong with the releasing process. Here is some info about configuration for Release mode (mainly in Android Options tab):
Packaging (Packaging properties): Nothing is checked in here.
Linker: I tried both Sdk assemblies only and Sdk and user assemblies but nothing works.
Advanced properties: I checked all options to support all possible CPU architectures (this should not be a problem because in debug mode, all these options are also checked).
At the beginning of learning Xamarin Android, I tried finding information about publishing Android app and did complete a simple test (to deploy a simple app). It worked OK at that time (maybe because it's too simple), but now when it comes to a complex one (mainly involving my binding system which uses reflection heavily) it can be crashed at some user interactions. I also have a separate library project (containing some custom Views) referenced OK in my main project (not sure if that could be a break, however one custom view is used OK while some others may cause crashing). Because all the crashes happen in a compiled build, I cannot debug anything to see what could be wrong.
No code is provided here because there is too much code, it seems to be crashed at many places and one more important reason is the code should not be the problem (for one reason I explained above - it just runs smoothly in debug mode, I even found a signed APK file in debug folder which can be installed OK and the app then runs just OK like in debug mode).
Since you stated you are using a lot of reflection, the first thing to do is:
In the Android Build Settings:
Disable Proguard if it selected
Change the Linker Options to Don't Link
Rebuild a release build
Update: Since this worked and the app no longer crashes.
The linker will sometimes remove code that you want to preserve.
For example:
You will need to determine what classes and/or method are being remove because that have no direct references and are only called via reflection and preserve those to prevent the linker from removing them.
If they are in your code, you can use the [Preserve] attribute.
If they are 3rd party libs or the Xamarin.Android framework, you can create a "hardcoded" fake reference to those classes/members so the linker sees that you need them.
You might have code that you call dynamically via System.Reflection.MemberInfo.Invoke.
If you instantiate types dynamically, you may want to preserve the default constructor of your types.
If you use XML serialization, you may want to preserve the properties of your types.
Ref: https://developer.xamarin.com/guides/android/advanced_topics/linking/
Background
I wanted to simplify the usage of DB in an Android app.
For this, I've compared some third party libraries that create a DAO layer.
I've come up with a nice library called "GreenDao" (presentation about it here) . The website shows that it's faster than other competitors (like ORMLite) and is optimized for Android.
The problem
For some reason, on some device (usually old devices, with GB) , I get the next console error when trying to install the app:
Installation error: INSTALL_FAILED_DEXOPT
Please check logcat output for more details.
Launch canceled!
I've searched for the reason of this error, but couldn't find out how to solve it. Many complain about this error, but I can't find out why it occurs, and what can be done.
The error is quite common and known, but it's never mentioned as the result of using this library, yet when I remove the usage of this library, everything works fine...
Also note that on newer devices (like nexus 4) it installs and works just fine, and that the sample itself also works fine no matter which device I test it on.
The question
Why does it occur?
Is it possible that the structure of the classes is just too much for old devices to load, since we use other libraries ?
Could it be that I've reached the limit of code that is supported by android apps?
The jar file itself takes just 87KB ...
How can I solve this?
Ok, I've found the problem and the solution:
It has nothing to do with GreenDao.
It's because the app uses too many jars, so maybe Android has a limitation of code.
The solution is to either delete un-needed jar files or delete a lot of code.
I've been working on an app for some time now and recently it keeps crashing on startup.
The error that causes it to crash is java.lang.ClassNotFoundException on my launcher activity. I've launched and debugged my app tons of times with no problems so I think I must've accidently changed something in a configuration file somewhere but I can't work out where.
I've checked the manifest file and there's nothing wrong, the path for the activity is correct and I've looked through the class file itself and again the package prefix is correct. I've also gone through the file directory and there's nothing wrong there either.
I tried changing the launcher activity to another one inside the same application and it runs with no problem, I've also tried creating a new launcher activity and that runs with no problem.
However, when I create a new activity and paste in all the code from the one that crashes the whole app crashes again. Even when the new activity has a different class name.
Also just before the app crashes I get two warnings:
Unable to resolve superclass of Lcom/bend/... and Link of class 'Lcom/bend/... failed
Now everything in my app is com.bend... NOT Lcom.bend... but I can't find anywhere where it's written Lcom. But I don't know if that's the cause of the problem or just a change the system does.
I know it's a real obscure problem but I just cannot figure it out. Any help would be awesome.
EDIT: I've just tried running another app I've done that's has a similar design and it's doing exactly the same thing.
I've just recently updated the SDK. Could that be the problem?
I've just solved it by creating an entirely new Android project and copying the java files and resources etc. into the new project.
I think it might have been the v4 support library that was causing the problem. I'm using a lot of Fragments so was relying heavily on it. Though I tried replacing the .jar file from an app that worked and it didn't seem to help...
In any case it was nothing to do with any of the classes or the manifest file.
I have submitted an app to the Amazon app store. It has been rejected twice now for the same reason, but I can't find the problem. It crashes right at the start, usually 2-3 activity windows in. This error never happens on our test devices, and there hasn't been a single error or crash from the app on the Google market. So thus far I've been completely unable to replicate the error.
On the last rejection we requested a stacktrace, which they sent, but only with errors, not warnings, which from what I gather is what I need to find out exactly what method is causing the Java.Lang.VerifyError from W/dalvikvm. Is it reasonable to assume that when they decompile the app, and inject their amazon drm/tracking/whatever code into the app, and recompile it, it's causing clashing errors with some of my code? or that Amazon are possibly compiling on a different version of Java than we are? (ours is 1.6)
The app has both minSDK and targetSDK set to api8, which is 2.2 minimum, and we compile it against 2.2, Has anyone else had this error with Amazon before and might be able to give me some insight as to how the problem was resolved?
Thanks
Found the problem. In the Manifest there was a .java file that was declared as an activity, which it was originally, but it had been changed to extend Dialog instead.
When Amazon injects code into your app, they look at the manifest to find the Android Activities, and inject code into them such as callbacks and method overrides, some of which are specific to the Activity class. When Amazon looked at my manifest, they thought the class was an Activity, but it was actually now a Dialog, and the app was crashing when trying to override methods that didn't exist.
Once removing the manifest declarations to the classes that weren't actual Activities, the app got approved. Its weird that google and eclipse didn't pick up on the declared activities that weren't activities when the app got compiled.
Hope this can help others who cant seem to find out the reason their apps not getting approved by Amazon.