android-sdd 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/index.js +143 -0
  2. package/package.json +27 -0
  3. package/skills/Android Ecosystem/Baseline Profile Generator/SKILL.md +277 -0
  4. package/skills/Android Ecosystem/Glance/SKILL.md +315 -0
  5. package/skills/Android Platform/Configuration/SKILL.md +201 -0
  6. package/skills/Android Platform/Filesystem/SKILL.md +216 -0
  7. package/skills/Android Platform/Lifecycle/SKILL.md +233 -0
  8. package/skills/Android Platform/Manifest/SKILL.md +226 -0
  9. package/skills/Android Platform/Process Death Recovery/SKILL.md +214 -0
  10. package/skills/Android Platform/Resources/SKILL.md +234 -0
  11. package/skills/Android Platform/SavedStateHandle/SKILL.md +217 -0
  12. package/skills/Android Platform/State Restoration/SKILL.md +210 -0
  13. package/skills/Architecture/Bounded Context/SKILL.md +207 -0
  14. package/skills/Architecture/Clean Architecture/SKILL.md +229 -0
  15. package/skills/Architecture/Domain Modeling/SKILL.md +236 -0
  16. package/skills/Architecture/Entity Design/SKILL.md +243 -0
  17. package/skills/Architecture/Feature Isolation/SKILL.md +216 -0
  18. package/skills/Architecture/MVI/SKILL.md +224 -0
  19. package/skills/Architecture/MVVM/SKILL.md +198 -0
  20. package/skills/Architecture/Modularization/SKILL.md +194 -0
  21. package/skills/Architecture/Offline First/SKILL.md +249 -0
  22. package/skills/Architecture/Repository Pattern/SKILL.md +216 -0
  23. package/skills/Architecture/Side Effect Management/SKILL.md +278 -0
  24. package/skills/Architecture/State Management/SKILL.md +229 -0
  25. package/skills/Architecture/Unidirectional Data Flow/SKILL.md +196 -0
  26. package/skills/Architecture/Use Case Design/SKILL.md +244 -0
  27. package/skills/Architecture/Value Object/SKILL.md +226 -0
  28. package/skills/Build Infrastructure/Build Orchestration/SKILL.md +257 -0
  29. package/skills/Build Infrastructure/Dependency Compatibility Resolver/SKILL.md +259 -0
  30. package/skills/Build Infrastructure/Environment Validator/SKILL.md +311 -0
  31. package/skills/Build System/Build Cache/SKILL.md +233 -0
  32. package/skills/Build System/Build Flavor Strategy/SKILL.md +171 -0
  33. package/skills/Build System/Build Variant/SKILL.md +215 -0
  34. package/skills/Build System/Convention Plugin/SKILL.md +288 -0
  35. package/skills/Build System/Dependency Management/SKILL.md +261 -0
  36. package/skills/Build System/Gradle/SKILL.md +284 -0
  37. package/skills/Build System/Incremental Build/SKILL.md +199 -0
  38. package/skills/Build System/KAPT/SKILL.md +198 -0
  39. package/skills/Build System/KSP/SKILL.md +263 -0
  40. package/skills/Build System/Module Dependency Graph Validation/SKILL.md +223 -0
  41. package/skills/Build System/Specialized/C++/SKILL.md +308 -0
  42. package/skills/Build System/Specialized/JNI/SKILL.md +306 -0
  43. package/skills/Build System/Specialized/NDK/SKILL.md +264 -0
  44. package/skills/Build System/Version Catalog/SKILL.md +304 -0
  45. package/skills/Concurrency/Background Processing/SKILL.md +185 -0
  46. package/skills/Concurrency/Channel/SKILL.md +207 -0
  47. package/skills/Concurrency/Coroutine/SKILL.md +200 -0
  48. package/skills/Concurrency/Flow/SKILL.md +179 -0
  49. package/skills/Concurrency/Mutex Strategy/SKILL.md +185 -0
  50. package/skills/Concurrency/SharedFlow/SKILL.md +171 -0
  51. package/skills/Concurrency/StateFlow/SKILL.md +175 -0
  52. package/skills/Concurrency/Structured Concurrency/SKILL.md +197 -0
  53. package/skills/Concurrency/Synchronization Policy/SKILL.md +192 -0
  54. package/skills/Core Language/Annotation Processing/SKILL.md +224 -0
  55. package/skills/Core Language/DSL/SKILL.md +186 -0
  56. package/skills/Core Language/Extension Functions Design/SKILL.md +191 -0
  57. package/skills/Core Language/Immutability/SKILL.md +156 -0
  58. package/skills/Core Language/KMP/SKILL.md +182 -0
  59. package/skills/Core Language/Kotlin/SKILL.md +187 -0
  60. package/skills/Core Language/Reactive State Management/SKILL.md +228 -0
  61. package/skills/Core Language/Reactive Streams/SKILL.md +235 -0
  62. package/skills/Core Language/Serialization/SKILL.md +191 -0
  63. package/skills/Data Layer/Cache Strategy/SKILL.md +261 -0
  64. package/skills/Data Layer/Conflict Resolution/SKILL.md +248 -0
  65. package/skills/Data Layer/DAO/SKILL.md +225 -0
  66. package/skills/Data Layer/DTO Mapping/SKILL.md +269 -0
  67. package/skills/Data Layer/DataStore/SKILL.md +264 -0
  68. package/skills/Data Layer/Database Versioning Strategy/SKILL.md +215 -0
  69. package/skills/Data Layer/Encrypted Database/SKILL.md +212 -0
  70. package/skills/Data Layer/File Storage/SKILL.md +247 -0
  71. package/skills/Data Layer/Indexing/SKILL.md +184 -0
  72. package/skills/Data Layer/Key-Value Store Strategy/SKILL.md +185 -0
  73. package/skills/Data Layer/Merge Strategy/SKILL.md +240 -0
  74. package/skills/Data Layer/Migration/SKILL.md +243 -0
  75. package/skills/Data Layer/Paging/SKILL.md +264 -0
  76. package/skills/Data Layer/Proto DataStore/SKILL.md +250 -0
  77. package/skills/Data Layer/Room/SKILL.md +244 -0
  78. package/skills/Data Layer/SQLite/SKILL.md +255 -0
  79. package/skills/Data Layer/Sync Engine/SKILL.md +268 -0
  80. package/skills/Dependency Injection/Dagger/SKILL.md +283 -0
  81. package/skills/Dependency Injection/Hilt/SKILL.md +345 -0
  82. package/skills/Dependency Injection/Koin/SKILL.md +282 -0
  83. package/skills/Developer Experience/Detekt/SKILL.md +272 -0
  84. package/skills/Developer Experience/Lint Rule/SKILL.md +281 -0
  85. package/skills/Google Ecosystem/Analytics/SKILL.md +281 -0
  86. package/skills/Google Ecosystem/Crashlytics/SKILL.md +234 -0
  87. package/skills/Google Ecosystem/Firebase/SKILL.md +200 -0
  88. package/skills/Google Ecosystem/Firebase Messaging/SKILL.md +266 -0
  89. package/skills/Media/Audio/SKILL.md +257 -0
  90. package/skills/Media/Camera/SKILL.md +229 -0
  91. package/skills/Media/CameraX/SKILL.md +295 -0
  92. package/skills/Media/ExoPlayer/SKILL.md +258 -0
  93. package/skills/Media/Video/SKILL.md +228 -0
  94. package/skills/Meta Skills/Domain Error Model/SKILL.md +238 -0
  95. package/skills/Meta Skills/Error Handling/SKILL.md +255 -0
  96. package/skills/Meta Skills/Error Mapping/SKILL.md +232 -0
  97. package/skills/Meta Skills/Failure Strategy/SKILL.md +294 -0
  98. package/skills/Meta Skills/Migration Strategy/SKILL.md +305 -0
  99. package/skills/Meta Skills/User Friendly Errors/SKILL.md +334 -0
  100. package/skills/Navigation/Deep Navigation/SKILL.md +209 -0
  101. package/skills/Navigation/Navigation/SKILL.md +215 -0
  102. package/skills/Navigation/Nested Navigation/SKILL.md +214 -0
  103. package/skills/Networking/API Contract/SKILL.md +220 -0
  104. package/skills/Networking/Authentication/SKILL.md +210 -0
  105. package/skills/Networking/Certificate Pinning/SKILL.md +167 -0
  106. package/skills/Networking/Fallback Strategy/SKILL.md +182 -0
  107. package/skills/Networking/Ktor/SKILL.md +219 -0
  108. package/skills/Networking/Multipart Upload/SKILL.md +213 -0
  109. package/skills/Networking/OkHttp/SKILL.md +193 -0
  110. package/skills/Networking/REST/SKILL.md +178 -0
  111. package/skills/Networking/Rate Limiting/SKILL.md +170 -0
  112. package/skills/Networking/Retrofit/SKILL.md +241 -0
  113. package/skills/Networking/Retry-Backoff/SKILL.md +181 -0
  114. package/skills/Networking/Server-Sent Events (SSE)/SKILL.md +196 -0
  115. package/skills/Networking/WebSocket/SKILL.md +224 -0
  116. package/skills/Observability/Crash Reporting/SKILL.md +219 -0
  117. package/skills/Observability/Logging/SKILL.md +168 -0
  118. package/skills/Observability/Metrics/SKILL.md +227 -0
  119. package/skills/Observability/Structured Logging/SKILL.md +234 -0
  120. package/skills/Performance/ANR Prevention/SKILL.md +192 -0
  121. package/skills/Performance/Allocation Optimization/SKILL.md +179 -0
  122. package/skills/Performance/App Startup/SKILL.md +183 -0
  123. package/skills/Performance/Baseline Profile/SKILL.md +205 -0
  124. package/skills/Performance/Battery Optimization/SKILL.md +192 -0
  125. package/skills/Performance/Benchmark/SKILL.md +182 -0
  126. package/skills/Performance/Bitmap Optimization/SKILL.md +178 -0
  127. package/skills/Performance/Compose Optimization/SKILL.md +187 -0
  128. package/skills/Performance/Heap Management/SKILL.md +184 -0
  129. package/skills/Performance/Macrobenchmark/SKILL.md +214 -0
  130. package/skills/Performance/Memory Leak Prevention/SKILL.md +218 -0
  131. package/skills/Performance/Rendering Performance/SKILL.md +205 -0
  132. package/skills/Performance/Startup Optimization/SKILL.md +219 -0
  133. package/skills/Security/Biometric/SKILL.md +224 -0
  134. package/skills/Security/Certificate Transparency/SKILL.md +158 -0
  135. package/skills/Security/Cryptography/SKILL.md +244 -0
  136. package/skills/Security/Encrypted Storage/SKILL.md +273 -0
  137. package/skills/Security/Frida Detection/SKILL.md +230 -0
  138. package/skills/Security/Hook Detection/SKILL.md +197 -0
  139. package/skills/Security/Keystore/SKILL.md +272 -0
  140. package/skills/Security/Network Security Config/SKILL.md +186 -0
  141. package/skills/Security/Obfuscation/SKILL.md +226 -0
  142. package/skills/Security/Proguard/SKILL.md +202 -0
  143. package/skills/Security/R8/SKILL.md +234 -0
  144. package/skills/Security/Reverse Engineering Resistance/SKILL.md +267 -0
  145. package/skills/Security/Root Detection/SKILL.md +220 -0
  146. package/skills/Security/Secure Networking/SKILL.md +220 -0
  147. package/skills/System Integration/AlarmManager/SKILL.md +182 -0
  148. package/skills/System Integration/App Widget/SKILL.md +182 -0
  149. package/skills/System Integration/Deep Link/SKILL.md +187 -0
  150. package/skills/System Integration/Foreground Service/SKILL.md +212 -0
  151. package/skills/System Integration/Notification/SKILL.md +237 -0
  152. package/skills/System Integration/WorkManager/SKILL.md +256 -0
  153. package/skills/System Integration/clipboard/SKILL.md +155 -0
  154. package/skills/System Integration/share-intent/SKILL.md +182 -0
  155. package/skills/Testing/Compose Testing/SKILL.md +296 -0
  156. package/skills/Testing/Espresso/SKILL.md +292 -0
  157. package/skills/Testing/Fake Data/SKILL.md +245 -0
  158. package/skills/Testing/Integration Testing/SKILL.md +288 -0
  159. package/skills/Testing/Mocking/SKILL.md +229 -0
  160. package/skills/Testing/Snapshot Testing/SKILL.md +259 -0
  161. package/skills/Testing/UI Testing/SKILL.md +293 -0
  162. package/skills/Testing/Unit Testing/SKILL.md +309 -0
  163. package/skills/UI System/Bottom Sheet Patterns/SKILL.md +279 -0
  164. package/skills/UI System/Compose/SKILL.md +296 -0
  165. package/skills/UI System/Compose Animation/SKILL.md +281 -0
  166. package/skills/UI System/Compose Multiplatform/SKILL.md +261 -0
  167. package/skills/UI System/Compose Navigation/SKILL.md +255 -0
  168. package/skills/UI System/Compose Performance/SKILL.md +274 -0
  169. package/skills/UI System/Design System/SKILL.md +217 -0
  170. package/skills/UI System/Empty State Strategy/SKILL.md +208 -0
  171. package/skills/UI System/Keyboard Navigation/SKILL.md +214 -0
  172. package/skills/UI System/Loading Strategy/SKILL.md +254 -0
  173. package/skills/UI System/Material 3/SKILL.md +279 -0
  174. package/skills/UI System/RTL/SKILL.md +179 -0
  175. package/src/index.ts +182 -0
  176. package/tsconfig.json +19 -0
@@ -0,0 +1,306 @@
1
+ ---
2
+ name: jni
3
+ description: >
4
+ Java Native Interface (JNI) for Android — calling native C/C++ code from Kotlin.
5
+ Load this skill when bridging Kotlin and native code, declaring native methods,
6
+ handling JNI types, managing memory across the JNI boundary,
7
+ or passing complex objects between Kotlin and C/C++.
8
+ ---
9
+
10
+ # JNI
11
+
12
+ ## Overview
13
+ JNI (Java Native Interface) is the bridge between Kotlin/Java code and native C/C++ code in Android. It allows calling C/C++ functions from Kotlin and vice versa. JNI is used for performance-critical code, hardware access, reusing existing C/C++ libraries, or code that must resist reverse engineering.
14
+
15
+ ---
16
+
17
+ ## Core Principles
18
+
19
+ - **Minimize JNI boundary crossings** — each call has overhead; batch operations
20
+ - **JNI calls are synchronous** — run on the calling thread; use coroutines/threads on the Kotlin side
21
+ - **Memory is manual in native code** — no GC; always release resources
22
+ - **JNI types map to Java types** — `jstring` not `String`, `jint` not `Int`
23
+ - **Avoid storing JNI objects across calls** — use Global References when needed
24
+
25
+ ---
26
+
27
+ ## Basic Setup
28
+
29
+ ```kotlin
30
+ // build.gradle.kts
31
+ android {
32
+ defaultConfig {
33
+ externalNativeBuild {
34
+ cmake {
35
+ cppFlags("-std=c++17", "-O2")
36
+ }
37
+ }
38
+ }
39
+ externalNativeBuild {
40
+ cmake {
41
+ path("src/main/cpp/CMakeLists.txt")
42
+ version("3.22.1")
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ ```cmake
49
+ # src/main/cpp/CMakeLists.txt
50
+ cmake_minimum_required(VERSION 3.22.1)
51
+ project("myapp")
52
+
53
+ add_library(
54
+ myapp-native
55
+ SHARED
56
+ native_lib.cpp
57
+ )
58
+
59
+ find_library(log-lib log)
60
+
61
+ target_link_libraries(
62
+ myapp-native
63
+ ${log-lib}
64
+ )
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Declaring Native Methods
70
+
71
+ ```kotlin
72
+ // ✅ Kotlin side — declare native functions
73
+ class NativeCrypto {
74
+ external fun encrypt(data: ByteArray, key: ByteArray): ByteArray
75
+ external fun decrypt(data: ByteArray, key: ByteArray): ByteArray
76
+ external fun generateKey(): ByteArray
77
+
78
+ companion object {
79
+ init {
80
+ System.loadLibrary("myapp-native")
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ```cpp
87
+ // ✅ C++ side — implement with JNI naming convention
88
+ // Package: com.example.app.security
89
+ // Class: NativeCrypto
90
+ // Function name format: Java_<package>_<class>_<method>
91
+
92
+ #include <jni.h>
93
+ #include <string>
94
+
95
+ extern "C" {
96
+
97
+ JNIEXPORT jbyteArray JNICALL
98
+ Java_com_example_app_security_NativeCrypto_encrypt(
99
+ JNIEnv* env,
100
+ jobject /* this */,
101
+ jbyteArray data,
102
+ jbyteArray key
103
+ ) {
104
+ // Get data from Java
105
+ jsize dataLen = env->GetArrayLength(data);
106
+ jbyte* dataBytes = env->GetByteArrayElements(data, nullptr);
107
+ jbyte* keyBytes = env->GetByteArrayElements(key, nullptr);
108
+
109
+ // Perform encryption (simplified)
110
+ jbyteArray result = env->NewByteArray(dataLen);
111
+ jbyte* resultBytes = env->GetByteArrayElements(result, nullptr);
112
+
113
+ for (jsize i = 0; i < dataLen; i++) {
114
+ resultBytes[i] = dataBytes[i] ^ keyBytes[i % env->GetArrayLength(key)];
115
+ }
116
+
117
+ // ✅ Always release elements
118
+ env->ReleaseByteArrayElements(data, dataBytes, JNI_ABORT);
119
+ env->ReleaseByteArrayElements(key, keyBytes, JNI_ABORT);
120
+ env->ReleaseByteArrayElements(result, resultBytes, 0); // 0 = copy back + free
121
+
122
+ return result;
123
+ }
124
+
125
+ } // extern "C"
126
+ ```
127
+
128
+ ---
129
+
130
+ ## JNI Type Mapping
131
+
132
+ | Kotlin/Java | JNI Type | Array Type |
133
+ |---|---|---|
134
+ | `Boolean` | `jboolean` | `jbooleanArray` |
135
+ | `Int` | `jint` | `jintArray` |
136
+ | `Long` | `jlong` | `jlongArray` |
137
+ | `Float` | `jfloat` | `jfloatArray` |
138
+ | `Double` | `jdouble` | `jdoubleArray` |
139
+ | `Byte` | `jbyte` | `jbyteArray` |
140
+ | `String` | `jstring` | — |
141
+ | `Object` | `jobject` | `jobjectArray` |
142
+ | `void` | `void` | — |
143
+
144
+ ---
145
+
146
+ ## Handling Strings
147
+
148
+ ```cpp
149
+ // ✅ Convert jstring to std::string
150
+ std::string jstringToString(JNIEnv* env, jstring jStr) {
151
+ if (jStr == nullptr) return "";
152
+ const char* chars = env->GetStringUTFChars(jStr, nullptr);
153
+ std::string result(chars);
154
+ env->ReleaseStringUTFChars(jStr, chars); // ✅ always release
155
+ return result;
156
+ }
157
+
158
+ // ✅ Convert std::string to jstring
159
+ jstring stringToJstring(JNIEnv* env, const std::string& str) {
160
+ return env->NewStringUTF(str.c_str());
161
+ }
162
+
163
+ JNIEXPORT jstring JNICALL
164
+ Java_com_example_app_NativeUtils_processText(
165
+ JNIEnv* env, jobject, jstring input
166
+ ) {
167
+ std::string text = jstringToString(env, input);
168
+ std::string result = /* process */ text + "_processed";
169
+ return stringToJstring(env, result);
170
+ }
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Global References (Persistent JNI Objects)
176
+
177
+ ```cpp
178
+ // ✅ Use Global Reference to hold a Java object across JNI calls
179
+ static jobject gCallback = nullptr;
180
+
181
+ JNIEXPORT void JNICALL
182
+ Java_com_example_app_NativeLib_registerCallback(
183
+ JNIEnv* env, jobject, jobject callback
184
+ ) {
185
+ // ✅ Delete old reference if exists
186
+ if (gCallback != nullptr) {
187
+ env->DeleteGlobalRef(gCallback);
188
+ }
189
+ // ✅ Create global reference — survives across JNI calls
190
+ gCallback = env->NewGlobalRef(callback);
191
+ }
192
+
193
+ JNIEXPORT void JNICALL
194
+ Java_com_example_app_NativeLib_unregisterCallback(
195
+ JNIEnv* env, jobject
196
+ ) {
197
+ if (gCallback != nullptr) {
198
+ env->DeleteGlobalRef(gCallback);
199
+ gCallback = nullptr;
200
+ }
201
+ }
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Calling Kotlin from C++ (Callbacks)
207
+
208
+ ```cpp
209
+ // ✅ Call a Kotlin method from native code
210
+ void callKotlinCallback(JNIEnv* env, jobject callback, int progress) {
211
+ jclass callbackClass = env->GetObjectClass(callback);
212
+
213
+ // Find the method: void onProgress(int progress)
214
+ jmethodID onProgressMethod = env->GetMethodID(
215
+ callbackClass,
216
+ "onProgress",
217
+ "(I)V" // method signature: (int) returns void
218
+ );
219
+
220
+ if (onProgressMethod != nullptr) {
221
+ env->CallVoidMethod(callback, onProgressMethod, (jint)progress);
222
+ }
223
+ env->DeleteLocalRef(callbackClass);
224
+ }
225
+ ```
226
+
227
+ ---
228
+
229
+ ## JNI Method Signatures
230
+
231
+ ```
232
+ Type Signature
233
+ void V
234
+ boolean Z
235
+ byte B
236
+ char C
237
+ short S
238
+ int I
239
+ long J
240
+ float F
241
+ double D
242
+ String Ljava/lang/String;
243
+ int[] [I
244
+ Object Ljava/lang/Object;
245
+
246
+ Method: void foo(int, String) → (ILjava/lang/String;)V
247
+ Method: int bar(byte[]) → ([B)I
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Error Handling
253
+
254
+ ```cpp
255
+ // ✅ Check for exceptions after calling Java methods
256
+ env->CallVoidMethod(obj, method, arg);
257
+ if (env->ExceptionCheck()) {
258
+ env->ExceptionDescribe(); // prints to logcat
259
+ env->ExceptionClear();
260
+ // handle error
261
+ return nullptr;
262
+ }
263
+
264
+ // ✅ Throw a Java exception from native code
265
+ void throwException(JNIEnv* env, const char* message) {
266
+ jclass exceptionClass = env->FindClass("java/lang/RuntimeException");
267
+ if (exceptionClass != nullptr) {
268
+ env->ThrowNew(exceptionClass, message);
269
+ env->DeleteLocalRef(exceptionClass);
270
+ }
271
+ }
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Logging from Native Code
277
+
278
+ ```cpp
279
+ #include <android/log.h>
280
+
281
+ #define TAG "NativeLib"
282
+ #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
283
+ #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
284
+
285
+ // Usage
286
+ LOGI("Processing %d bytes", dataLen);
287
+ LOGE("Encryption failed: %s", errorMsg);
288
+ ```
289
+
290
+ ---
291
+
292
+ ## Anti-Patterns
293
+
294
+ - Not releasing `GetByteArrayElements` / `GetStringUTFChars` — memory leak
295
+ - Storing `JNIEnv*` across threads — `JNIEnv` is thread-local; each thread needs its own
296
+ - Using Local References after the JNI call returns — they become invalid
297
+ - Crossing the JNI boundary on every frame — batch operations; minimize round-trips
298
+ - Forgetting `extern "C"` in C++ files — C++ name mangling breaks JNI lookup
299
+
300
+ ---
301
+
302
+ ## Related Skills
303
+ - `ndk` — NDK build system and toolchain setup
304
+ - `c++` — C++ patterns for Android native code
305
+ - `cryptography` — using JNI for native crypto implementations
306
+ - `reverse-engineering-resistance` — native code as a hardening technique
@@ -0,0 +1,264 @@
1
+ ---
2
+ name: ndk
3
+ description: >
4
+ Android NDK build system, toolchain, and project setup.
5
+ Load this skill when configuring the NDK version, setting up CMake
6
+ or ndk-build, managing ABI splits, linking third-party native libraries,
7
+ debugging native crashes, or configuring native build flags.
8
+ ---
9
+
10
+ # NDK
11
+
12
+ ## Overview
13
+ The Android NDK (Native Development Kit) provides the toolchain for compiling C/C++ code into native libraries (`.so` files) that run on Android. It includes the compiler (Clang), standard libraries, Android-specific headers, and the build system integration with Gradle via CMake or ndk-build.
14
+
15
+ ---
16
+
17
+ ## Core Principles
18
+
19
+ - **Pin the NDK version** in `build.gradle.kts` — NDK updates can break builds
20
+ - **CMake is preferred** over ndk-build for new projects — better IDE support
21
+ - **ABI filters** reduce APK size — only include the ABIs your app supports
22
+ - **STL selection** matters — use `c++_shared` for shared libraries, `c++_static` for single `.so`
23
+ - **Symbols** — strip debug symbols from release builds for size; keep for crash analysis
24
+
25
+ ---
26
+
27
+ ## Gradle Setup
28
+
29
+ ```kotlin
30
+ // app/build.gradle.kts
31
+ android {
32
+ ndkVersion = "26.1.10909125" // ✅ pin exact version
33
+
34
+ defaultConfig {
35
+ externalNativeBuild {
36
+ cmake {
37
+ cppFlags("-std=c++17", "-fexceptions", "-frtti")
38
+ arguments(
39
+ "-DANDROID_STL=c++_shared",
40
+ "-DANDROID_PLATFORM=android-26"
41
+ )
42
+ }
43
+ }
44
+
45
+ // ✅ Only build for ABIs you support
46
+ ndk {
47
+ abiFilters += listOf("arm64-v8a", "x86_64") // drop x86 for production
48
+ }
49
+ }
50
+
51
+ externalNativeBuild {
52
+ cmake {
53
+ path("src/main/cpp/CMakeLists.txt")
54
+ version("3.22.1")
55
+ }
56
+ }
57
+
58
+ // ✅ Split APKs by ABI (Play Store handles delivery)
59
+ splits {
60
+ abi {
61
+ isEnable = true
62
+ reset()
63
+ include("arm64-v8a", "armeabi-v7a", "x86_64")
64
+ isUniversalApk = false
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ ---
71
+
72
+ ## CMakeLists.txt — Full Example
73
+
74
+ ```cmake
75
+ cmake_minimum_required(VERSION 3.22.1)
76
+ project("myapp" VERSION 1.0.0)
77
+
78
+ # ✅ Set C++ standard
79
+ set(CMAKE_CXX_STANDARD 17)
80
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
81
+
82
+ # ✅ Source files
83
+ set(SOURCES
84
+ src/native_lib.cpp
85
+ src/crypto/aes_gcm.cpp
86
+ src/utils/string_utils.cpp
87
+ )
88
+
89
+ # ✅ Create shared library
90
+ add_library(myapp-native SHARED ${SOURCES})
91
+
92
+ # ✅ Find Android system libraries
93
+ find_library(log-lib log)
94
+ find_library(android-lib android)
95
+
96
+ # ✅ Include headers
97
+ target_include_directories(myapp-native PRIVATE
98
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
99
+ )
100
+
101
+ # ✅ Link libraries
102
+ target_link_libraries(myapp-native
103
+ ${log-lib}
104
+ ${android-lib}
105
+ )
106
+
107
+ # ✅ Compiler flags
108
+ target_compile_options(myapp-native PRIVATE
109
+ -Wall
110
+ -Wextra
111
+ -O2
112
+ $<$<CONFIG:Debug>:-g>
113
+ $<$<CONFIG:Release>:-Os -fvisibility=hidden>
114
+ )
115
+
116
+ # ✅ Strip symbols in release (reduces .so size)
117
+ set_target_properties(myapp-native PROPERTIES
118
+ $<$<CONFIG:Release>:LINK_FLAGS "-Wl,--strip-all">
119
+ )
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Linking Pre-built Libraries
125
+
126
+ ```cmake
127
+ # ✅ Link a pre-built .so from a third-party SDK
128
+ add_library(third-party-lib SHARED IMPORTED)
129
+ set_target_properties(third-party-lib PROPERTIES
130
+ IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libthirdparty.so
131
+ )
132
+
133
+ target_link_libraries(myapp-native
134
+ third-party-lib
135
+ ${log-lib}
136
+ )
137
+
138
+ # ✅ Copy the .so to jniLibs so it's packaged in the APK
139
+ # Place in: src/main/jniLibs/<abi>/libthirdparty.so
140
+ ```
141
+
142
+ ---
143
+
144
+ ## ABI Reference
145
+
146
+ | ABI | Architecture | Notes |
147
+ |---|---|---|
148
+ | `arm64-v8a` | 64-bit ARM | Most modern Android devices |
149
+ | `armeabi-v7a` | 32-bit ARM | Older devices; still ~15% of installs |
150
+ | `x86_64` | 64-bit x86 | Emulators, some Chrome OS |
151
+ | `x86` | 32-bit x86 | Legacy emulators; safe to drop |
152
+
153
+ ```kotlin
154
+ // ✅ Production — include arm64-v8a + armeabi-v7a for device coverage
155
+ ndk { abiFilters += listOf("arm64-v8a", "armeabi-v7a") }
156
+
157
+ // ✅ During development — add x86_64 for emulator
158
+ ndk { abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64") }
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Debugging Native Crashes (Tombstones)
164
+
165
+ ```bash
166
+ # ✅ Symbolicate a native crash from logcat
167
+ # The crash shows: #00 pc 0000abcd /data/app/.../libmyapp.so
168
+
169
+ # 1. Find your .so with debug symbols (from build/intermediates/)
170
+ # 2. Use ndk-stack:
171
+ adb logcat | ndk-stack -sym app/build/intermediates/cmake/debug/obj/arm64-v8a/
172
+
173
+ # ✅ Or use addr2line to decode a single address
174
+ $NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-addr2line \
175
+ -e libmyapp.so \
176
+ 0x0000abcd
177
+
178
+ # ✅ Use Android Studio's LLDB debugger for live native debugging
179
+ # Run/Debug Configurations → Debugger → Debug type: Dual
180
+ ```
181
+
182
+ ---
183
+
184
+ ## Accessing Android APIs from Native Code
185
+
186
+ ```cpp
187
+ // ✅ Android-specific native APIs
188
+ #include <android/asset_manager.h>
189
+ #include <android/asset_manager_jni.h>
190
+ #include <android/log.h>
191
+ #include <android/bitmap.h>
192
+ #include <GLES3/gl3.h> // OpenGL ES 3.0
193
+ #include <EGL/egl.h>
194
+
195
+ // ✅ Read asset from native code
196
+ JNIEXPORT jbyteArray JNICALL
197
+ Java_com_example_NativeAssets_readAsset(
198
+ JNIEnv* env, jobject,
199
+ jobject assetManager, jstring filename
200
+ ) {
201
+ AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
202
+ const char* file = env->GetStringUTFChars(filename, nullptr);
203
+
204
+ AAsset* asset = AAssetManager_open(mgr, file, AASSET_MODE_BUFFER);
205
+ env->ReleaseStringUTFChars(filename, file);
206
+
207
+ if (asset == nullptr) return nullptr;
208
+
209
+ off_t size = AAsset_getLength(asset);
210
+ jbyteArray result = env->NewByteArray(size);
211
+ jbyte* buf = env->GetByteArrayElements(result, nullptr);
212
+ AAsset_read(asset, buf, size);
213
+ AAsset_close(asset);
214
+
215
+ env->ReleaseByteArrayElements(result, buf, 0);
216
+ return result;
217
+ }
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Build Variants for Native
223
+
224
+ ```kotlin
225
+ // ✅ Different native flags per build type
226
+ android {
227
+ buildTypes {
228
+ debug {
229
+ externalNativeBuild {
230
+ cmake {
231
+ cppFlags("-DDEBUG_BUILD", "-g")
232
+ arguments("-DCMAKE_BUILD_TYPE=Debug")
233
+ }
234
+ }
235
+ }
236
+ release {
237
+ externalNativeBuild {
238
+ cmake {
239
+ cppFlags("-DNDEBUG", "-O2", "-fvisibility=hidden")
240
+ arguments("-DCMAKE_BUILD_TYPE=Release")
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Anti-Patterns
251
+
252
+ - Not pinning `ndkVersion` — CI builds may use different NDK than local builds
253
+ - Building for all 4 ABIs — `x86` is dead; `x86_64` only needed for emulators
254
+ - `c++_static` STL with multiple `.so` files — causes ODR violations and crashes
255
+ - Storing debug `.so` in the release APK — exposes symbols; strip in release
256
+ - Not checking `env->ExceptionCheck()` after calling back into Java — silent crashes
257
+
258
+ ---
259
+
260
+ ## Related Skills
261
+ - `jni` — JNI bridge between Kotlin and native code
262
+ - `c++` — C++ patterns for native Android code
263
+ - `gradle` — Gradle build configuration
264
+ - `reverse-engineering-resistance` — native code hardening