The question has popped up on Stack Overflow a few times: how the heck does
do what it is doing?
Parallel Space allows the user to have N copies of your app, each with its
own portion of internal storage. The user could then register as Foo in one
copy and Bar in another, and use each copy of the app independently. This does
not require Android for Work, Samsung KNOX, or any other hardware-supplied
partitioning system – Parallel Space is just an ordinary Android app.
LBE Tech, the firm behind Parallel Space, has not said much about how they do
it, other than it involves “MultiDroid, the first application virtualization
engine on Android”. And I have never used Parallel Space personally, let alone
attempted to examine it (though
My guess is that this is a commercialization of
or at least an implementation of the same concept.
If somebody asked us what our Android apps run on, our initial response might
be “ummmm… Android?”, as the answer seems obvious.
However, most apps do not really interact much with Android, the OS, directly.
When you get past all the Java, most things in Android eventually hit one of
an IPC call using Binder, which covers everything from system services to
a native call to a JNI-style C/C++ library linked into our app, including
many such calls that come from framework code
Boxify, in effect, proxies both of those through its own app.
The details are in the Boxify paper.
In a nutshell, Boxify:
Forks a process
Loads your APK into that process
Replaces a lot of system service implementations, like
PackageManager, with its own implementations that route the IPC through
Uses “syscall hooking” to replace necessary system calls with others that,
again, route through Boxify
Runs your tweaked-in-memory app (notably, nothing Boxify does requires modifying
the APK itself)
So, for example, let’s think about disk I/O. Usually, we find out where to write by
calling methods on
Environment. Those, in turn, wind up returning
paths supplied by Boxify. When you try to open a
FileInputStream or something,
the Linux syscalls triggered by that I/O also route through Boxify, as it
android:isolatedProcess to carefully manage what capabilities the
APK can actually perform, and so your app would not be able to write to
Boxify, itself, was written as a proof of concept for running apps in dedicated
sandboxes, particularly for “untrusted apps”, to use the authors’ term.
However, this sort of virtualization technique – Android apps running inside other
Android apps, for an Inception-style
experience – requires that you trust the virtualization engine. After all,
by definition, it can see all I/O between the app and Android, as it proxies
all of that I/O. It is a MITM attack on the app.
I have little doubt that such virtualization
can be put to plenty of positive uses. At the same time, I sincerely hope that Google
and independent security researchers examine any such virtualization app, to
“trust, but verify”, to use the Reagan-era maxim.
However, this illustrates yet another way – on top of custom ROMs, emulators,
and related tricks – where a user can arrange to run your app in an environment
that the user controls more than they do a standard Android environment. That,
on top of standard rooting techniques, further emphasizes that
you cannot defend yourself from the user. DRM solutions and related techniques
are difficult to secure when the user controls the entire environment around
your app. Treating the user as the enemy might work for a majority of users,
but those who might really be your enemy may well be able to work around
whatever DRM-style protections you add. These protections resemble
the Maginot Line: strong defenses
against predictable attacks that may prove useless with a nimble adversary.
IMHO, you are better served finding a business model that does not require you
to treat the user as the enemy.
—Jan 17, 2017
The Busy Coder's Guide to Android Development Version 8.2 Released
Subscribers now have
access to the latest release of The Busy Coder’s Guide to Android Development,
known as Version 8.2, in all formats. Just log into
your Warescription page and download
away, or set up an account and subscribe!
In this update, I:
Added a chapter on the basics of using RxJava
Added a chapter on viewing PDFs, including embedding PDF viewers
in your app
Added a chapter on advanced
RecyclerView techniques, starting
RecyclerView to replace a
ViewPager for page-at-a-time user
Removed the appendix focusing on Android 7.0’s changes, with that material
being moved into appropriate chapters of the book
Added various miscellaneous improvements and errata fixes
This update also uses two different font sizes for code listings, employing a
larger font for listings whose lines are all fairly short, to help improve
Due to a change in the publication process, links between chapters
are showing up with changebars in this version. This should be a
one-time issue, not affecting future versions of the book.
Also, the APK edition of the book has a new appinar on
Android 7.0’s changes to notifications.
The next update is planned for late February.
—Jan 09, 2017
Options for Viewing PDFs
A remarkable number of developers come to Stack Overflow to ask about
how to show a PDF… without using a third-party PDF viewer app. The
conventional solution for showing PDFs is to use a third-party app,
ACTION_VIEW, as that minimizes work on the developer’s part and
gives the user the flexibility to choose what tool to use to view the
PDF. But, some developers do not want this.
Frankly, I haven’t quite figured out why they do not want this.
The stated reason, in many cases, is that the developers do not control
the PDF viewer app, and therefore do not trust it. However, since
the #1 recommended solution is to upload the PDF to a Web site,
then use a Google Docs URL to render it in a
WebView… how exactly
is that an improvement?
Regardless of rationale, there are some in-process options for viewing
PDFs, though they have their issues.
The only one native to Android proper is
PdfRenderer, and that was
only added in Android 5.0, leaving out a lot of current devices at
the present time. Also, it seems to have been developed primarily for
use with print preview, and specifically with previewing the sorts
of PDFs that you might create with
WebView or a
Canvas. In other
PdfRenderer chokes on various PDF files, rendering nothing
at all. Plus, all it does is give you the ability to convert a page
of PDF to a
Bitmap, so you still have to roll your own UI around
that. It also requires a seekable stream from a
which pretty much limits you to rendering files (no assets, no raw
The PDF renderer that Mozilla uses for Firefox is
PDF.js. This works with
WebView, but only the modern incarnation of
(i.e., Android 4.4+). It will also add ~2MB to your APK file, in
assets. But, it can handle a fairly wide range of PDF files.
The PDF renderer that Google uses for Chromium is
pdfium. However, this
wraps Pdfium in a
View that handles rendering and standard gestures (e.g.,
horizontal swipes to move between pages). This works well on older
Android versions (I tested through 4.1), but it adds about 5MB to
your APK per CPU architecture. By default, you get six architectures
and 30MB of overhead. With careful pruning of unnecessary CPU
support (see ya, MIPS) and ABI splits, you can minimize the per-APK
footprint, but you wind up with greater deployment complexity.
The next update to my Android book — due out on
Monday, if all goes well — has a chapter profiling and demonstrating
I suspect that there are some commercial PDF viewing libraries, which
may be worth considering as well.
But, overall, most developers should just let
the details of letting the user view a PDF.
—Jan 04, 2017
PSA: v25.1.0 Support Fragments Behavior Change
The most recent Awesome Android Newsletter
contained a link to an Android issue
about a side-effect of an API change.
Up until a few weeks ago, both for the native implementation of fragments
android.app.Fragment) and the Android Support Library backport
android.support.v4.app.Fragment), when executing
replace() transaction, the fragment being replaced would be called
onStop() before the replacement fragment would be called
However, the v25.1.0 version of the backport inverts this by default,
of the replacement fragment being called before
onStop() is called
on the fragment being replaced.
And, since this issue is flagged as “working as intended”, this default
behavior seems unlikely to change.
Note that the native implementation of fragments behaves as it has –
this change has not affected Android 7.1.1, for example. Also note
setAllowOptimization(false) on the
should revert this change and roll you back to the prior behavior.
This is part of a larger optimization change that aims to apply only the
subset of your transactions that represent the overall net change in the
state of the fragments. Quoting the documentation:
For example, one transaction adds fragment A, a second adds fragment B, then a third removes fragment A. Without optimization, fragment B could expect that while it is being created, fragment A will also exist because fragment A will be removed after fragment B was added. With optimization, fragment B cannot expect fragment A to exist when it has been created because fragment A’s add/remove will be optimized out.
If you have code that is dependent upon the order of these lifecycle
events, you will want to double-check how your code behaves with
fragment optimizations enabled. If you encounter problems, either adjust
your code or disable the optimizations.
—Dec 27, 2016
About the Support ExifInterface
Version 25.1.0 of the Android Support library has debuted a new
com.android.support:exifinterface artifact, which offers a standalone
ExifInterface, a Java class for reading the EXIF
tags from JPEG and raw files.
If that class name sounds familiar, that is because:
I suggested moving
ExifInterface into Android Support, to
InputStream as a data source, to better work with
I suggested moving
ExifInterface into Android Support, to give
us an implementation that was free of the security bug that Tim Strazzere
ExifInterface is not showing up in
the online Android developer documentation.
Also, there are no JavaDocs in the Android Support Repository (the
JavaDocs JAR is effectively empty). Hopefully,
this is a temporary hiccup.
Based on eyeballing the source to
it seems like they matched the API of the Android 7.0
This solves two problems:
We now have an
ExifInterface constructor that takes an
This implementation is pure Java, and so it avoids the buggy JHEAD
implementation that was the source of the security flaw
Note though that this class — and its SDK counterpart —
offers a limited API compared with
elsewhere in the AOSP. In particular:
You cannot modify the thumbnail image
You cannot save modified EXIF tags, thumbnails, etc. to a different
JPEG file than the one that you started with
Hence, you may find yourself still needing to use a separate EXIF
parser, just to get needed functionality.
That being said, though, the
ExifInterface in the the Android Support
library is a welcome addition, and I am very grateful to the engineers
who took the time to create it!
—Dec 15, 2016