So it turns out that if you actually read the developer documentation carefully, "Services" in Android are not "background jobs" or "daemons" as you might expect from the name. No what they are is in fact simply a configuration mechanism to inform the Android OS that your application has work to do that can occur at times when your application Activities are not visible to the user.
Thus Services not only do not have their own separate Thread, but in fact are simply executed by your applications main thread, in response to events based on the service life-cycle. An important result of this is that within a Service or an Activity, all long-running jobs should be performed on a separate background as otherwise they will be run on the main thread.
The main source of confusion comes about because the Android developer documentation talks about Services being "killed" and restarted by the OS. But this actually simply referring to the process (i.e. the Linux process) which hosts each apps Dalvik VM and the fact that the OS can kill the process at anytime such as when memory is low. It's only in this case that Services would be "restarted" by the OS/Framework, but this of course only refers to the Services lifecycle callback methods (e.g. onCreate and onStartCommand) being called by your apps main thread after your app is restarted inside a new VM running within a new process. Once you understand this, the purpose of the "STICKY" flags then becomes obvious, as just being means to inform the framework how it should go about re-calling those callback methods after an app is restarted in a new VM.
An interesting result of all this is that there is no such thing as a Service "dying" in your app, except of course for the case of it throwing an uncaught exception, which would cause your apps main thread to exit and thus your whole app to "quit" bringing up the famous "Force Close" system dialog. Should you wish however to handle that situation, you have available to you the Thread.setDefaultUncaughtExceptionHandler() method which will allow you to catch unhandled exceptions and doing something useful (like logging them to the device storage or some external service) prior to your current foreground Activity existing.
Tuesday, May 1, 2012
Sunday, April 15, 2012
Automatic Android Release Builds with CI
So if you are using a CI server (eg. Hudson aka Jenkins) to build your Android app, when you come to release it you'll want to do that automatically too.
All thats required is this kind of stanza in your build.xml:
<property environment="env"/>
<target name="-post-build" >
<copy todir="bin">
<fileset dir="bin">
<include name="myappname-*.apk"/>
</fileset>
<globmapper from="myappname-*.apk" to="myappname-*.${env.BUILD_NUMBER}.apk"/>
</copy>
</target>
As you can see I'm also naming the final apk file with the Jenkins build number environment variable. There are a lot more other env vars that Jenkins sets that you can use.
Also note the reason I've used the globmapper is that this will work for both the debug and release build targets that are pre-defined in the standard android project ant build configs. This means you can have Hudson build configs for both debug and release.
If you want your release apk to be properly signed, you need to create a certificate and then point your ant build at it (ant.properties):
key.store=path/to/my.keystore
key.alias=mykeystore
If you don't want to type in the password for each build, you can add the following to your local.properties:
key.store.password=secretpasswd
key.alias.password=secretpasswd
And also add the passwd properties to your Jenkins config (click "Advanced" button in the "Invoke Ant" section of your build config). This way you never have to check your keystore passwords into version control.
Oh as a bonus, if you want to be able to access the build information within your apps code at runtime, you can stash this in a string value by putting something
like this in your build.xml:
<property environment="env"/>
All thats required is this kind of stanza in your build.xml:
<property environment="env"/>
<target name="-post-build" >
<copy todir="bin">
<fileset dir="bin">
<include name="myappname-*.apk"/>
</fileset>
<globmapper from="myappname-*.apk" to="myappname-*.${env.BUILD_NUMBER}.apk"/>
</copy>
</target>
As you can see I'm also naming the final apk file with the Jenkins build number environment variable. There are a lot more other env vars that Jenkins sets that you can use.
Also note the reason I've used the globmapper is that this will work for both the debug and release build targets that are pre-defined in the standard android project ant build configs. This means you can have Hudson build configs for both debug and release.
If you want your release apk to be properly signed, you need to create a certificate and then point your ant build at it (ant.properties):
key.store=path/to/my.keystore
key.alias=mykeystore
If you don't want to type in the password for each build, you can add the following to your local.properties:
key.store.password=secretpasswd
key.alias.password=secretpasswd
And also add the passwd properties to your Jenkins config (click "Advanced" button in the "Invoke Ant" section of your build config). This way you never have to check your keystore passwords into version control.
Oh as a bonus, if you want to be able to access the build information within your apps code at runtime, you can stash this in a string value by putting something
like this in your build.xml:
<property environment="env"/>
<target name="-pre-build">
<echo file="res/values/buildtag.xml"><![CDATA[<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="build_version">ABCXYZ123</string>
</resources>
]]>
</echo>
<replace file="res/values/buildtag.xml" token="ABCXYZ123" value="${env.BUILD_TAG}"/>
</target><echo file="res/values/buildtag.xml"><![CDATA[<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="build_version">ABCXYZ123</string>
</resources>
]]>
</echo>
<replace file="res/values/buildtag.xml" token="ABCXYZ123" value="${env.BUILD_TAG}"/>
Panel indicators for Unity
If you just want the system load indicator panel applet back just use this.
A whole lot more applets are listed in this answer.
A whole lot more applets are listed in this answer.
Tuesday, April 10, 2012
Html Notifications
Chrome has a simple API spec for doing "desktop notifications" from webpages. There's even a quasi-standard "editors draft" at the W3C for it.
Luckily someone has been nice enough to write a Firefox add-on to implement the API in Firefox (open source).
Unfortunately some sites such as Flowdock only sniff for the presence of the API in the DOM instead of actually doing a call to the API to ask user permission as suggested by the spec itself and so fails due to the different approach taken by the add0on vs the implementation in Chrome.
Luckily this is easily fixed by pre-approving Flowdocks url via a property in about:config
Luckily someone has been nice enough to write a Firefox add-on to implement the API in Firefox (open source).
Unfortunately some sites such as Flowdock only sniff for the presence of the API in the DOM instead of actually doing a call to the API to ask user permission as suggested by the spec itself and so fails due to the different approach taken by the add0on vs the implementation in Chrome.
Luckily this is easily fixed by pre-approving Flowdocks url via a property in about:config
key: extensions.html5notifications.permissions
value: {"www.210computing.com":0, "mydomain.flowdock.com" : 0}
Monday, April 9, 2012
Pretty JSON and Dark Ubuntu
Do get Eclipse using a dark theme to match dark background syntax highlighting plugin you need to set the gtk theme using myunity (from this answer on SO).
Pretty printing JSON with bash using just Python:
Using NodeJS and the pretty-data module to make a simple shell script.
Pretty printing JSON with bash using just Python:
Pretty JSON using an add-on in Firefox.echo '{"foo": "lorem", "bar": "ipsum"}' | python -mjson.tool
Using NodeJS and the pretty-data module to make a simple shell script.
Sunday, April 8, 2012
Mp3s
So out of box install of Ubuntu 12.04 now includes mp3 encoding (as well as decoding using fluendo decoder).
But theres this issue with VBR encoding (which is set in default gstreamer pipeline for mp3 encoding). And yes its been open just over 6 years!
Still I learnt about a handy tool called "mp3check" (and id3v2), exactly the kind of toold I'd been looking after for ages.
Of course the correct solution is to use a decent cdripper like the cli-based abcde.
But theres this issue with VBR encoding (which is set in default gstreamer pipeline for mp3 encoding). And yes its been open just over 6 years!
Still I learnt about a handy tool called "mp3check" (and id3v2), exactly the kind of toold I'd been looking after for ages.
Of course the correct solution is to use a decent cdripper like the cli-based abcde.
Saturday, April 7, 2012
Getting Android Emulator accelerated
On Ubuntu 10.04 or later install KVM as follows:
- sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
- install 2.3.3 Intel Atom Image via Android SDK Manager
- run: emulator-x86 -avd <avd_name> -nosound -qemu -m 1024 -enable-kvm
Subscribe to:
Posts (Atom)