When I right click on a project on Eclipse and click on "Run as Android App", does it have a different build process then Ant builds?
Currently I am working on an app that uses another project as a library dependence. Everything compiles fine and the app loads, but when I try to use the functionality the library provides, problems come up. The library has a checksum file to verify that the library resources are loaded correctly. When I build to my phone from Eclipse, this check passes. But when I use my ant build, the resource check fails.
I have compared both apk results (diff -rq ant/ eclipse/) and my differences are as follows:
Files ant/AndroidManifest.xml and eclipse/AndroidManifest.xml differ (this is expected)
Files ant/META-INF/CERT.RSA and eclipse/META-INF/CERT.RSA differ
Files ant/META-INF/CERT.SF and eclipse/META-INF/CERT.SF differ
Files ant/META-INF/MANIFEST.MF and eclipse/META-INF/MANIFEST.MF differ
Files ant/classes.dex and eclipse/classes.dex differ
Files ant/resources.arsc and eclipse/resources.arsc differ
I suspect resources.arsc may be causing the problem. The size of these files are only 8 bytes different.
I'm lost on this, anyone have an idea of why this is happening. I've tried deleting the checksum file, but the library won't work without it.
Related
Background info
When uploading an app to the play store that uses a native library its necessary to also upload the native debug symbols to get useful crash/ANR info.
If you upload without symbols you receive the following warning: "This App Bundle contains native code, and you've not uploaded debug symbols. We recommend you upload a symbol file to make your crashes and ANRs easier to analyze and debug."
In the past when uploading apps as .apk files it was necessary to manually upload such debug info. Now using .aab if the native library is built via android studio its possible to set android.defaultConfig.ndk.debugSymbolLevel = 'FULL' at which point when you build a the .aab it will include the debug info automatically, you upload this single file and everything is done/working.
pre-built libraries
However its not always possible/ideal/necessary to build a library inside android studio. Sometimes there are reasons for libraries to be externally pre-built and just used by android studio not built by it; Android studio supports this via a directory structure which is described here https://developer.android.com/studio/projects/gradle-external-native-builds#jniLibs
In short you just copy the libraries into the correct src/main/jniLibs/{ABI} path(s) and it is picked up and made part of the bundle.
Problem
Android studio can build a .aab that contains debug info that play store can understand so that you don't need to upload it manually.
Android studio can use pre built native libraries if you place them in the right path structure
I am unable to find any documentation or way to do both of these things together, use native pre-built libraries but include their debug info in the .aab. Even though logically it should be possible to do this.
I have searched everywhere I think but can't find anyone even talking about this really, how/where do you place the corresponding debug information so that that also can be included as part of the .aab? Is there a separate path for this, do they just need a specific file extension, does gradle need to be told what to do with them somehow?
Is it really just not possible?
Things I have tried:
Don't split the debug info just leave them in the .so files - play store does not strip them then so you deliver giant debug versions of your builds to your users
Split the debug info into files with .so.dbg extension and place them alongside the .so files - they aren't included in the .aab
Following the instructions (here https://support.google.com/googleplay/android-developer/answer/9848633 and elsewhere) to manually zip and upload the symbols after uploading the .aab - this appears to work but isn't the same convenience wise as having them in the .aab
I've tried building a sample app with android studio building a lib instead of using a pre-built lib just to verify that it does then include the debug info and what file extension it uses.
After some more digging I found the task responsible for this is "ExtractNativeDebugMetadataTask" with which some effort can likely be tailored/altered to do custom things here.
However this ended up being unnecessary as while digging into this I discovered that it actually already works.
At least as of now in latest gradle versions (not sure about the past).
It was only failing due to some NDK path confusion which doesn't fail the build/creation of the bundle building but just logs an easy to miss informational message.
Ultimately all you need to do to make this work is:
Build your external .so files with -g -g3 or similar
Do not strip them in any way
Place them in jniLibs directory structure un-stripped
Configure your build.gradle appropriately android{ ndk { debugSymbolLevel 'FULL' } ndkPath "$projectDir/path/to/NDK" }
Resulting .aab will contain the stripped .so files and the split-debug .so.dbg files all in the right location.
I have seen that there are decompilers that works pretty well to show on fly code and resources of compiled APK.
I'm wondering if there is a way to edit and rebuild APK classes without export all sources and resources recreating a new project manually adding all libraries resources code etc. Since the APK already contains all the needed dependencies and resources configured to work together should be possible.
Often there are apps that have small bugs that would be easy to fix if only was possible edit and rebuild APK on fly
You can use Virtuous Ten Studio that allows you to import an APK edit smali code and resources and rebuild the edited version of the APK.
(You can also configure it to show Java code but since uses a "smali to Java" approach the generated code is imperfect.)
https://ibotpeaches.github.io/Apktool/
You can use Apktools to extract and compress APK-files
It is possible to manage/edit Smali files. They are similar to Java-files.
I have a mature app that needs to have an SDK brought in that wraps the camera and makes it do some spiffy processing while it's running. The SDK has come to me in the form of some aar files but my app still lives in Eclipse. Because of my massive, steaming pile of a branding structure and deadlines for this integration the uncertain timeline required to fully migrate to Android Studio will not work (for now) so I'm going for converting the aars and using them in my app via Eclipse.
The problem I'm having is that I need to kick off the activity in the library but even though I fixed up all my build time reference problems, when running the app once I get to the point that is supposed to kick off the activity I get this error.
I've read through and double checked dozens of how-tos explaining how to consume the aar files and I think I've followed every step including:
Unzip the aar files and dress them up as individual library projects, including the file structure with the resources, the manifest, and the .jar
Make the project that needs the libraries add them as such
Add the .jars contained in the library projects to the build path (this step was not listed in most articles, and wasn't necessary for the project to build, but nevertheless it did not help my problem)
Declare the activity in your AndroidManifest.xml that the library brings in and declares in its AndroidManifest.xml
As I've said, everything looks good at build time, so I'm not sure what else to check. Because I'm reading that Gradle and Android Studio mashes manifests together really well, I have a hunch that it's something I'm supposed to regulate between the manifests but I don't know what it could be if that is it. I've wondered if I'm declaring the 3rd party's activity properly, but I'm not sure how to test it because the only way I can think to test it is to provide gibberish for the namespace but even then there are no complaints. I've also tried dissecting the .apk to look at the .dex file but I could not decipher anything useful.
My guess is that the library may not be building properly in eclipse - even before it's being added as a dependency to the application project.
Try looking at out/classes/* and making sure you have a .class file for the activity in question. I think the .class should actually be in the library as well as end up in the application project's out/ dir also.
If there are any native files (x.so) (as I would imagine there might be for spiffy camera stuff), you can look for the x.so files being included in the out/ dirs of both the library and application projects as well as the library.jar file.
Another option to maybe consider for this use case: https://github.com/ksoichiro/gradle-eclipse-aar-plugin
It seems that our app had a bad version of the appcompat-v7 support library. The .jars in it were different sizes than the one that comes with the SDK and several resources were missing. I have no idea how we ended up that way or where this bad version came from. Once I replaced it, things went great.
Later, I did encounter the need to drop in the .so files into the libraries I made that came out of the .aar files as Stad Kurdziel said in his answer, but that was causing a different error (the exception explicitly states that the .so is missing) and I arrived at the solution independently.
I am using an Android Unity plugin for a library which followed the prior Unity 5 suggested structure and it was working perfectly. The package was placing the necessary files under Assets/Plugins/Android where the jar file existed and in folder Assets/Plugins/Android/res/raw some .js and .css files used by the library. Everything was working perfectly but when upgraded to Unity 5 hundreds of errors appeared regarding the .js and .css files. (like insert semicolon at a specific line, or expected token at that line etc.)
I am aware of the changes in Unity 5, especially as mentioned here: http://docs.unity3d.com/Manual/PluginInspector.html , however I cannot find a proper solution to resolve this. So what i think the issue is that Unity is trying to parse these files as something different most probably as c# files resulting to the errors. How can exclude files in Assets/Plugins/Android/res/raw from that procedure, or at least how can i handle this situation. Do i have to restructure the file hierarchy with the new Unity 5? As far as I read they can keep the same structure for backwards compatibility.
We've got a similar issue on one of our projects, and there seems to be no way of preventing unity (at least, to try) to compile all your scripts. At this point unity expects the .js files to be "unity script files" and tries to compile them, which of then fails, when the .js files are some kind of web stuff.
I must admit, that I have no clue, why unity changed the behaviour from 4.x to 5, as the folder was indeed skipped from compilation in unity prior to version 5. See also "specific folders" section below.
Possible solutions
1. Putting the potential script files in a specific folder
There are some specific folders, where unity does not try to compile your files e.g. WebPlayerTemplates.
see http://docs.unity3d.com/Manual/ScriptCompileOrderFolders.html
2. Renaming the potential script files
As the unity compilation will only be performed for certain files (e.g. .cs or .js) you can avoid compilation by renaming them to e.g. .js_
For sure, both solutions will break your plugin in the first place, if you won't adapt it accordingly.
But what you can do is, to use a pre build hook to revert your changes (renaming or moving the files back) and make the plugin work on the device.
And just after the build again, to avoid the compilation (errors).
How to achieve this
Just create a custom build script (must be stored in an Editor folder, e.g. Assets/Editor). You'll find a new menu in unity named Build with an entry CustomBuild, where you can (and must) start your build.
Minimum version:
using UnityEditor;
using UnityEngine;
public class BuildProcessor {
[MenuItem ("Build/Custom Build", false, 0)]
static void CustomBuild() {
PreProcess();
BuildPipeline.BuildPlayer(new string[] { "your-main-scene.unity" }, "build-output-dir", BuildTarget.Android, BuildOptions.None);
PostProcess();
}
static void PreProcess() {
//Your pre-process here (e.g. rename all files from .js_ to .js)
}
static void PostProcess() {
//Your post-process here (e.g. rename all files back from .js to .js_)
}
}
More advanced scripts can be found on the web, or just feel free to add your creativity here ;-)
I took some inspiration here: http://jon-martin.com/?p=309
For how to rename a bunch of files you may want to check out this post: Renaming files in folder c#
I hope this will somehow satisfy your needs, let me know if something is not clear to you.
So I have noticed fairly recently a folder within my Phonegap/Android project (project/bin/dexedLibs) and this folder contains two .jar files. After scratching around the internet, I found one website in which the author says ADT version 21 puts "pre-dexed Libs" in the project to enable faster build times.
I did upgrade recently to ADT 21 and was just wondering if anybody else can give me more information on what these "pre-dexed Libs" really do? I haven't been able to find any other useful info on the net.
I have an Android project with about 20 external libraries. Before ADT 21, every time I changed source code it took ages to rebuild the app. Now it's quite fast!
I guess the reason is that, before ADT 21, it compiled the external libraries into dex code every time you hit the "Run" button in eclipse. Now it will compile the dex code for the external libraries only once (until they change) and use the prebuild libraries for later "Run"s.
I like that feature!
Be aware! I've just spent an hour to find out why I get the exception:
Caused by: java.lang.NoSuchMethodError:
The reason was because I changed my lib jar to new jar (the same name) with working method, and ADT 21 didn't prepare the new one in dexedLibs.
So just delete bin dir and Eclipse will recreate this.
The question is about 2 years old yet still of interest.
For people who browse here later: I just had trouble because I renamed a Cordova project from my.name.a3e to my.name.A3E and then the build process crashed. Came out that the dexed files in ant-build were not refreshed (case sensitivity). It worked fine after I deleted the ant-build folder, but the build took longer the first time after.
A dex file is a Dalvik EXecutable file, some compiled byte code that can be executed by the Dalvik virtual machine. Dalvik is a core component of Android, so that's why it is there.
http://sourceforge.net/projects/dexer/
http://developer.android.com/reference/dalvik/system/DexFile.html
http://fileinfo.com/extension/dex
Note that Eclipse project clean won't remove dexed libs.