A missing manual for Android.

1. Preface. A missing manual for Android.

1.1. Motivation

The motivation for this text is somehow bizarre. I am by no means an Android expert, but I have been using computers for a long time, and over that time I have found that despite superficial UX and command-line differences, the basic principles behind most programming systems are the same. So switching to a new system in most cases just requires thoroughly reading a manual, and you are good to go.

And, from most perspectives, Android is not at all different. It is generally a normal operating system, it can run processes, organise IPC, multiplex windows, sounds, and services.

But its official documentation is just a giant pile of AI-generated slop, and nobody seems to have written an unofficial version, which really baffles me. Seriously, WinAPI has good books about it, not even mentioning user-level books, UNIX has an insane amount of books, starting from “The UNIX Programming Environment” and ending with Michael Kerrisk’s “The Linux Programming Interface”.

Android, in its turn, is not even a bit simpler than WinAPI or UNIX, but, despite being the most popular OS in the world, seems to be lacking a decent manual.

Of course, I cannot write a book on something I did not take part in developing (nobody should), but due to such a horrible lack of materials I had the bravery to guess that even my humble jottings might be helpful to someone learning to efficiently use this wonderfully interesting system.

1.2. Basic principles

Writing down this book, I tried to follow the Occam’s razor in its (allegedly attributed to Albert Einstein) formulation: “Everything should be kept as simple as possible, but no simpler.”

When applied to computing, it becomes the following:

“I already have everything working the way I like it to be working on my desktop machine, now I just need to extend exactly the same things to my new portable device, spending as little effort as possible.”

The rest of this HOWTO is dedicated to implementing this principle.

2. Main body

2.3. TODO Storage

2.3.1. FHS

  1. /data/local/tmp – some developer-related temp directory? manuals recommend placing lldb-server, frida-server, and such there

2.5. TODO Debugging Android applications

Android’s default debugger on newer releases is lldb. Older releases used gdb. They are quite similar, but since newer Androids use lldb, I will pay more attention to it.

You need to get familiar with lldb itself:

  1. https://lldb.llvm.org/use/map.html
  2. https://lldb.llvm.org/use/tutorial.html

While it is probably possible to run lldb on the device itself.

2.5.1. Using the default debugger interface

  1. https://stackoverflow.com/questions/53733781/how-do-i-use-lldb-to-debug-c-code-on-android-on-command-line

You need to push a static build of lldb-server onto the device. I found that using the one shipped with Android is easier than building myself. lldb-server is in prebuilts/clang/host/linux-x86/clang-r530567/runtimes_ndk_cxx/aarch64/lldb-server. What exactly is specifically good about the build 530567 I have no idea, but other builds failed for me, the debugger stopping unexpectedly and the program being incredibly slow, too slow to debug.

With respect to a system-wide lldb, I had an issue with it, it didn’t disassemble aarch64 code, I do not know why.

adb push prebuilts/clang/host/linux-x86/clang-r530567/runtimes_ndk_cxx/aarch64/lldb-server
 ./lldb-server platform --listen "*:54321" --server
 adb forward tcp:54321 tcp:54321
 PYTHONHOME=prebuilts/clang/host/linux-x86/clang-r530567/python3/ LD_LIBRARY_PATH=prebuilts/clang/host/linux-x86/clang-r530567/python3/lib PYTHONPATH=prebuilts/clang/host/linux-x86/clang-r547379/lib/python3.11/site-packages/ ./prebuilts/clang/host/linux-x86/clang-r530567/bin/lldb
 # in lldb
 platform select remote-android
 platform connect connect://:54321
 process handle --pass true --stop false --notify true SIGSEGV
 process handle --pass true --stop false --notify true SIGBUS

In principle you can do something similar with GDB, you just need to find a static build of GDB.

https://github.com/hugsy/gdb-static

2.5.2. Use the Ghidra debugger

After you have set up the default lldb, you can connect a GUI to it, for example a Ghidra-debugger, because GUI software is better for data inspection.

https://github.com/NationalSecurityAgency/ghidra/issues/6386

adb -s a740e4ea forward tcp:54321 jdwp:20971

2.6. TODO getprop

This is a kind of “Registry” for system properties. "getprop" -T -Z.

They have something like selinux attributes attached to them (crazy!), so you need to understand SELinux first, before doing anything useful with them.

There is also setprop.

2.7. TODO init.rc

This is something like what Android has instead of init.d (why would you reinvent the wheel again?). Magisk can plug into this file without making the system go insane, but I guess it is better to use Magisk’s services anyway.

2.9. List of Java apps:

/data/system/packages.list

2.10. am (Activity Manager)

  1. https://stackoverflow.com/questions/2056717/how-to-debug-an-app-on-android-with-gdbserver

Some command for activities/services management.

For example, you can restart “Airplane Mode” by typing:

#!/system/bin/sh
  settings put global airplane_mode_on 1
  sleep 1
  am broadcast -a android.intent.action.AIRPLANE_MODE
  sleep 1
  settings put global airplane_mode_on 0
  sleep 1
  am broadcast -a android.intent.action.AIRPLANE_MODE

2.12. dalvikvm64

2.13. tombstones

3. Application-level development

3.1. Unset _JAVA_OPTIONS

Because Android Studio is shit and broken.

3.2. Delete all Android Studio data when updating

Otherwise very weird symptoms occur

  1. ~/.config/

3.3. when you change applicationId, it is not enough to re-sync Gradle

You also have to manually delete all run configurations and re-sync, otherwise weird errors occur.

~/.config/Google/AndroidStudio2024.2/

3.5. Sometimes adb server fails

The symptom is

Adb connection Error:EOF Cannot reach ADB server, attempting to reconnect daemon not running; starting now at tcp:5037

I fixed this by switching from openscreen to bonjour in Debugger settings.

This also makes the emulator start/stop buttons work again.

3.6. Camera APP in the emulator crashes.

This is because Google has a broken AOSP Marshmallow (Android 6.0) image. Use the Google API enabled one.

3.11. Dagger

3.12. Mortar

4. Debugging weird stuff