Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Painless Libraries - Londroid April 2019
Search
Sérgio Marques Moura
April 16, 2019
Programming
130
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Painless Libraries - Londroid April 2019
Sérgio Marques Moura
April 16, 2019
More Decks by Sérgio Marques Moura
See All by Sérgio Marques Moura
Go Native: Integrating Native Code on Android
sergiomarquesmoura
0
29
AndroidLX: From an app to a library
sergiomarquesmoura
2
49
Android Lx - 25 Jan 2017 - RxJava: More than the basic
sergiomarquesmoura
0
96
AndKotlin
sergiomarquesmoura
0
42
Other Decks in Programming
See All in Programming
技術記事、 専門家としてのプログラマ、 言語化
mizchi
13
7.2k
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
280
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.1k
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
820
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
220
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
180
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
180
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
200
The Bowling Game- From Imperative to Functional Programming - Part 1
philipschwarz
PRO
0
190
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
330
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
450
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
96
14k
How to Think Like a Performance Engineer
csswizardry
28
2.7k
Mind Mapping
helmedeiros
PRO
1
270
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
240
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
55k
Embracing the Ebb and Flow
colly
88
5.1k
Docker and Python
trallard
47
3.9k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
240
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
170
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Transcript
@sergiomarqmoura
Who here develops Android libraries…?
Who here develops Android libraries...to be used by external applications?
onfido-android-sdk ├── build.gradle ├── gradle.properties ├── proguard-rules.pro ├── src ├──
main │ ├── AndroidManifest.xml │ ├── java │ └── res └── test
onfido-android-sdk └── build.gradle
onfido-android-sdk └── build.gradle ├── resources name prefix
onfido-android-sdk └── src ├── main └── res ├── drawable ├──
logo.xml ├── layout ├── activity_camera.xml app └── src ├── main └── res ├── drawable ├── logo.xml ├── layout ├── activity_camera.xml
onfido-android-sdk app logo.xml logo.xml <ImageView android:id="@+id/logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/logo"/>
onfido-android-sdk app activity_camera.xml activity_camera.xml <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.onfido.android.sdk.capture.ui.camera.CameraView android:id="@+id/cameraView"
android:layout_width="match_parent" android:layout_height="match_parent"/> ... </androidx.coordinatorlayout.widget.CoordinatorLayout> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/logo"/> ... </androidx.coordinatorlayout.widget.CoordinatorLayout> import kotlinx.android.synthetic.main.activity_camera.* cameraView.start() java.lang.NoSuchFieldError: com.onfido.android.sdk.capture.R$id.cameraView
• android { /* Enables IDE warning if non-prefixed resource
is defined. Code still compiles. Allowed names: - onfidoResource - onfido_resource - OnfidoResource */ resourcePrefix 'onfido' } • lintOptions { lintConfig rootProject.file("lint-rules.xml") abortOnError true } lint-rules-xml <lint> <issue id="ResourceName" severity="error" /> ... <issue id="NewApi" severity="warning" /> <issue id="MissingTranslation" severity="warning" /> </lint> ./gradlew onfido-android-sdk:lint
onfido-android-sdk └── build.gradle ├── bundled Proguard rules ├── resources name
prefix ├── size impact
• ◦ ◦ ▪ ◦ ▪ ▪ dependencies { implementation
"com.onfido.sdk.capture:onfido-capture-sdk:4.8.0" } ./gradlew app:assembleRelease; ls -lh app/build/outputs/apk/release/
• ◦ ◦ // host application build.gradle splits { abi
{ enable true reset() include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' universalApk true //generate an additional APK that contains all the ABIs } } AndroidX build artifacts androidx.core:core:1.0.0 androidx.recyclerview:recyclerview:1.0.0 androidx.constraintlayout:constraintlayout:1.0.0 androidx.lifecycle:lifecycle-livedata:1.0.0 dependencies { implementation 'com.onfido.sdk.capture:onfido-capture-sdk:4.8.0' // OR implementation 'com.onfido.sdk.capture:onfido-capture-sdk-core:4.8.0' (-48% size) }
onfido-android-sdk └── build.gradle ├── bundled Proguard rules ├── resources name
prefix ├── size impact ├── dependencies
• // library implementation 'com.onfido:sample-lib:4.0.0' // app implementation 'com.onfido:sample-lib:4.0.0' ◦
▪ ◦ ▪ ▪ // library implementation 'com.onfido:sample-lib:4.0.0' // app implementation 'com.onfido:sample-lib:3.0.0'
• // library implementation 'com.google.dagger:dagger:2.22' // app implementation 'com.squareup:dagger:1.2.5' com.android.build.api.transform.TransformException:
com.android.dex.DexException: Multiple dex files define Ldagger/MembersInjector • •
class MyApplication : Application() { override fun onCreate() { super.onCreate()
AnalyticsLib.init(this, "APP_TOKEN") SampleLib.init(this) } } • class SampleLib { companion object { @JvmStatic fun init(context: Context) { AnalyticsLib.init(context, "LIBRARY_TOKEN") } } } • AnalyticsLib • AnalyticsLib • AnalyticsLib fun track(eventName: String) { AnalyticsLib.getInstance().track(eventName) }
• ◦ com.samplelib.AnalyticsLib -> com.onfido.samplelib.AnalyticsLib com.samplelib.AnalyticsLib.init(context, "TOKEN") =/= com.onfido.samplelib.AnalyticsLib.init(context, "TOKEN")
◦ ◦ buildscript { dependencies { classpath 'ru.tinkoff.gradle:jarjar:1.1.0' classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.1' } } apply plugin: 'ru.tinkoff.gradle.jarjar' apply plugin: 'com.github.johnrengelman.shadow'
jarJar { rules = [ “analyticsLib-$version.jar” : 'com.samplelib.** com.onfido.samplelib.@1' ]
} dependencies { jarJar "com.samplelib:analytics:$version" implementation files("build/libs/analytics-$version.jar") } ◦ ◦ $version LICENSE.md
onfido-android-sdk ├── build.gradle │ ├── bundled Proguard rules │ ├──
resources name prefix │ ├── size impact │ ├── dependencies ├── src │ ├── main │ │ ├── AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.onfido.android.sdk.capture"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> <application>
<activity android:name=".ui.OnfidoActivity" android:label="@string/onfido_activity_label" android:theme="@style/OnfidoActivityTheme" /> </application> </manifest> java.lang.IllegalArgumentException: either category or name must be provided.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.onfido.android.sdk.capture"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> <application>
<provider android:name=".OnfidoInitProvider" android:authorities="${applicationId}.onfidoinitprovider" android:enabled="true" android:exported="false"/> <activity android:name=".ui.OnfidoActivity" android:label="@string/onfido_activity_label" android:theme="@style/OnfidoActivityTheme" /> </application> </manifest>
class MyApplication : Application() { override fun onCreate() { super.onCreate()
SampleLib.init(this) } } class OnfidoInitProvider extends ContentProvider { override fun onCreate(): Boolean { SampleLib.init(context); return false; } } • ◦ ◦ • ◦ ◦
onfido-android-sdk ├── build.gradle │ ├── bundled Proguard rules │ ├──
resources name prefix │ ├── size impact │ ├── dependencies ├── src │ ├── main │ │ ├── AndroidManifest.xml ├── java ├── res
• google-services.json ❖ firebase-auth ❖ firebase-messaging ❖ firebase-* { "project_info":
{ "project_number": "PROJECT_NUMBER", "firebase_url": "FIREBASE_URL", "project_id": "PROJECT_ID", "storage_bucket": "STORAGE_BUCKET" }, "client": [ { "client_info": { "mobilesdk_app_id": "MOBILE_SDK_APP_ID", "android_client_info": { "package_name": "PACKAGE_NAME" } }, "api_key": [ { "current_key": "KEY" } ], "services": { "analytics_service": { "status": 1 } } } ], "configuration_version": "CONFIGURATION_VERSION" } <string name="google_api_key">API_KEY</string> <string name="google_app_id">APPLICATION_ID</string> <string name="google_storage_bucket">STORAGE_BUCKET</string> <string name="firebase_database_url">FIREBASE_URL</string> <string name="project_id">PROJECT_ID</string> try { FirebaseApp.initializeApp(context, FirebaseOptions.Builder() .setApiKey("API_KEY") .setApplicationId("APPLICATION_ID") .build(), "PACKAGE_NAME") } catch (e: IllegalStateException) { // fallback code }
Thank you! Q&A