main.main on Android

Burcu Dogan · · 2405 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

main.main on Android

main.main is a Go package’s main function. This article will explain you how it is being invoked on Android.

Android’s primary language has been Java and each application was supposed load Dalvik VM and talk to system libraries through Dalvik. For this historical reason, Android operating system has never stabilized its system level libraries. The system libraries was always a moving target and backward compatibility has been handled at the SDK layer. This model is still true as of today. Even though Android supports native applications, they are being loaded by Dalvik or ART and talk through ABI stable (in a similar fashion to SDK) rather than making any direct system calls.

With Go 1.4, a main package became build-able into a Dalvik- or ART- loadable so file. So it became possible to generate Android APKs from a Go package by generating a boilerplate Android application that loads the generated shared library. As of today, gomobile build subcommand does this cumbersome work for you if you set -target=android.

The runtime story is straightforward. Once the shared library is loaded, we are looking for the exported main.main symbol by dlsyming and invoke it. At this point we already have Go runtime initialized — each so file contains its own Go runtime.

In order to target Android, we are using Android NDK’s toolchain and the system library headers provided in the NDK distribution. Due to the limitation of going through ART, we can’t simply cross compile to a binary but need to use the -buildmode=c-shared mode to output everything into a shared library.

In order to explain how this mechanism work, I will reverse engineer an APK that has been built by the gomobile tool.

$ gomobile build -target=android golang.org/x/mobile/example/basic

It will generate basic.apk which is a zip archive. Unzip to see the contents.

$ unzip basic.apk
Archive: basic.apk
extracting: AndroidManifest.xml
extracting: classes.dex
extracting: lib/armeabi/libbasic.so
extracting: META-INF/MANIFEST.MF
extracting: META-INF/CERT.SF
extracting: META-INF/CERT.RSA

classes.dex contains a subclass of NativeActivity that does the basic job of loading libbasic.so at runtime when the application is starting. AndroidManifest.xml is the bare minimum manifest that has org.golang.app.GoNativeActivity as its launcher activity. libbasic.so contains runtime, the main package and all of its dependencies.

System.loadLibrary(“basic”) loads the shared library and invokes ANativeActivity_onCreate. ANativeActivity_onCreate is responsible to find the Go package’s main function by looking for main.main.

$ gobjdump -t lib/armeabi/libbasic.so | grep main.main
001bff04 l O .rodata 00000004 main.main.func1.f
00072208 l F .text 000003bc main.main.func1
00071d14 g F .text 00000034 main.main

onCreate dlsyms main.main, calls it and the application code written in Go runs. Since ANativeActivity_onCreate is called each time the activity is recreated, we are ensuring that main.main won’t be called again on the later onCreate events.


有疑问加站长微信联系(非本文作者)

本文来自:medium

感谢作者:Burcu Dogan

查看原文:main.main on Android

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2405 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传