I learned recently of an Android library AndFix which allows for live method patching. Now, as far as I know, Dalvik does not allow runtime manipulation of bytecode or dex.
Can someone provide a good explanation on how AndFix does live patching?
Looking at the sources, you can see the patch mechanism for Dalvik here. The dalvik_replaceMethod() function is modifying the internal Dalvik state, changing the Method struct to point to a replacement method.
It doesn't modify the DEX on disk or in memory, just routes the method calls to a replacement method. This approach is highly version-dependent, as changes to Method or the way methods work will break things. Dalvik hasn't changed much since mid-2011, which makes it easy, but if you look at the nearby "art" directory you can see different implementations for each major version of Android.
Related
For example, I want to create a simple application based on GPS, with making waypoints, showing them on map, etc.. So, is it possible to make such an app using C++ only, without any Java sources? Would it be more difficult than making the same on Java?
So, is it possible to make such an app using C++ only, without any
Java sources?
No. If you want to receive GPS coordinates, there is no way to do this without any Java code.
You could write an app in which Java is used as a thin wrapper around native code, using JNI to exchange data between Java and C++. However...
Would it be more difficult than making the same on Java?
Yes! In addition, the app would likely end up being:
Slower.
Buggier.
Harder to understand and maintain.
For Android development, Java is just the natural, normal, default language, and C++ is for exotic special tasks, typically those which involve really intensive calculations. You use it when you need it, not because you don't "want to" write in Java or because "Java is slow".
Writing correct JNI code is also not exactly trivial. For example, it's very easy to get local references and global references wrong if you don't read the documentation, as the compiler cannot detect their incorrect usage.
As the official documentation of the Android Native Development Kit says:
Before downloading the NDK, you should understand that the NDK will
not benefit most apps. As a developer, you need to balance its
benefits against its drawbacks. Notably, using native code on Android
generally does not result in a noticable performance improvement, but
it always increases your app complexity. In general, you should only
use the NDK if it is essential to your app—never because you simply
prefer to program in C/C++.
It also says:
You cannot access features such as Services and Content Providers
natively, so if you want to use them or any other framework API, you
can still write JNI code to do so.
Yes, search for Android NDK. Apparently it's a bit of a hassle, you'll be using SO a lot!
I am embarking on some Android NATIVE coding (e.g. C++, not Java), and need to use the fairly undocumented sp<> ("Strong Pointer") refcount'd pointer class.
As far as I can tell, the Android sp<> template looks VERY much like the more familiar BOOST shared_ptr<> template. Standard refcount mechanism. They do NOT appear to be part-for-part compatible. For instance, Strong Pointers do NOT appear to be threadsafe. What other gotchas are there between the two?
A wider question would be: why is there no online reference for the NDK? Are they having enough diskspace problems on developer.android.com that they cannot fit it there? Grumble.
Android's sp<> is undocumented because it is part of the platform, and its implementation might change between platform revisions. You should not use it in NDK code, unless you copy all of the headers and corresponding source files into your own project.
It is intentionally not thread-safe for performance reason: actually doing thread-safe ref-counting requires adding memory barrier instructions which slow down the operation significantly on ARM (not so much on x86 and x86_64 though). Even Chrome uses two different classes to implement ref-counting for this reason (i.e. base::RefCounted and base::RefCountedThreadSafe).
As to other gotchas, I can't really tell, but I guess the implementation of weak pointers is also different from Boost. In all cases, if you don't understand what this code does, don't use it, it's not meant for general consumption.
I was wondering - how 'safe' are the functions provided by android libraries when doing development of other native libraries on android?
Are there things like Microsoft's strsafe.h or bstring? Or can those be ported over?
There are usually safe variants of unsafe functions you can use to ensure any manipulation problems are generally detected and dealt with before introducing difficult to detect bugs only noticed later on in execution. If I understand your question correctly, you may want to look at things like snprintf in place of printf, strncat instead of strcat, and using variants of malloc when creating character arrays that follow the 'succeed or die' convention.
I find these references helpful when coding in C for Android (I know the native library is lacking a bit).
http://www.cplusplus.com/reference/clibrary/cstring/
http://en.wikipedia.org/wiki/C_string_handling#Overview_of_functions
Using variants that require additional information, such as max buffer size or trigger easy to spot errors on failure is generally helpful to avoid subtle bugs that can be a hassle later on.
I am working on Android projects which involve the lot of concurrent programming and I am going to implement some custom inter-threads communication stuff (the one from java.util.concurent are not well suited for my purposes).
The concurrent programming is not easy in general but with Dalvik it seems to be even harder. To get the correct code you should know some specific things and that where problem arise with Dalvik. I just can't find a detailed documentation about the Dalvik VM. Most Android resources (even the developer.android.com focused on platform API and doesn't provide any deep information about some non-trivial (or low-level) things).
For example, to which edition of Java Language Specification the Dalvik VM is conform ? Depending of answer the treatment of volatile variables are different and affect the any concurrent code which use the volatile variables.
There are already some related questions:
Is Dalvik's memory model the same as Java's?
Double checked locking in Android
and some answers by fadden are very useful but I still want to get more detailed and complete understanding of matter in question.
So below a raw questions I am interesting in (I will update the list if necessary as answers for previous questions will arrive):
Where to find the details about the Dalvik VM which may provide the answers for questions below ?
To which edition of Java Language Specification the Dalvik VM is conform to ?
If answer to (2) is "third edition" then how complete the Dalviks's support of Java Memory Model defied in this specification ? And especially how complete the support for semantic of volatile variables ?
In the Double checked locking in Android the fadden provide the following comment:
Yup. With the addition of the "volatile" keyword, this will work on uniprocessor (all versions of Android) and SMP (3.0 "honeycomb" and later)
Does it mean that Samsung Galaxy SII which has the dual-core CPU but only Android 2.3 may execute the concurrent code incorrectly ? (of course Galaxy is only an example, the question is about of any multicore device with pre-Android 3.0 platform)
In the Is Dalvik's memory model the same as Java's? the fadden provide the answer with the following sentence:
No currently-shipping version of Dalvik is entirely correct with respect to JSR-133
Does it mean that any existing correct concurrent Java code may work incorrectly on any Android version released up to date of posting of this comment ?
Update#1: Answer to #gnat's comment (too long to be comment too)
#gnat post a comment:
#Alexey Dalvik does not conform to any JLS edition, because conformance requires passing JCK which is not an option for Dalvik. Does it mean that you even can't apply standard Java compiler because it conform to standard specification ? does that matter? if yes, how?
Well, my question was somehow ambiguous. What I actually meant is that JLS is not only the rules for Java compiler implementations but also an implicit guidelines for any JVM implementations. Indeed, JLS, for example, states that reading and writing of some types are atomic operations. It is not very interesting for compiler writer because read/write translated just into a single opcodes. But it is essential for any JVM implementation which should implement these opcodes properly. Now you should see what I am talking about. While Dalvik accept and execute the programs compiled with standard Java compiler there are no any guaranties that they are executed correctly (as you may expect) just because no one (except maybe Dalvik's developers) knows if all JLS's features used in the program are supported by Dalvik.
It is clear that JCK is not an option for Dalvik and it is Ok, but programmers really should know on which features of JLS they may rely when execute their code on Dalvik. But there is no any words about this in documentation. While you may expect that simplest operators like =, +, -, *, etc. are works as you expect what about non-trivial features like semantic of volatile variables (which is different in 2nd and 3rd editions of JLS)? And latter is not the most non-trivial things you may find in JLS and particular in Java Memory Model.
I haven't read your question completely,
but first of all do not use volatile, even opengles coders do not use it for different ui vs renderer threads.
Use volatile if and only if one thread writes (say to some class' static property)
and other reads, even then you have to synchronize, read this for some good ways to handle counts
How to synchronize a static variable among threads running different instances of a class in java?
always use synchronize
do not jump at large projects for such difficult topics like concurrent programming
go through android samples on games where they have discussed the concept of runnables,
handlers, and exchanging messages b/w threads (UI THREAD AND RENDERER THREAD).
I think you answered your own question, although you have given no details as to why the java.util.concurrent package does not fit your needs, most mobile apps simply use asynchronous IO and a minimum of threading. These devices aren't super computers capable serious distributed processing so I have a little difficulty understanding why java.util.concurrent wont meet your needs.
Secondly, if you have questions about the Dalvik implementation and whether it conforms to the JLS (it doesnt), it would seem to reason that the only reliable support for threading mechanisms would be those which the language defines - java.util.concurrent, runnable and thread local storage.
Hand rolling anything outside of the built in language support is only asking for trouble, and as your question suggests will likely not be supported in a consistent manner on Dalvik.
As always when you think you can do threading better than the guys who wrote Java, think again.
<copied from comment> Dalvik does not conform to any JLS edition, because conformance requires passing JCK which is not an option for Dalvik. </copied from comment>
programmers really should know on which features of JLS they may rely when execute their code on Dalvik
I think the only way for them to know is to study Dalvik test suite (I bet there's one and I expect it is open source isn't it?). For any feature you need, 1) try to find a test that would fail if your feature is implemented incorrectly and check if the test looks good enough. If there's no such test or it's not good enough, 1a) add new or improve existing test. Then, 2) find out if the test has been successfully run against your target implementation. If test hasn't run then 2a) run it yourself and find out if it passes or fails.
BTW above is roughly about how JCK works. The main difference is that one has to invest own time and effort with Dalvik for things one gets from Sun/Oracle for granted. Another difference seems to be that for Dalvik this is not documented while Snorcle has clear docs on that iirc
But there is no any words about this in documentation.
well if there are no words on that then I'd say quality of Dalvik documentation is suboptimal. Softly speaking
Here's the honest answer. If java.util.concurrent is not up to task for your implementation then your problem isn't java.util.concurrent but is instead your original design specifications. Revisit your design, maybe post here what in your design makes using simple mutex's not up to task for you and then the community can show you how to design it better.
The Android NDK has just been significantly expanded to include support for writing android applications entirely in native C/C++ code. One can now capture input events on the keyboard and touch screen using native code, and also implement the application lifecycle in C/C++ using the new NativeActivity class.
Given all the expanded native capabilities, would it be worthwhile to completely bypass Java and write Android application in native code?
The NDK is not native per-se. It is to a large extent a JNI wrapper around the Android SDK. Using NativeActivity gives you a convenient way of dealing with certain app-life cycle events, and add your own native code on top. ALooper, AInputQueue etc. are all JNI wrappers of the Java SDK counterparts, some with additional code that is private and unaccessible for real apps.
When it comes to Android development, there's no such thing as writing an application entirely in native C++ - you will (in every real App case that I can think of) always need to use the Android API:s, which are to a huge extent pure Java. Wether you use these through wrappers provided by the NDK or wrappers that you create yourself doesn't really change this.
So, to answer your question: No, it wouldn't be worthwhile, because you would end up writing JNI wrappers for SDK calls instead of writing JNI wrappers to your own Java methods that do the same thing, with less code, simpler code and faster code. For example, showing a dialog using "pure c++", involves quite many JNI calls. Just calling a Java method through JNI that does the same thing will give you faster code (one JNI call), and, arguably, code that is easier to maintain.
To fully understand what you can do, you really must examine the Android source code. Start with native_app_glue.c, which is available in the NDK, then continue with the OS implementation of AActivity, ALooper, AInputQueue etc. Google Code Search is a great help in this. :-)
If it is easy to do in Java, and includes many calls, call a method through JNI that does it all, rather than writing all the extra code to do it with multiple JNI calls. Preserve as much of your existing C++ code as is reasonable.
Not if you are just making a standard application. The Java SDK is more complete than its Native counterpart right now so you would still be making things more difficult for yourself.
If you are not doing something that requires the NDK (read: real time performance sensitive) then stick with Java.
Just some food for thought but if you have an app on iOS and Android, some C/C++ code might be shareable. Obviously the iOS Obj-C and platform specific code wouldn't work elsewhere. (Ditto for the Android specific stuff). But you might be able have some shared code that's platform neutral.
If you can, stick with the java style apps until versions of Android supporting native activities constitute a significant fraction of the installed base.
For things that were hard to do before - particularly ports of existing code - this will probably be a big help.
It's not entirely clear yet what has changed vs. just writing your own thin java wrapper. For example, is there still a copy of the dalvik VM hanging around?