Installed probably the last custom ROM update on my Galaxy S3 this year

I’ve been running custom CyanogenMod builds on my now aging Galaxy S3 for a while now (12.1, 13). Given that support for CyanogenMod ended at the end of last year, I thought it would be worth one last new ROM before I upgrade my phone this year, and installed the new LineageOS.

Using the already installed TWRP recovery that I already have installed, I downloaded the latest nightly LineageOS build from here, the latest Google Apps for Android 7.1 from here, booted into Recovery, deleted cache files etc, installed both new ROMs and now I’m up and running.

Even on my aging Galaxy S3, I have to say, this Android 7.1 build is surprisingly snappy, even faster than the last CyanogenMod build that I had that was pretty good.

Android development: drawing text on a Canvas

I have an Android project bubbling away. More details soon 🙂

I’m using a SurfaceView and needed to draw some text on it. The rest of the app is mostly drawing on the SurfaceView Canvas directly, but I need some text too.

I’ve dabbled with some Android development before, and I have to admit getting the layouts to do what you want them too almost seems to suck up the majority of my development time 🙁 This time round I got sidetracked trying to create a layout that was using a mix of TextView elements and adding my SurfaceView programmatically. This didn’t go too well, didn’t work at all, so I found a few posts like this, and worked out you need to draw directly on the canvas. Something like this does the job:

Paint textPaint = new Paint();
textPaint.setColor(Color.WHITE);
this.canvas.drawText("Hello world!", 20,50, textPaint);

This code is in the middle of a game display loop, but for completeness, to be able to draw to the Canvas first you need:

SurfaceHolder surfaceHolder = this.getHolder();
if (surfaceHolder.getSurface().isValid()) {
    this.canvas = surfaceHolder.lockCanvas();
   ...
}

And then to release the Canvas after you’ve finished drawing:

this.surfaceHolder.unlockCanvasAndPost(this.canvas);

 

Ok, next up, what about custom TTF fonts? Drop the TTF font you want to use in your assets/fonts folder, and then load it up with:

Typeface typeFace = Typeface.createFromAsset(this.context.getAssets(), 
    "fonts/yourfont.ttf");

To use this font with the text snippet above, just call setTypeface() and pass it in:

textPaint.setTypeface(this.typeFace);

Ok, how about specifying a font size that’s proportional to the resolution of the user’s screen? This is an interesting question. To avoid using fixed pixel size fonts and then having them not scale appropriately for different devices with different screen resolutions, Android uses a concept called ‘scale independent pixels’, or SP. This is described in this post here. In short, defines an SP value in /res/values/dimens.xml/dimens.xml like:

<dimen name="scoreFontSize">20sp</dimen>

And then reference and set it like this:

int fontSize = getResources().getDimensionPixelSize(R.dimen.scoreFontSize);
textPaint.setTextSize(fontSize);

Done! (I’ll share more on what I’m working on in a few days 🙂

Building a multi-container Spring Boot and MongoDB webapp with Docker 1.12.x – part 2

In the first part of this article, I showed how I split the frontend, backend and database all into their own containers, and how each could be individually scaled using docker-compose.

If you’re already familiar with docker-compose and using haproxy for load balancing against container, you might have noticed there’s a limitation in my approach, as both the backend REST service was exposing it’s port 8080 externally, and so I don’t think HTTP requests from the frontend browser in the app were ever passing through the haproxy to be load balanced, only the requests to load the front end on port 80 were being load balanced.

I looked into how I could configure haproxy with multiple backends, listening on different ports, but eventually came to the conclusion that adding two different haproxy containers, one load balancing for port 80 and one for port 8080 was easy to do.

I’m not sure if this is the best way to approach this, but it certainly. works. Leave me a comment if you have any suggestions.

Here’s my final docker-compose.yml:

 

version: '2'
  
services:
    mongodata:
        image: mongo:3.2
        volumes:
        - /data/db
        entrypoint: /bin/bash
    mongo:
        image: mongo:3.2
        depends_on: 
            - mongodata
        volumes_from:
            - mongodata
        ports:
            - "27017"
    addressbook:
        image: addressbook
        depends_on: 
            - mongo
        environment:
            - MONGODB_DB_NAME=addressbook
        ports:
            - "8080"
        links:
            - mongo
    web:
        image: docker-web-angularjs
        ports:
            - "80"
    lb-web:
        image: dockercloud/haproxy
        depends_on: 
            - web
        environment:
            - STATS_PORT=1936
            - STATS_AUTH="admin:your-password"
        links:
            - web
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
        ports:
            - 80:80
            - 1936:1936
    lb-addressbook:
        image: dockercloud/haproxy
        depends_on: 
            - addressbook
        environment:
            - STATS_PORT=1937
            - STATS_AUTH="admin:your-password"
        links:
            - addressbook
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
        ports:
            - 8080:80
            - 1937:1937

Spring Boot REST app in a Docker Container on the Raspberry Pi

Docker on the Raspberry Pi? Sure, with help from Hypriot who provide an iso image ready to go, getting docker up and running on the Pi is as simple as burning their image to an sd card and booting it up. Ok, so that part is simple.

Building an image to run on the Pi is not as straightforward as it sounds. Well, it’s no more complicated than building an image from a Dockerfile, but given that the Pi is ARM based and not x86, you have to build an image that is built/compiled with executables/libraries for ARM.

This makes complete sense when you think about it, you’re not going to get an image containing x86 executables and libraries to run on a Pi, but it’s rather sad that it isn’t possible to build an image for example from my Mac and and I can run on my Mac, or Linux, or on the Pi. Well, you can build the image on any architecture, but you can’t run an ARM compatible image on the Mac (or docker-machine/boot2docker).

Ok, so that in mind, there are a number of ARM compatible images on Docker Hub already – Hypriot also have base images ready to go. So to run Spring Boot in a container on the Pi, I need an ARM image with Java. Luckily, here’s one ready to go.

For a quick test, I took my simple Sprig Boot REST app I already have on GitHub, and threw together a Dockerfile using Alpine first to check it would run locally:

FROM java:openjdk-8-alpine

ADD SpringBootREST-0.0.1-SNAPSHOT.jar /opt/SpringBootREST-0.0.1-SNAPSHOT.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/opt/SpringBootREST-0.0.1-SNAPSHOT.jar"]

This runs as expected in docker-machine on my Mac.

To push to the Pi, the only change is to replace the base image with an ARM compatible image with Java, so this looks like:

FROM hypriot/rpi-java

ADD SpringBootREST-0.0.1-SNAPSHOT.jar /opt/SpringBootREST-0.0.1-SNAPSHOT.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/opt/SpringBootREST-0.0.1-SNAPSHOT.jar"]

To get it to my Pi, I set up a local Registry to push the image to, and then pulled it from the Pi. So tag the image to the registry:

docker tag spring-boot-rest-rpi registry-ip:5000/spring-boot-rest-rpi

…push to the registry:

docker push registry-ip:5000/spring-boot-rest-rpi

and then pull from the Pi:

docker pull registry-ip:5000/spring-boot-rest-rpi

And then fire it up!

docker run -it -p 8080:8080 registry-ip:5000/spring-boot-rest-rpi

Spring Boot in a Docker Container on the Pi!