Swift, Kotlin, and Go

It is impressive to see the amount of similarity which exists in Swift, Kotlin and Go, the three new languages for iOS, Android, and server-development respectively. Consider a simple, Hello World program. Swift Swift 1 2 3 4 5 func printHello() { // Type automatically inferred to string let name = "Ashish" // let declares a read-only variable print("Hello world from \(name)!") } Kotlin ...

Android logo

Android: The right way to pull SQLite database

Here’s the proper way to pull an application’s SQLite database from an Android device.

Diagnosing Mac apps which won't open (error -10810)

Occasionally, my mac applications end up in a corrupt state where they won’t open. I recently encountered this with Deluge. The first step to diagnose is to open Terminal and open them in the terminal via Sh 1 2 $ open -a deluge # This name is same as the name of the app (minus the ".app" portion). LSOpenURLsWithRole() failed for the application /usr/local/Caskroom/deluge/1.3.12/Deluge.app with error -10810. Now, the error is more diagnosable but still cryptic. Deluge.app above is a directory and we can navigate to the binary located at Deluge.app/Contents/MacOS/Deluge and execute the actual binary to see a more actionable error ...

Java Musings - referencing an uninitialized final variable

Java has fewer quirks compared to C++, but sometimes I do come across surprises. A code like following will fail to compile since you are trying to initialize a variable with an uninitialized variable. Java 1 2 3 4 5 6 7 8 9 public class Sample { private final String mField1; private final String mField2 = mField1 + " two"; private Sample(String field1) { mField1 = field1; } } But if instead of directly referencing mField1, you reference indirectly via a getter method code will compile, and mField2 will get null value for mField1. ...

Application Not Responding (ANR)

Demystifying Android rendering: Jank and ANR

Almost everyone developing an Android app has seen something like this in their device logs. Bash 1 I/Choreographer(1200): Skipped 60 frames! The application may be doing too much work on its main thread. On most devices, the Android platform tries to render a new frame every 16 milliseconds (60 fps). The rendering requires that whatever work is happening on the UI thread should finish in that timeframe. Any unit of work (== Runnable) scheduled on the UI thread has to fit in that. When the work takes longer, then frames are skipped. One skipped frame is 16 ms of the hung screen. The UI looks janky and unresponsive and if the user interacts with the screen and the application does not respond in time ( 5 seconds) then Application Not Responding (ANR) shows up. ...

Built-in "Developer options" in Android

Android has a few good settings built right into the platform for debugging under a hidden “Developer Options” menu. You can turn them on via Settings -> About Phone -> Build Number (tap 7 times). The steps will be similar but might vary a bit across OEMs. In older versions of Android, this used to be an explicit option under the Settings tab. I find the following options to be useful for the development ...

Floating point in user-facing strings

%f in user-facing strings is dangerous. Depending on the architecture, programming language involved, version of that language and compiler optimization flags, results can vary slightly. And if there are multiple languages involved in the serving stack, it is almost impossible to argue with the outcome. If those variations are immaterial, then use %.1f or %.2f to get one or two digits of precision after the decimal point, respectively. Otherwise, don’t use %f at all. ...

Tabs vs spaces for code indentation

One argument which some people might give in favor of using tabs is that it allows the viewer to decide how the code should appear to them. And hence, it separates the logic (indentation) from its appearance. The biggest flaw in that argument is that it renders the concept of line length limits meaningless. Line length limits and the associated rules of wrapping bring a good structure to the code. Someone looking at a piece of code with 3-levels of nesting and tab-length set to 8 will see a very different line length from someone using a tab-length of 2. Always expand tabs. ...

File size should always be of "long" type

Java 1 2 3 int getTextFileSize(String fileName) { return (int) (new File(BASE_DIR, fileName).length(); // WRONG } A 32-bit signed int can deal with ~2GB worth of data. And if your code is not going to deal with files larger than 2GB, why worry? But what if someone wants to use the same code for a video file some day? Or What if someone writes another code to iterate over all the files in the BASE_DIR directory? Most likely they will be inclined to use int for the final sum as well. Adding integers in most languages results in int and automatic overflows into a negative number (and even worse, back to a positive number). The caller code might think that BASE_DIR does not exist. Therefore, the best future-proofing is to never have file size stored as an integer. Even, Android platform got it wrong with StatFs#getBlockSize and corrected it by adding StatFs#getBlockSizeLong. ...

My rm -rf moment

Yes, it did happen, and no, I am not stupid enough to execute rm -rf *. It was a bit more convoluted than that. I was trying to prepare a customized SD card image for the Android emulator. The fastest way to do that was to mount the SD card on my GNU/Linux machine and modify the files. The files on the SD card have root as the owner. Therefore, the easiest way to maintain a clean state was to make all modifications using sudo. My script included a command rm -r ${base_dir}/${old_file}. While executing the script, due to an error, both the variables were not set. It took me a few hours to recover; I never committed the broken script, so, I did not harm anyone else. But since then, my bash scripts have always included set -o nounset. ...