The module class extends the generated spec and overrides each method; the Kotlin is kept minimal here, and Android with Kotlin teaches the language properly:
class BookShareModule(context: ReactApplicationContext) : NativeBookShareSpec(context) {
private val prefs = context.getSharedPreferences("book_share", Context.MODE_PRIVATE)
override fun getName() = NAME
// Promise<boolean> in the spec: the last parameter is a Promise to settle
override fun shareBook(title: String, url: String, promise: Promise) {
Log.d(NAME, "shareBook on thread ${Thread.currentThread().name}")
val activity = reactApplicationContext.currentActivity
if (activity == null) {
promise.reject("E_NO_ACTIVITY", "BookNest is not in the foreground")
return
}
val send = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "$title $url")
}
activity.startActivity(Intent.createChooser(send, "Share $title"))
prefs.edit().putInt("count", prefs.getInt("count", 0) + 1).apply()
promise.resolve(true) // the sheet opened
}
// A synchronous method; Codegen declared its Int32 result as a Java double
override fun getShareCount(): Double {
Log.d(NAME, "getShareCount on thread ${Thread.currentThread().name}")
return prefs.getInt("count", 0).toDouble()
}
// ...companion object { const val NAME = "NativeBookShare" }The two Log.d lines show where calls run. After one app start and one tap on a Share button (Calling Native Modules), logcat held:
adb -s emulator-5554 logcat -d -s NativeBookShare:D--------- beginning of main 09-25 01:44:15.804 2824 3220 D NativeBookShare: getShareCount on thread mqt_v_js 09-25 01:44:41.392 2824 3221 D NativeBookShare: shareBook on thread mqt_v_native 09-25 01:44:41.654 2824 3220 D NativeBookShare: getShareCount on thread mqt_v_js
The synchronous method ran on the JavaScript thread itself (mqt_v_js), so a slow one freezes the whole UI's logic; the promise-returning one ran on React Native 36,878 's native-modules thread (mqt_v_native). Neither is Android's main thread, so touching views needs runOnUiThread; starting an activity is allowed from any thread. Settle every promise exactly once: a forgotten one leaves an await hanging forever, and reject's first argument becomes the JavaScript error's code. And true only means the chooser opened: Android does not tell the app whether the user finally shared, so the count really means "share sheets opened".