Best android questions in February 2011

Why was "Avoid Enums Where You Only Need Ints" removed from Android's performance tips?

18 votes

The section "Avoid Enums Where You Only Need Ints" was removed from the official developper documentation. (See Why doesn't Android use more enums? for the old section content)

Why? Was there a change in the Android VM that made the tip obsolete?

the original version of that document was just a bunch of prejudices. it's been rewritten to only contain facts backed up by actual benchmarks, and it's updated as the VM is updated. you can find the various benchmarks -- plus some of the benchmarks we use to optimize the core libraries -- at http://code.google.com/p/dalvik/.

Loaders in Android Honeycomb

16 votes

I'm trying to figure out how to use Loaders in Android 3.0 but can't seem to get it to work. The docs only describe using CursorLoader but I'm using AsyncTaskLoader.

From the docs it seems that you should only need to implement AsyncTaskLoader.loadInBackground() but it never gets called after getLoaderManager().initLoader() and then creating the loader in the callback.

I can see debug messages saying Created new loader LoaderInfo{4040a828 #0 : ArticleDataLoader{4036b350}} so it seems like it is created successfully.

Is it possible that loaders are currently broken in the SDK or is there some method you need to call after creating the loader? (they don't do that in the CursorLoader example).

EDIT: Seems like calling forceLoad() on the Loader returned from initLoader() starts the loading at least but this means you can't handle rotations correctly :(

Dianne Hackborn replied on the bug tracker and referred us to the static library implementation. CursorLoader is doing forceLoad() which is why it is working.

See my attached class for a class which handles this for you in most simple cases at the bug tracker: http://code.google.com/p/android/issues/detail?id=14944

What optimizations can I expect from Dalvik and the Android toolchain?

14 votes

I'm working on a high-performance Android application (a game), and though I try to code for readability first, I like to keep in the back of my mind a picture of what is happening under the hood. With C++, I've developed a fairly good intuition about what the compiler will and won't do for me. I'm trying to do the same for Java/Android.

Hence this question. I could find very little about this topic on the web. Will the Java compiler, Dalvik converter (dx) and/or JITter (on Android 2.2+) perform optimizations like the following?

  • Method inlining. Under what conditions? private methods can always safely be inlined; will this be done? How about public final methods? Methods on objects of other classes? static methods? What if the runtime type of the object can easily be deduced by the compiler? Should I declare methods as final or static wherever possible?

  • Common subexpression elimination. For example, if I access someObject.someField twice, will the lookup be done only once? What if it's a call to a getter? What if I use some arithmetic expression twice; will it be evaluated only once? What if I use the result of some expression, whose value I know not to change, as the upper bound of a for loop?

  • Bounds checking on array lookups. Will the toolchain eliminate this in certain conditions, like the archetypical for loop?

  • Value inlining. Will accesses to some public static final int always be inlined? Even if they're in another class? Even if they're in another package?

  • Branch prediction. How big an issue is this even? Is branching a large performance hit on a typical Android device?

  • Simple arithmetic. Will someInt * 2 be replaced by someInt << 1?

Etcetera...

Hello,

This is Ben, one of the engineers working on the JIT @ Google. When Bill and I started on this project, the goal was to deliver a working JIT as soon as possible with minimal impact to resource contention (eg memory footprint, CPU hijacked by the compiler thread) so that it can run on low-end devices as well. Therefore we used a very primitive trace based model. That is, the compilation entity passed to the JIT compiler is a basic block, sometimes as short as a single instruction. Such traces will be stitched together at runtime through a technique called chaining so that the interpreter and code cache lookup won't be invoked often. To some degree the major source of speedup comes from eliminating the repeated interpreter parsing overhead on frequently executed code paths.

That said, we do have quite a few local optimizations implemented with the Froyo JIT:

  • Register allocation (8 registers for v5te target since the JIT produces Thumb code / 16 registers for v7)
  • Scheduling (eg redundant ld/st elimination for Dalvik registers, load hoisting, store sinking)
  • Redundant null check elimination (if such redundancy can be found in a basic block).
  • Loop formation and optimization for simple counted loops (ie no side-exit in the loop body). For such loops, array accesses based on extended induction variables are optimized so that null and range checks are only performed in the loop prologue.
  • One entry inline cache per virtual callsite w/ dynamic patching at runtime.
  • Peephole optimizations like power-reduction on literal operands for mul/div.

In Gingerbread we added simple inlining for getters/setters. Since the underlying JIT frontend is still simple trace based, if the callee has branches in there it won't be inlined. But the inline cache mechanism is implemented so that virtual getters/setters can be inlined without problems.

We are currently working on enlarging the compilation scope beyond a simple trace so that the compiler has a larger window for code analysis and optimization. Stay tuned.

How to slice & reverse camera view?

11 votes

Hi

I am working on an app that will show reverse view from camera. For example, if current view from camera is like: enter image description here,

the app should reverse view like: enter image description here

so user will see constantly reverse view from camera through this app.

I am not very sure how to achieve this. Any help or idea would be highly appreciated. Thanks!

I understand from your answer that you want to display the reversed view in real-time.

I would create a custom SurfaceView and override the onDraw method to split the image in two and reverse the two slices.

Then I would pass the holder of your surface to the camera object like this:

camera.setPreviewDisplay(myCustomSurfaceView.getHolder());

Why are Android popup messages called toasts?

11 votes

My guess it that the lightweight notifications in Android are called Toast because they popup like toast from a toaster. Can anyone confirm this or provide a better explanation? I am teaching a course on Android development and would like to edit the wiki, so I want to be sure to get it right.

Quoting wikipedia :

An ex-Microsoft employee of Google is credited with coining the term during the development of MSN Messenger, since Messenger's small notification windows slide upward into view, like toast popping out of a toaster

It seems your explanation might be the right one ;-)

Eclipse 3.6 frequently stalls on auto complete.

10 votes

Has anyone ever solved this issue? The auto complete stalls so frequently and for so long, I quit using it altogether. I've only seen one other post for this and the answer did not help. Any guidance would be greatly appreciated.

I've had success with the following using Eclipse (Classic) 3.6.1 on Windows 7 x64.

"A workaround, until the fix is released in 3.6.2 is summarized here: http://groups.google.com/group/android-developers/msg/0f9d2a852e661cba"

(copied for convenience)

"You can replace your /plugins/ org.eclipse.jdt.core_3.6.1.v_A68_R36x.jar plugin with one from http://www.google.com/url?q=http://adt-addons.googlecode.com/svn/patches/org.eclipse.jdt.core_3.6.1.v_A68_R36x.zip&ei=vg5aTf2RIMrUgAeI-qTvDA&sa=X&oi=unauthorizedredirect&ct=targetlink&ust=1297749446528273&usg=AFQjCNFv7FGlTrnoVhRGE35JPjHxOwI_Bw and restart Eclipse. Content Assists will be much better. Just try it. Don't forget backup your original plugins. "

lockCanvas() really slow

10 votes

Testing my game on a slower device (Orange San Francisco aka ZTE Blade) and I have been getting an appalling frame rate.

I put some debug code into the draw loop and discovered the following line is taking over 100ms:

c = mSurfaceHolder.lockCanvas();

Anyone else seen this behaviour? I temporarily replaced the surfaceview by extending View and implementing onDraw(), and I got a much better framerate.

Although in general surfaceView is much faster on my HTC Desire. I am suspicious this may be a Android 2.1 problem. I'm contemplating rooting the phone and upgrading it to 2.2 if possible, but I did want a device running on 2.1 so that might be counter-productive in the long run.

** update **

I've been working on this some more, and have discovered some more puzzling aspects to it.

I rooted the phone and installed 2.2 and the problem still happens. When the app is first started, the lockCanvas is working as expected (0-1 ms). Then at some point during my initialisation, lockCanvas suddenly starts taking approx 100ms.

It might be worth pointing out that I am loading my assets in an Async task, so that I can display a loading screen.

Despite my best efforts to pin down what the program is actually doing when the slowness occurrs I was not able to do so. In fact when I run it in debug mode and single step, it works fast!

Now I discovered that if I add a delay in the constructor of my SurfaceView (of about 10 seconds), the slowness doesn't occur and all works fine.

However if you press Home, and then switch back, the slowness comes back.

I'm pretty much at the end of my tether on this stupid illogical problem! I've got a mind to put it down to a device specific problem.

I feel it could have something to do with memory usage. Maybe something is being swapped out and it affects the video ram?

I'd be interested in theories at least.

About lockCanvas() from docs:

If you call this repeatedly when the Surface is not ready (before Callback.surfaceCreated or after Callback.surfaceDestroyed), your calls will be throttled to a slow rate in order to avoid consuming CPU.

Is it possible that your draw loop is initiated too early for some devices? I think this is the problem, since you wrote:

Now I discovered that if I add a delay in the constructor of my SurfaceView (of about 10 seconds), the slowness doesn't occur and all works fine.

Ensuring correct date/time

7 votes

Hi,

we are creating a location-enabled app where users use this app to record certain events in the field.

The important part of the event data is when an event happened. This is no issue when user is online, but we also support situations when user is offline (by remembering & later syncing events).

There could be situations when users are offline and they change the time on the phone, so that event times are wrongly recorded.

So, what would be the best way to ensure we get a correct time, independent of user actions, given that device could be offline. Some ideas:

  1. GPS time. Is it possible to acquire it?
  2. Tracking system time changes made by user?
  3. Any other idea?

Note: time does need second accuracy, approximately minute accuracy would be ok.

Note2: we are creating mobile apps for Android and iPhone, so I'm interested for generic solutions and also solutions that are specific to any of those two platforms.

I, personally, wouldn't worry so much about this scenario. The liklihood of someone intentionally changing the time on their Android (which periodically throughout the day syncs to a time server automatically) while offline seems low to me. That being said, the only way I could see compensating for this is to keep a service running in the background that keeps a running tally of the seconds passed since recording the location data offline. Once uploaded to your servers you could use the elapsed seconds to calculate a time offset from current UTC time. It's an awful lot to go through, but it would work.

GPS time is an interesting idea, but Android allows users of the SDK to send mock locations to their devices. I'm not sure you could reliably track changes to system time either, and even if you could you'd be capturing them after the fact without the current real time as context.

SyncML with Android and PHP Web Service

4 votes

I was just curious if anyone has used SyncML (Synchronization Markup Language) and if it's a good standard to use.

We'd need it for synchronising information from a tablet device to a web server (via web service) and vice versa.

Is SyncML too bloated? I was looking at some of the SyncML APIs and was quite daunting. So the big choice is to use this standard or build an in-house solution.

Even if I did do it in-house, we'd have to create some sort of way to define the data we're sending up, so definitely looking at building an XML schema, or alternatively use JSON.

Any opinions? Ideas?

SyncML and ActiveSync (and possibly some other prepared solution) have a signifficant advantage: There are some implementations that are probably stable. Another signifficant advantage is that the protocols are designed and tested. If you design your own protocol, you'll have to think about all possible situations in synchronization. So, even if your own protocol can be a bit simpler, you probably have to do more work and the result can be less stable.