Is there some sort of alternative toolchain or language for Android, which can generate standalone APK files?
Ideally it should not depend on the huge and ever-changing, ever-upgraded official Android SDK.
As a parable, I am looking for a rough equivalent to how PowerBASIC and Mingw targets plain Windows just fine, despite Microsoft releasing new Visual Studios all the time.
Bonus points if this language or toolchain itself is an Android program...
As you may or may not be aware, the Android toolchain is based on a few simple ideas:
Your code is compiled using the plain old java compiler, and linked against the Android stubs (android.jar) for linkage against the system library.
After being compiled, the code is converted to dex format. You can actually run this yourself, just do a dx --help. The job of the dx tool is to take Java class files and convert them to dex code, a pretty straightforward compilation which involves going from a stack based to register based vm, and a few other changes.
After having this in place, an apk is built using a set of apk tools. It used to be apkbuilder, but this has since been deprecated. You can actually run this yourself as well. All an APK is is simply a collection of the manifest, resources, and a single file for all the code in dex form. (I.e., many .class files compile to a single .dex which is quite a bit smaller because of a wrapped web of pointers).
So the Android toolchain isn't really all that complex. The custom build process is handled by ant build rules, which are defined in an SDK wide build.xml, which you can find in the platform-tools/ directory (iirc). However, to generate new baseline projects using this custom build environment you simply use the android update project command.
While I'm not sure if this is the response you'd hoped for, I hope it will disambiguate the build process. It's not really all that complex of a toolchain, the majority of it is off the shelf Java, and not Android specific (all that makes it Android specific is library specific stubs for dynamically linked system code). Beyond this, once you have a set of classes, you need only run a few commands to make an executable APK which Android unpacks. I would suspect that any tool targeting the JVM (and capable of linking with the Android specific dynamically linked API) could perform a similar process of producing class files and using this toolchain to compile the rest of the way, though obviously the automated ant build process makes it much simpler.
EDIT:
After some more digging, I found this relevant android-developers thread. An unsettling quote:
At this time we simply don't have the resources to support people who
want to use their own build system, but we really wish we could. In
many ways we try to make it easy on other tools vendor by clearly
separating logic to eclipse or ant specific code (hence the multitude
of jar files everywhere in the tools and in ADT), but this is not one
of them.
However, you may also find this link helpful.
Terminal-IDE and AIDE are pretty much what I was looking for. Both runs on Android.
Related
I want to develop an App that makes use of some heavy C++ code.
From what I have understood, I have two choices.
Build the library outside Android Studio and then import it, or put the C++ source code directly in Android Studio to let it build.
If I choose to build the library Outside Android Studio, I can use (OW): Windows or (OL): Linux.
At the same time, I know I can run Android Studio on either (AW): Windows or (AL): Linux.
My question is, can there be any performance difference in the App product running on the phone, depending on a specific approach I would follow (OW+AW/OW+AL/OL+AW/OL+AL/AW/AL)?
To integrate a C++ library into your Android application, from the performance point of view there's absolutely no difference. The difference in all those your mentioned options is the build process of your C++ library (the files with .so extension, i.e. shared library) which will be later integrated into your final .apk executable file. The Android NDK is doing everything at one place, but aside from performance, you should also consider other factors like development and testing capabilities, based on your project and your (and your peers') active skills. Speaking of the performance, it mostly depends on the number of calls between Java and C++ parts - the less data goes back and forth the better for the performance.
I want to make an interface for a C++ complicated algorithm on a tablet environment, the idea of a server running the C++ code isn't applicable.
Can I embed my C++ algorithm in NDK application (for android, can I do the same for iOS?) and make the interface with Android SDK, and then use the NDK app (maybe as a function) in my SDK android app?? is this scenario possible and how hard it's?
I'd prefer the most a solution involving cordova and hybrid approaches.
If there is a simpler approach I'd appreciate any idea.
You probably want to port some code to Android. I do not know if you code has been ever built under Android.
Anyway, first of all you have to locate and manage to build the hello-jni example in the Android NDK. I have it in android-ndk-r9d/samples/hello-jni. After that, you may start to add functions to that project. Forwarding data between Java and C++ is... well... error-prone.
Android comes with two build systems, the old one is ant-based, the new one is gradle. In addition, some guys manage to use 3rd-party build systems for Android.
If your project has never been built under Android, you will have to port it. If it has Windows/Linux/Mac builds, start from a Linux or a Mac one (in the latter case please note that "darwin" contains "win", this may cause bugs in your build script.) You will likely have to borrow some standard functions from where you can find them. In addition, a while ago Android did not support std::string at all...
If your project has been built under Android, you will have to manage to build it yourself and then use the binaries. Alternatively, you might prefer to just use the existing binaries (this will require less effort) and just not care about bugs.
One more possible approach is to find the project that both uses your preferred build system and has an Android build, build that project for Android and remove the contents, thus obtaining an empty project that is built with your build system of choice. I did no do this and I suppose it will not be as easy as it sounds now. (But you will have a chance to become an expert in that build system.) UPD This section applies mostly to projects that come with a 3rd-party build system. Usually such exotic build systems have some specific features, and one needs these features to build successfully. The general rule is that beyond some level of complexity all working systems are modifications of other working systems (and are never created from scratch). (Example: programmers add functionality gradually and testing is done after each addition; they just cannot write all and then test all.) So in the case of a 3rd-party build system it may be reasonable to take some working project using that 3rd-party build system, get the build system working and replace the project source.
In general what you want is possible for both Android and iOS, but there is no general-case solution.
I'm not too familiar with the Android build process, so I'm sorry if this comes off as a really stupid question.
Anyway, I'm writing testing code utilizing ActivityInstrumentationTestCase2 and Robotium for an Android application by the company I work for.
The company is rather large, so the transition to Gradle is going very slow. I would like to use Gradle for my testing project for ease and future maintainability, but right now the application I'm testing is built using a combination of ANT scripts and manual intervention with all dependencies checked in as jars in the repository. I'm not at all involved in that process, but I know it's pretty hacked together.
From what I understand, Gradle cannot simply depend on and trigger the building of another existing Android project unless that project also utilizes Gradle. So unless I want to really get my hands dirty with the build process of our application (we have people who are literally hired to only deal with that), I'm out of luck.
What I do have access to, however, are debug builds of our application.
So my question is, is there some way that I can have Gradle use the compiled debug APK as a local file dependency, or can APKs not work like that?
APKs don't work like that; you can't depend on them, for a variety of reasons. The most important reason is that the code and resources are processed and compressed and much of the original information needed to build them is lost at that point.
You'll have a tough time getting it to work properly. If things that you depend on are pure Java libraries, then if you could get them in JAR format you could depend on them from a Gradle project pretty easily. But if they're Android projects containing resources and manifest entries and such, then there isn't a compiled file format you could obtain those libraries in that would be compatible with Gradle. Gradle supports the AAR format for Android libraries, but that format is generated by Gradle and nothing else.
After searching a lot and reading a lot of information, I cannot decide which tool I should use for compiling my code. My codebase is mainly c++. I use primarily linux as my development machine.
Based on opinions I read before, my final candidates are waf and cmake, but I cannot decide myself which one should be more appropiate.
My primary requirements are:
Must be able to compile software in windows/linux and android.
Must be ready to run tests.
Must be able to play nicely with other libraries that must be compiled with another build system but most likely will have to be compiled from source.
Must be able to add custom steps, like for example, generating some data from some files (mainly graphics) before compiling, all integrated in the build system.
Some strong preferences are:
Being ready to support MAC compilation.
Being able to cross-compile from linux as many platforms as I can (maybe windows/linux/android but cannot MAC?)
Being able to add support for iOS compilation if the need arises.
Would be nice if the invocation interface was similar to that of autotools, since it is the one many people know and it is well documented.
Some questions:
If I have some rare requirement, which build system would be more ready to be extended?
Are both currently well maintained? (I wonder about waf mainly).
Community: if I find a problem, both communities are big enough to support me, in your experience?
For now my feeling is that I favour waf a bit as a tool, but cmake seems to have been quite successful for whatever reason.
Don't know much about waf, but CMake fits your requirements pretty well. I do know waf is written in Python, my personal favourite programming language ATM.
My primary requirements are:
Must be able to compile software in windows/linux and android.
CMake does Windows and Linux very well but so does any other build system worth its salt.
Someone wrote some Android scripts for CMake. Can't find anything similar for waf (my Google-fu turns up nothing.)
Must be ready to run tests.
CMake has a sibling testing framework.
Must be able to play nicely with other libraries that must be compiled with another build system but most likely will have to be compiled from source.
CMake has good integration with pkg-config, and can link against arbitrary shared libraries.
Must be able to add custom steps, like for example, generating some data from some files (mainly graphics) before compiling, all integrated in the build system.
CMake can generate custom rules.
Some strong preferences are:
Being ready to support MAC compilation.
CMake supports Mac quite well. It will even make you an Xcode project if you want, but it can also do command line builds.
Being able to cross-compile from linux as many platforms as I can (maybe windows/linux/android but cannot MAC?)
Cross-compiling is supported in CMake. CMake will not be the primary source of pain with cross-compiling - literally everything else will.
Especially with regards to cross-compiling for Mac. It's possible, but not worth it to cross-compile for that platform, considering you need access to a Mac anyways to get the libraries and header files, you need to patch GCC and clang and LLVM, etc. The only sound reason I've heard for going through this much pain is running an automated build server. Anyways, if you get a working Linux -> Mac toolchain, you should be able to cross-compile with CMake as if it were any other Unix platform.
Being able to add support for iOS compilation if the need arises.
iOS cross-compilation can be done, but you need a Mac.
Would be nice if the invocation interface was similar to that of autotools, since it is the one many people know and it is well documented.
Write a configure script that just calls CMake (cmake .). Then your users can do a ./configure && make && make install on platforms where that makes sense. There's also CPack which lets you generate DEB, RPM, NSIS (Windows) and DMG (Mac) installers/packages.
Some questions:
If I have some rare requirement, which build system would be more ready to be extended?
CMake is very extensible. It can be extended to support new languages and target platforms. (Given that waf is written in Python, it's going to be pretty hackable too.)
Are both currently well maintained? (I wonder about waf mainly).
CMake is mature and well-maintained.
Community: if I find a problem, both communities are big enough to support me, in your experience?
The community and extensions available are what keeps me coming back to CMake, from things like bakefile, honestly.
WAF
is pure Python
becomes part of your project, i.e. no external dependency
supports many build tools
can be used to do all kind of automations, not just building
It works perfectly for Linux, Mac or Windows.
On Android, gradle is the chosen build tool of Google. To use that is
wise, because it is set up to work by Google. You can call waf from
gradle and vice-versa, though.
If you want to learn all the low level Android
SDK tools, you could also use
WAF directly.
The SDK has
javac for Android Runtime (formerly Dalvik), Android\'s JVM, and produces a .class file
jar can also be used for Android
d8 (formerly dx) produces .dex files, with Dalvik executable code
aapt2 can then produce the .apk
javac and jar are known to WAF. For dx and aapt2 you would need
to create your own tasks, which is very
easy.
You would best make a WAF tool and
share it. Tools are either part of WAF or there is
waftools.
There are also these Steinwurf
tools.
If you make Android native code using
NDK:
you use CLANG, which is known to WAF
Further on you mentioned requirements:
WAF has waf_unit_test
WAF can do gnu_cross compilation. The Gnu toolchain knowns many
targets. But for Android you would need to set things up yourself
using the SDK or NDK. For NDK you could use the Gnu toolchain.
You would do waf configure, waf build instead of configure,
make, but you could wrap a Configure or Makefile around waf to
have the same commands.
WAF is very easily extendible with Python
WAF is now on gitlab and
constantly worked on.
The community is surely smaller than for CMake. But it is Python.
You can look into it and find out for yourself. You can also
contribute and become part of the community.
Im pretty sure the answer is no, but im using the new IntelliJ EAP version and have a project i worked on a while back which was just written against JDK 1.6 for an applet based application.
However now i could see how it could be useful in an android app that im interested in creating.
Do i now have to re-write all the code/tests again targeting the android sdk or can i just drop in my existing JAR file and only use android for the UI layer.
Its just android seems to make testing WAY harder than it needs to be, and i have alot of existing tests written and working, if it wasnt so hard to just write a quick unit test (standard Junit #Test style) i wouldnt mind porting, however i just dont get the whole instrumentation thing, as i dont need a UI at the moment...
Anyway so back to the point, can i use my existing JDK built code in an android app?
No!
Android uses the "Dalvik" VM from project harmony which uses a different set of bytecodes which are incompatable with the standard Java JVM bytecodes.
This was done both to optimise the VM for opreration on mobile platforms, and, probably more importantly to try and avoid Copyright and patent disputes with Sun and now Oracle.
More info here
However there is a tool called "dx" which can perform the conversion in the dev environment.
Okay, let me clear up your confusion.
Jars are converted to dex Dalvik bytecode during the compiling process thus you can use 3rd party jar libs.
However, in your case because its applet which has a different application lifecycle yes you might have to re-do it to get it to work in android.
As far as testing instrumentation is used on all java mobile development even JavaMe. It basically means that the Junit tests are run in the emulator or device but in android's case you are using android mock objects to test android specific things.