Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Painless Libraries - Londroid April 2019
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
31
AndroidLX: From an app to a library
sergiomarquesmoura
2
51
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
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
400
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
5.2k
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
130
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
340
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
190
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
370
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
160
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
510
Heart of Swift Concurrency
koher
0
1.1k
AWSに止められる覚悟してますか?
morizo_1984
2
490
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
130
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
280
Featured
See All Featured
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
The SEO Collaboration Effect
kristinabergwall1
1
580
So, you think you're a good person
axbom
PRO
2
2.2k
[SF Ruby Conf 2025] Rails X
palkan
3
1.4k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
560
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
710
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
Raft: Consensus for Rubyists
vanstee
142
7.7k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.7k
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