Dedexer got competition! Not one but immediately two - smali and baksmali is a DEX assembler/disassembler pair. The programs are brand new and - like Dedexer - they are also based on a Jasmin-like format. I tried them very shortly, the disassembler - baksmali - worked correctly and indeed produced an output similar to dedexer but I could not compile the output of baksmali back to DEX format with the assembler - smali. The disassembler does not handle ODEX files either.
The initiative is indeed valuable, however, and I encourage every reverse engineer out there give the new tools a try.
Wednesday, July 1, 2009
Tuesday, June 30, 2009
Custom adapter in color
I got a comment on this blog with relation to an old sin of mine, the custom adapter example program. That example was about custom views in a list adapter. The comment was innocent enough: is there a way to change the colors of that list? I thought it was a 5 minute task to answer that question, in the end I had to deal with a topic I never wanted to know about: themes.
Click here to download the example program.
It turned out that the color scheme used by ListView is eventually taken from the active theme. It is possible to change it programmatically but it is quite complicated to do so. Meanwhile, with themes, it is relatively easy. If you know the information source. The Android development guide is almost completely useless regarding themes, for example sample themes don't work. This blog entry from Brainflush is much more informative, at least its examples work. The source that helped me the most was the actual Android XML fileset that defines the themes. If you have access to the Android source tree, the Android system resources can be found under the platform\frameworks\base\core\res\res directory. The relevant files are styles.xml under the values subdirectory and the content of the drawable subdirectory.
If you check the styles.xml in the res/values directory in our example program, you will see that modifying the color scheme of the ListView is a quite complicated, multi-step process. First of all, in res/values/styles.xml, the ListView style is overridden with the android:listViewStyle property. The ListViewStyle (MyListView) in turn references a list selector (android:listSelector) that is stored in the res/drawable directory. That selector defines color schemes for all the possible state combination of the list row. To increase the fun, the resource compiler screwed up the image IDs in the R.java file if the weather icon image files were not at the beginning of the file name list, hence the bizarre names in the drawable subdirectory. Now what we need more is a transition that refers a 9-patch background image (block blue in our case) for the selected row and we are ready.
Don't say that it was not easy.
PS: I apologize for the hideous colors. :-)
Click here to download the example program.
It turned out that the color scheme used by ListView is eventually taken from the active theme. It is possible to change it programmatically but it is quite complicated to do so. Meanwhile, with themes, it is relatively easy. If you know the information source. The Android development guide is almost completely useless regarding themes, for example sample themes don't work. This blog entry from Brainflush is much more informative, at least its examples work. The source that helped me the most was the actual Android XML fileset that defines the themes. If you have access to the Android source tree, the Android system resources can be found under the platform\frameworks\base\core\res\res directory. The relevant files are styles.xml under the values subdirectory and the content of the drawable subdirectory.
If you check the styles.xml in the res/values directory in our example program, you will see that modifying the color scheme of the ListView is a quite complicated, multi-step process. First of all, in res/values/styles.xml, the ListView style is overridden with the android:listViewStyle property. The ListViewStyle (MyListView) in turn references a list selector (android:listSelector) that is stored in the res/drawable directory. That selector defines color schemes for all the possible state combination of the list row. To increase the fun, the resource compiler screwed up the image IDs in the R.java file if the weather icon image files were not at the beginning of the file name list, hence the bizarre names in the drawable subdirectory. Now what we need more is a transition that refers a 9-patch background image (block blue in our case) for the selected row and we are ready.
Don't say that it was not easy.
PS: I apologize for the hideous colors. :-)
Tuesday, June 23, 2009
Assets
Let's have something lighter than the application separation stuff was in the previous entry.
I got a mail from someone who wanted to embed raw files into the APK file so that they are available for the application when it is executing. I have never done such a thing but I remembered faintly something about the res/raw directory where such resources reside. They are still there but now there is a better thing: assets. The difference between a raw resource in res/raw directory and an asset is that assets behave like a file system, they can be listed, iterated over, discovered, just like files while for raw resources, you need the resource ID.
Click here to download the example program.
This simple application iterates over the files in the asset directory, reads their contents and sets three TextFields according to the content of these files. Assets go into the ./assets directory in the project root and can contain any files. The AssetManager class provides access to assets as InputStreams.
I got a mail from someone who wanted to embed raw files into the APK file so that they are available for the application when it is executing. I have never done such a thing but I remembered faintly something about the res/raw directory where such resources reside. They are still there but now there is a better thing: assets. The difference between a raw resource in res/raw directory and an asset is that assets behave like a file system, they can be listed, iterated over, discovered, just like files while for raw resources, you need the resource ID.
Click here to download the example program.
This simple application iterates over the files in the asset directory, reads their contents and sets three TextFields according to the content of these files. Assets go into the ./assets directory in the project root and can contain any files. The AssetManager class provides access to assets as InputStreams.
Saturday, June 13, 2009
Controlling application separation
I thought I knew how application separation in Android works. Then I had a little project and I realized that there is more than meets the eye. Here are my experiences.
The basic - and very efficient - separation method in Android is the multiprocess capability of the Dalvik VM. Dalvik is able to fork many instances of itself and can run applications in different Linux processes. By default, each application (the application tag in AndroidManifest.xml) has its own process. There is however another, often overlooked separation mechanism inside each VM process that provides further separation. The good old ClassLoader separation - originally designed to separate applets, used heavily in multi-module frameworks like OSGi - is also at work. Inside each VM process, each task - acitivity or service - uses in its own ClassLoader. This means that object instances created in different tasks are not visible to each other. The standard setup for Android applications is such that the classes.dex in the application's APK package is on the path of the application's own classloader. The application's own classloader delegates the loading of system classes to the boot classloader instance which is common for all the tasks in one particular VM process.
Class loading implementation in Dalvik is tied heavily to DEX files. This has visible side effects. Classes loaded by different class loaders that don't delegate to each other should be completely separated. The implementation differentiates the "initiating" and "defining" classloader (the latter is the one that managed to call defineClass() for a particular class from a particular DEX file in a particular VM process). This differentiation does not work very well and results in a glitch: once a class from a particular DEX file is defined, its static fields are visible and shared from all the class loaders that access the DEX file, even if they don't delegate to each other. This means that tasks of the same application (usually packed into the same DEX file) see each other's static fields.
As if this was not enough, Android provides control of task-VM process mapping. As said previously, usually each application goes into its own VM process. It is possible to declare, however, that applications share a process. This works like the following:
Click here to download the example program.
Our two example programs demonstrate the techniques described below. SharedApp1 allows the user to enter a string and it shares that string in different ways. With its own popup, it shares the string by means of a static field of SharedApp1 activity class. SharedApp2 is another application, having its own APK file but is placed into the same process as SharedApp1. SharedApp1 and SharedApp2 communicate through the good old System.getProperty/setProperty mechanism. Observe, that this works only if the sharedUserId/process mechanism is properly used, if you remove e.g. the process attribute from the manifest file of any of the apps, the property set by SharedApp1 is not visible anymore to SharedApp2 because they run in different VM processes. Also note that I compiled these applications with the debug option which means that they are both signed with the debug key. That key is common for both applications therefore they can have the same sharedUserIds. If you use a proper signing key, take care of using the same key when you sign applications that depend on the sharedUserId mechanism.

And now for something completely different. I was one of the reviewers of Roy Osherove's book titled The Art of Unit Testing (Manning, about 27 USD). Even though the book uses .NET examples, it is easily readable for Java programmers too. Unit testing is one of the most useful techniques I am aware of in software engineering, if you feel that your knowledge is not up to date, you might as well read this book. :-)
The basic - and very efficient - separation method in Android is the multiprocess capability of the Dalvik VM. Dalvik is able to fork many instances of itself and can run applications in different Linux processes. By default, each application (the application tag in AndroidManifest.xml) has its own process. There is however another, often overlooked separation mechanism inside each VM process that provides further separation. The good old ClassLoader separation - originally designed to separate applets, used heavily in multi-module frameworks like OSGi - is also at work. Inside each VM process, each task - acitivity or service - uses in its own ClassLoader. This means that object instances created in different tasks are not visible to each other. The standard setup for Android applications is such that the classes.dex in the application's APK package is on the path of the application's own classloader. The application's own classloader delegates the loading of system classes to the boot classloader instance which is common for all the tasks in one particular VM process.
Class loading implementation in Dalvik is tied heavily to DEX files. This has visible side effects. Classes loaded by different class loaders that don't delegate to each other should be completely separated. The implementation differentiates the "initiating" and "defining" classloader (the latter is the one that managed to call defineClass() for a particular class from a particular DEX file in a particular VM process). This differentiation does not work very well and results in a glitch: once a class from a particular DEX file is defined, its static fields are visible and shared from all the class loaders that access the DEX file, even if they don't delegate to each other. This means that tasks of the same application (usually packed into the same DEX file) see each other's static fields.
As if this was not enough, Android provides control of task-VM process mapping. As said previously, usually each application goes into its own VM process. It is possible to declare, however, that applications share a process. This works like the following:
- First we declare that applications wishing to share the same VM process belong to the same user ID. This is done by adding the sharedUserId attribute to the manifest tag in AndroidManifest.xml file like the following: android:sharedUserId="aexp.share.sharedapp". The value of the attribute must be a unique string shared among the applications wishing to use the same VM process. This is a powerful mechanism, hence Android enforces strong check of the APKs containing the declaration. Only the first APK for a particular sharedUserId can be installed without limitation. The issuer of the digital signature of that APK is saved and further APKs with the same sharedUserId must have digital signature from the same issuer, else their installation is rejected.
- We have to declare the alias of the process a certain task or the entire application goes into with the process attribute. This attribute can be added to application, activity or service tags in the AndroidManifest.xml file. For example: android:process="aexp.share.sharedappprocess". VM processes are proper Linux processes identified by PIDs but Android does an additional transformation: whenever a process is started which is tagged by the process alias, the Android framework saves the Linux PID and the process alias. If some other application refers to that process alias and the VM process is still running, that process will be used.
Click here to download the example program.
Our two example programs demonstrate the techniques described below. SharedApp1 allows the user to enter a string and it shares that string in different ways. With its own popup, it shares the string by means of a static field of SharedApp1 activity class. SharedApp2 is another application, having its own APK file but is placed into the same process as SharedApp1. SharedApp1 and SharedApp2 communicate through the good old System.getProperty/setProperty mechanism. Observe, that this works only if the sharedUserId/process mechanism is properly used, if you remove e.g. the process attribute from the manifest file of any of the apps, the property set by SharedApp1 is not visible anymore to SharedApp2 because they run in different VM processes. Also note that I compiled these applications with the debug option which means that they are both signed with the debug key. That key is common for both applications therefore they can have the same sharedUserIds. If you use a proper signing key, take care of using the same key when you sign applications that depend on the sharedUserId mechanism.
And now for something completely different. I was one of the reviewers of Roy Osherove's book titled The Art of Unit Testing (Manning, about 27 USD). Even though the book uses .NET examples, it is easily readable for Java programmers too. Unit testing is one of the most useful techniques I am aware of in software engineering, if you feel that your knowledge is not up to date, you might as well read this book. :-)
Wednesday, May 13, 2009
About quick method invocation
A good 3 months ago I wrote about the ODEX format when support for that DEX variant was added to the dedexer tool. Then I asked if there is anybody out there who knows, how the index in the invoke-virtual-quick Dalvik instruction can be interpreted. For example:
invoke-virtual-quick {v1,v2},vtable #0x3b
That 3BH is an offset but into what? I did not know, therefore dedexer does not interpret the offset which makes its output on ODEX files less useful. Then Nenik (nickname according to his request) finally gave me the solution. Here comes his mail, verbatim.
The index computation is pretty simple, but for reverse analysis you need more data.
The vtable contains all the methods that can be invoked by invoke-virtual, that is
all nonprivate member methods (even those final and native).
The vtable is obviously constructed by copying superclass's vtable, then replacing
overridden methods and appending all additional virtual methods.
The methods in the vtable are ordered as they were in the dex file.
Let's look at android.view.KeyCharacterMap for example. It extends java.lang.Object,
so it starts with:
Object:
0: .method protected clone()Ljava/lang/Object;
1: .method public equals(Ljava/lang/Object;)Z
2: .method protected finalize()V
3: .method public final native getClass()Ljava/lang/Class;
4: .method public native hashCode()I
5: .method public final native notify()V
6: .method public final native notifyAll()V
7: .method public toString()Ljava/lang/String;
8: .method public final wait()V
9: .method public final wait(J)V
a: .method public final native wait(JI)V
Then it replaces:
2: .method protected finalize()V
with the implementation from KeyCharacterMap
and adds:
b: .method public get(II)I
c: .method public getDisplayLabel(I)C
d: .method public getEvents([C)[Landroid/view/KeyEvent;
e: .method public getKeyData(ILandroid/view/KeyCharacterMap$KeyData;)Z
f: .method public getKeyboardType()I
10: .method public getMatch(I[C)C
11: .method public getMatch(I[CI)C
12: .method public getNumber(I)C
13: .method public isPrintingKey(I)Z
Anyway,
invoke-virtual-quick {v1},vtable #0x2
on an instance of any kind is simply the quick variant of
invoke-virtual {v1}, Ljava/lang/Object;.finalize:()V
Obviously for decoding invoke-virtual-quick opcodes inside, say,
framework.odex, you need the coresponding core.odex and ext.odex
to reconstruct the vtables of all the base classes.
An .odex file contains a list of such dependencies appended
after the body of the encapsulated dex, together with their SHA-1s:
00498D10 44 6E 95 3A │ 13 BC 10 91 │ 0E 00 00 00 │ 02 00 00 00 Dn.:.¼..........
00498D20 1C 00 00 00 │ 2F 73 79 73 │ 74 65 6D 2F │ 66 72 61 6D ..../system/fram
00498D30 65 77 6F 72 │ 6B 2F 63 6F │ 72 65 2E 6F │ 64 65 78 00 ework/core.odex.
00498D40 93 97 93 82 │ 99 DA 46 4E │ E2 13 DD 35 │ 4C 48 B5 7B .....ÚFNâ.Ý5LHµ{
00498D50 F0 06 51 D7 │ 1B 00 00 00 │ 2F 73 79 73 │ 74 65 6D 2F ð.Q×..../system/
00498D60 66 72 61 6D │ 65 77 6F 72 │ 6B 2F 65 78 │ 74 2E 6F 64 framework/ext.od
00498D70 65 78 00 54 │ F1 D0 82 95 │ 97 53 15 60 │ E4 D6 2C 48 ex.TñÐ...S.`äÖ,H
00498D80 8E 36 51 C5 │ 75 BE 2C 00 │ 50 4B 4C 43 │ 08 80 01 00 .6QÅu¾,.PKLC....
00498D90 08 80 01 00 │ 00 20 00 00 │ 00 00 21 AA │ C2 5C 31 00 ..... ....!ªÂ\1.
With all this data, it should be possible to reconstruct .dex from current
.odex format, something I would like to be able to do.
Thanks, Nenik, this is the information I needed to improve the dedexer tool. I will do that soon. If anyone has something to add, please, comment.
invoke-virtual-quick {v1,v2},vtable #0x3b
That 3BH is an offset but into what? I did not know, therefore dedexer does not interpret the offset which makes its output on ODEX files less useful. Then Nenik (nickname according to his request) finally gave me the solution. Here comes his mail, verbatim.
The index computation is pretty simple, but for reverse analysis you need more data.
The vtable contains all the methods that can be invoked by invoke-virtual, that is
all nonprivate member methods (even those final and native).
The vtable is obviously constructed by copying superclass's vtable, then replacing
overridden methods and appending all additional virtual methods.
The methods in the vtable are ordered as they were in the dex file.
Let's look at android.view.KeyCharacterMap for example. It extends java.lang.Object,
so it starts with:
Object:
0: .method protected clone()Ljava/lang/Object;
1: .method public equals(Ljava/lang/Object;)Z
2: .method protected finalize()V
3: .method public final native getClass()Ljava/lang/Class;
4: .method public native hashCode()I
5: .method public final native notify()V
6: .method public final native notifyAll()V
7: .method public toString()Ljava/lang/String;
8: .method public final wait()V
9: .method public final wait(J)V
a: .method public final native wait(JI)V
Then it replaces:
2: .method protected finalize()V
with the implementation from KeyCharacterMap
and adds:
b: .method public get(II)I
c: .method public getDisplayLabel(I)C
d: .method public getEvents([C)[Landroid/view/KeyEvent;
e: .method public getKeyData(ILandroid/view/KeyCharacterMap$KeyData;)Z
f: .method public getKeyboardType()I
10: .method public getMatch(I[C)C
11: .method public getMatch(I[CI)C
12: .method public getNumber(I)C
13: .method public isPrintingKey(I)Z
Anyway,
invoke-virtual-quick {v1},vtable #0x2
on an instance of any kind is simply the quick variant of
invoke-virtual {v1}, Ljava/lang/Object;.finalize:()V
Obviously for decoding invoke-virtual-quick opcodes inside, say,
framework.odex, you need the coresponding core.odex and ext.odex
to reconstruct the vtables of all the base classes.
An .odex file contains a list of such dependencies appended
after the body of the encapsulated dex, together with their SHA-1s:
00498D10 44 6E 95 3A │ 13 BC 10 91 │ 0E 00 00 00 │ 02 00 00 00 Dn.:.¼..........
00498D20 1C 00 00 00 │ 2F 73 79 73 │ 74 65 6D 2F │ 66 72 61 6D ..../system/fram
00498D30 65 77 6F 72 │ 6B 2F 63 6F │ 72 65 2E 6F │ 64 65 78 00 ework/core.odex.
00498D40 93 97 93 82 │ 99 DA 46 4E │ E2 13 DD 35 │ 4C 48 B5 7B .....ÚFNâ.Ý5LHµ{
00498D50 F0 06 51 D7 │ 1B 00 00 00 │ 2F 73 79 73 │ 74 65 6D 2F ð.Q×..../system/
00498D60 66 72 61 6D │ 65 77 6F 72 │ 6B 2F 65 78 │ 74 2E 6F 64 framework/ext.od
00498D70 65 78 00 54 │ F1 D0 82 95 │ 97 53 15 60 │ E4 D6 2C 48 ex.TñÐ...S.`äÖ,H
00498D80 8E 36 51 C5 │ 75 BE 2C 00 │ 50 4B 4C 43 │ 08 80 01 00 .6QÅu¾,.PKLC....
00498D90 08 80 01 00 │ 00 20 00 00 │ 00 00 21 AA │ C2 5C 31 00 ..... ....!ªÂ\1.
With all this data, it should be possible to reconstruct .dex from current
.odex format, something I would like to be able to do.
Thanks, Nenik, this is the information I needed to improve the dedexer tool. I will do that soon. If anyone has something to add, please, comment.
Thursday, May 7, 2009
Two books on Android
I have reviewed two Android books recently and now, that both are in press, I decided to write some words about the experience. The first book is Ed Burnette's Hello Android (The Pragmatic Programmers, ~22 USD).

The book is clearly written with newcomers in mind who want to produce something functional quickly. Innovative feature is the "fast forward" section at the end of each chapter. This guides the inpatient reader who don't want to read sequentially to other relevant section, much like a hypertext link. Then the book goes through the application model, user interface, 2D and 3D graphics (yes, it has a functional OpenGL example), multimedia, web programming and database issues. The book seems to concentrate on developers of UI-intensive applications, for example the Android service and content provider concepts are mentioned only shortly, meanwhile there is an abundance of UI-related examples, even advanced ones like 3D graphics. The integration of JavaScript and Java in the web programming section was a revelation for me, I did not know about the mechanism before reading the book and it is cool indeed.
The other book is Unlocking Android from Ableson, Collins and Sen (Manning, ~29$).

This book definitely has higher ambitions. It is longer than the previous one (~400 vs. ~200 pages) and expects sequential reading. Beside the usual topics, it ventures into such exotic areas like Linux-level programming in C in the Android environment. Curiously, this breadth of topics means that the Manning book deals less with UI-programming than Burnette's book (82 pages in the Burnette book vs. 62 pages in the Manning book).The Manning book does provide, however, a detailed view of Android programming model. It discusses Android services extensively and even presents, how to write a content provider (although not in detail).
To summarize, the two books follow different concepts. Burnette's book is, erm, pragmatic. It tries to make the reader productive as quickly as possible using the most common application type, the UI-intensive standalone application, with some web programming thrown in for good measure. Meanwhile, it omits a great deal of Android architecture. The Manning book builds systematically, by presenting the architectural concepts in detail. Decide yourself, which one suits you most. I enjoyed reading both.

The book is clearly written with newcomers in mind who want to produce something functional quickly. Innovative feature is the "fast forward" section at the end of each chapter. This guides the inpatient reader who don't want to read sequentially to other relevant section, much like a hypertext link. Then the book goes through the application model, user interface, 2D and 3D graphics (yes, it has a functional OpenGL example), multimedia, web programming and database issues. The book seems to concentrate on developers of UI-intensive applications, for example the Android service and content provider concepts are mentioned only shortly, meanwhile there is an abundance of UI-related examples, even advanced ones like 3D graphics. The integration of JavaScript and Java in the web programming section was a revelation for me, I did not know about the mechanism before reading the book and it is cool indeed.
The other book is Unlocking Android from Ableson, Collins and Sen (Manning, ~29$).

This book definitely has higher ambitions. It is longer than the previous one (~400 vs. ~200 pages) and expects sequential reading. Beside the usual topics, it ventures into such exotic areas like Linux-level programming in C in the Android environment. Curiously, this breadth of topics means that the Manning book deals less with UI-programming than Burnette's book (82 pages in the Burnette book vs. 62 pages in the Manning book).The Manning book does provide, however, a detailed view of Android programming model. It discusses Android services extensively and even presents, how to write a content provider (although not in detail).
To summarize, the two books follow different concepts. Burnette's book is, erm, pragmatic. It tries to make the reader productive as quickly as possible using the most common application type, the UI-intensive standalone application, with some web programming thrown in for good measure. Meanwhile, it omits a great deal of Android architecture. The Manning book builds systematically, by presenting the architectural concepts in detail. Decide yourself, which one suits you most. I enjoyed reading both.
Thursday, February 5, 2009
Asynchronous communication in Android
Old sins always come back to haunt. Once I wrote a blog post, shamelessly referring to a 2006 paper of mine. In that post, I praised the conformance of the Android system with regards to the requirements of the reflective middleware approach. I found that only one area was not covered appropriately, asynchronous communication. It could be then expected that when folks at Softwired ported their iBus//Mobile asynchronous communication framework to Android, they found me.
iBus//Mobile already supports a number of clients. For Java, there is J2SE, CDC and MIDP support, Android was just added to this list. Additionally, native clients like Windows CE and Symbian are also supported and all these clients are able to talk to each other using the iBus//Mobile queuing system. In Java, the access interface is the familiar JMS.
iBus//Mobile depends on a gateway on the network and each client talks to this gateway. Even if device-to-device communication is required, the data goes through the gateway. The protocol support is nicely done, the framework supports a bunch of protocols. Some are used in polling mode (e.g. HTTP), some of them, however, also work in push mode like the TCP or SMS bearers. In case of TCP, they maintain a TCP stream to the gateway, keep that stream alive with keepalive messages and push the device-bound messages over the gateway-device direction of this stream. The programmer has full control over the protocol selection. Also, there is pluggable encryption support.
Those who have not yet tried cannot even imagine, how time-consuming it can be to implement such a system. It sounds simple but when it comes to actually implement the communication between the client and the server parts, unpleasant surprises will pop up, e.g. about the differences of mobile networks with regards to timing, connection keepalive, etc.
How does iBus//Mobile compare to my dream system I envisioned in my paper? First, it is nicely componentized although not along the line of the Android component system. There is a pluggable protocol support which is a great feature, it is hard to survive without it in the mobile world. My dream system included protocol support for direct device-to-device communication (e.g. Bluetooth). This is missing in iBus//Mobile which may be due to their business requirements. I can imagine a creative usage of multiple protocols at the same time on the client side, e.g. falling back to SMS from TCP if packet data connection is not available or using SMS to trigger data push by e.g. HTTP to simulate a push bearer that can transfer large amount of data. I also find the relationship between queues and synchronization intriguing. iBus//Mobile uses a sliding window-based algorithm to ensure that there can be multiple queue items transmitted independently from each other at the same time. If off-line operation is a frequent requirement (e.g. the application puts large number of elements into the queue then connects to the server to deliver those elements), full-scale synchronization solution is more efficient.
But enough of the whining! Softwired provides a robust, field-tested solution to Android developers who need message queues. You'd better know about iBus//Mobile if you don't want to suffer in the weird world of mobile bearers, particularly in the push direction.
iBus//Mobile already supports a number of clients. For Java, there is J2SE, CDC and MIDP support, Android was just added to this list. Additionally, native clients like Windows CE and Symbian are also supported and all these clients are able to talk to each other using the iBus//Mobile queuing system. In Java, the access interface is the familiar JMS.
iBus//Mobile depends on a gateway on the network and each client talks to this gateway. Even if device-to-device communication is required, the data goes through the gateway. The protocol support is nicely done, the framework supports a bunch of protocols. Some are used in polling mode (e.g. HTTP), some of them, however, also work in push mode like the TCP or SMS bearers. In case of TCP, they maintain a TCP stream to the gateway, keep that stream alive with keepalive messages and push the device-bound messages over the gateway-device direction of this stream. The programmer has full control over the protocol selection. Also, there is pluggable encryption support.
Those who have not yet tried cannot even imagine, how time-consuming it can be to implement such a system. It sounds simple but when it comes to actually implement the communication between the client and the server parts, unpleasant surprises will pop up, e.g. about the differences of mobile networks with regards to timing, connection keepalive, etc.
How does iBus//Mobile compare to my dream system I envisioned in my paper? First, it is nicely componentized although not along the line of the Android component system. There is a pluggable protocol support which is a great feature, it is hard to survive without it in the mobile world. My dream system included protocol support for direct device-to-device communication (e.g. Bluetooth). This is missing in iBus//Mobile which may be due to their business requirements. I can imagine a creative usage of multiple protocols at the same time on the client side, e.g. falling back to SMS from TCP if packet data connection is not available or using SMS to trigger data push by e.g. HTTP to simulate a push bearer that can transfer large amount of data. I also find the relationship between queues and synchronization intriguing. iBus//Mobile uses a sliding window-based algorithm to ensure that there can be multiple queue items transmitted independently from each other at the same time. If off-line operation is a frequent requirement (e.g. the application puts large number of elements into the queue then connects to the server to deliver those elements), full-scale synchronization solution is more efficient.
But enough of the whining! Softwired provides a robust, field-tested solution to Android developers who need message queues. You'd better know about iBus//Mobile if you don't want to suffer in the weird world of mobile bearers, particularly in the push direction.
Subscribe to:
Posts (Atom)