Slide 1

Slide 1 text

G E T S T R E A M . I O Becoming an Android Librarian

Slide 2

Slide 2 text

G E T S T R E A M . I O skydoves @github_skydoves Android Developer Advocate @ Stream Jaewoong Eum

Slide 3

Slide 3 text

G E T S T R E A M . I O Open-Source Libraries

Slide 4

Slide 4 text

G E T S T R E A M . I O Open-Source Libraries

Slide 5

Slide 5 text

G E T S T R E A M . I O Library & SDK Lifecycles Design Develop Prepare Release

Slide 6

Slide 6 text

G E T S T R E A M . I O Library & SDK Lifecycles Design Develop Prepare Release Design process

Slide 7

Slide 7 text

G E T S T R E A M . I O Library & SDK Lifecycles Design process 1. Define a problem 2. Research overall ideas 3. Verify the feasibility of your ideas 4. Investigate dependencies 5. Draw blueprints of application interfaces 6. Design the application interfaces

Slide 8

Slide 8 text

G E T S T R E A M . I O Library & SDK Lifecycles Design Develop Prepare Release Development strategies

Slide 9

Slide 9 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Module Public Interface

Slide 10

Slide 10 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Client Client Client Client

Slide 11

Slide 11 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Client Client Client Client

Slide 12

Slide 12 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Client Client Client Client

Slide 13

Slide 13 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Public Internal

Slide 14

Slide 14 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Client Client Client Client Public Internal

Slide 15

Slide 15 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Client Client Client Client

Slide 16

Slide 16 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces Client Client Client Client

Slide 17

Slide 17 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces private internal importance protected public

Slide 18

Slide 18 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces private internal importance protected public Client Client Client

Slide 19

Slide 19 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces class ApiResponseCallAdapter constructor( val resultType: Type ) : CallAdapter>> { override fun responseType(): Type { return resultType } override fun adapt(call: Call): Call> { return ApiResponseCallDelegate(call) } } Client

Slide 20

Slide 20 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces internal class ApiResponseCallAdapter constructor( private val resultType: Type ) : CallAdapter>> { override fun responseType(): Type { return resultType } override fun adapt(call: Call): Call> { return ApiResponseCallDelegate(call) } } Client

Slide 21

Slide 21 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces fun Context.dp2Px(dp: Int): Int { val scale = resources.displayMetrics.density return (dp * scale).toInt() } fun Context.px2Sp(px: Int): Int { val scale = resources.displayMetrics.scaledDensity return (px / scale).toInt() } val px = context.dp2Px(dp = 22) val sp = context.px2Sp(px = 22)

Slide 22

Slide 22 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces internal fun Context.dp2Px(dp: Int): Int { val scale = resources.displayMetrics.density return (dp * scale).toInt() } internal fun Context.px2Sp(px: Int): Int { val scale = resources.displayMetrics.scaledDensity return (px / scale).toInt() } val px = context.dp2Px(dp = 22) // Unresolved reference val sp = context.px2Sp(px = 22) // Unresolved reference

Slide 23

Slide 23 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces internal fun Context.dp2Px(dp: Int): Int { val scale = resources.displayMetrics.density return (dp * scale).toInt() } internal fun Context.px2Sp(px: Int): Int { val scale = resources.displayMetrics.scaledDensity return (px / scale).toInt() } int px = ContextExtensionKt.dp2Px(context, 11); int sp = ContextExtensionKt.px2Sp(context, 11);

Slide 24

Slide 24 text

G E T S T R E A M . I O Development Strategies Minimize API surfaces @JvmSynthetic internal fun Context.dp2Px(dp: Int): Int { val scale = resources.displayMetrics.density return (dp * scale).toInt() } @JvmSynthetic internal fun Context.px2Sp(px: Int): Int { val scale = resources.displayMetrics.scaledDensity return (px / scale).toInt() } int px = ContextExtensionKt.dp2Px(context, 11); // Unresolved reference int sp = ContextExtensionKt.px2Sp(context, 11); // Unresolved reference

Slide 25

Slide 25 text

G E T S T R E A M . I O Development Strategies Explicit API mode

Slide 26

Slide 26 text

G E T S T R E A M . I O Development Strategies Explicit API mode

Slide 27

Slide 27 text

G E T S T R E A M . I O Development Strategies Explicit API mode

Slide 28

Slide 28 text

G E T S T R E A M . I O Development Strategies Explicit API mode

Slide 29

Slide 29 text

G E T S T R E A M . I O Development Strategies Explicit API mode

Slide 30

Slide 30 text

G E T S T R E A M . I O Development Strategies Binary Compatibility Validator

Slide 31

Slide 31 text

G E T S T R E A M . I O Development Strategies Binary Compatibility Validator build.gradle module.gradle On terminal

Slide 32

Slide 32 text

G E T S T R E A M . I O Development Strategies Binary Compatibility Validator module.api

Slide 33

Slide 33 text

G E T S T R E A M . I O Development Strategies Binary Compatibility Validator

Slide 34

Slide 34 text

G E T S T R E A M . I O Development Strategies Metalava

Slide 35

Slide 35 text

G E T S T R E A M . I O Development Strategies Exposing resources /classes.jar /res/ /R.txt /public.txt /assets/ /libs/name.jar /jni/abi_name/name.so /proguard.txt /lint.jar /api.jar AAR file

Slide 36

Slide 36 text

G E T S T R E A M . I O Development Strategies Exposing resources /classes.jar /res/ /R.txt /public.txt /assets/ /libs/name.jar /jni/abi_name/name.so /proguard.txt /lint.jar /api.jar AAR file res/drawable res/layout res/menu res/values res/xml res/raw res/anim res/animator res/mipmap res/font string.xml colors.xml styles.xml dimens.xml arrays.xml … /res/ /res/values/

Slide 37

Slide 37 text

G E T S T R E A M . I O Development Strategies Exposing resources #FFFFFF #000000 #57A8D8 #FBC02D Library (colors.xml) Project val whiteColor = ContextCompat.getColor(this, R.color.white) binding.myView.setBackgroundColor(whiteColor)

Slide 38

Slide 38 text

G E T S T R E A M . I O Development Strategies Exposing resources #FFFFFF #000000 #57A8D8 #FBC02D Library (colors.xml) val whiteColor = ContextCompat.getColor(this, R.color.white) binding.myView.setBackgroundColor(whiteColor) Project compile error!

Slide 39

Slide 39 text

G E T S T R E A M . I O Development Strategies Exposing resources

Slide 40

Slide 40 text

G E T S T R E A M . I O Development Strategies Exposing resources

Slide 41

Slide 41 text

G E T S T R E A M . I O Development Strategies Exposing resources

Slide 42

Slide 42 text

G E T S T R E A M . I O Development Strategies Exposing resources Project (XML) Project (code)

Slide 43

Slide 43 text

G E T S T R E A M . I O Development Strategies Exposing resources Project (XML) Project (code)

Slide 44

Slide 44 text

G E T S T R E A M . I O Development Strategies Exposing resources

Slide 45

Slide 45 text

G E T S T R E A M . I O Development Strategies Exposing resources

Slide 46

Slide 46 text

G E T S T R E A M . I O Development Strategies Exposing resources Library (layout_balloon.xml) Library (Balloon.Builder.kt)

Slide 47

Slide 47 text

G E T S T R E A M . I O Development Strategies Exposing resources ● Some issues have been reported in Crashlytics. ● But the reports were not helpful at all. ● Occasionally the library behaves very weirdly. ● Also it’s really difficult to reproduce.

Slide 48

Slide 48 text

G E T S T R E A M . I O Development Strategies Exposing resources Perhaps..?

Slide 49

Slide 49 text

G E T S T R E A M . I O Development Strategies Exposing resources … Library (layout_balloon.xml) Project (layout_balloon.xml) ...

Slide 50

Slide 50 text

G E T S T R E A M . I O Development Strategies Exposing resources … Library (layout_balloon.xml) // wrong behaviors Project (layout_balloon.xml) // runtime error! ...

Slide 51

Slide 51 text

G E T S T R E A M . I O Development Strategies Resource prefix resourcePrefix

Slide 52

Slide 52 text

G E T S T R E A M . I O Development Strategies Resource prefix resourcePrefix

Slide 53

Slide 53 text

G E T S T R E A M . I O Development Strategies Resource prefix build.gradle

Slide 54

Slide 54 text

G E T S T R E A M . I O Development Strategies Resource prefix layout_balloon.xml attrs.xml

Slide 55

Slide 55 text

G E T S T R E A M . I O Development Strategies Resource prefix

Slide 56

Slide 56 text

G E T S T R E A M . I O Development Strategies R class Non transitive R class

Slide 57

Slide 57 text

G E T S T R E A M . I O Development Strategies Non transitive R class

Slide 58

Slide 58 text

G E T S T R E A M . I O Development Strategies Non transitive R class

Slide 59

Slide 59 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :library :material (MDC) implementation implementation

Slide 60

Slide 60 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :library :material (MDC) com.google.android.material.R (:material) implementation implementation

Slide 61

Slide 61 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :library :material (MDC) com.my.library.R (:material) (:library) com.google.android.material.R (:material) implementation implementation

Slide 62

Slide 62 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :library :material (MDC) com.my.library.R (:material) (:library) com.google.android.material.R (:material) com.my.app.R (:material) (:library) (:app) implementation implementation

Slide 63

Slide 63 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :library :material (MDC) Transitive dependency com.my.library.R (:material) (:library) com.google.android.material.R (:material) com.my.app.R (:material) (:library) (:app) implementation implementation

Slide 64

Slide 64 text

G E T S T R E A M . I O Development Strategies Non transitive R class com.my.library.R (:material) (:library)

Slide 65

Slide 65 text

G E T S T R E A M . I O Development Strategies Non transitive R class

Slide 66

Slide 66 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :library :material (MDC) implementation implementation com.my.library.R (:material) (:library) com.google.android.material.R (:material) com.my.app.R (:material) (:library) (:app) Wow, a million of LoC in R classes in a minute!

Slide 67

Slide 67 text

G E T S T R E A M . I O Development Strategies Non transitive R class Dex format has 64K limit for methods and fields references! 64K (65,536 = 64 x 1024 (2^10))

Slide 68

Slide 68 text

G E T S T R E A M . I O Development Strategies Non transitive R class

Slide 69

Slide 69 text

G E T S T R E A M . I O Development Strategies Non transitive R class android.nonTransitiveRClass=true gradle.properties

Slide 70

Slide 70 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :library implementation implementation com.my.library.R (:library) com.google.android.material.R (:material) com.my.app.R (:app) Refer to its own resources without pulling resources from dependencies. nonTransitiveRclass :material (MDC)

Slide 71

Slide 71 text

G E T S T R E A M . I O Development Strategies Non transitive R class Before After (enabled non transitive R class)

Slide 72

Slide 72 text

G E T S T R E A M . I O Development Strategies Non transitive R class aar size diff 226054 bytes -> 214538 bytes (11516 bytes reduced) 10,000 end-users 2260540000 bytes -> 2145380000 bytes (≈115 MB reduced) 100,000 end-users 22605400000 bytes -> 21453800000 bytes (≈1.1 GB reduced) 1,000,000 end-users 226054000000 bytes -> 214538000000 bytes (≈10 GB reduced) 100,000,000 end-users 22605400000000 bytes -> 21453800000000 bytes (≈1 TB reduced)

Slide 73

Slide 73 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :feature1 :feature2 :feature3 com.my.app.R (:feature1) (:feature2) (:feature3) (:app) Unresolved reference

Slide 74

Slide 74 text

G E T S T R E A M . I O Development Strategies Non transitive R class :app :feature1 :feature2 :feature3 com.my.app.R (:feature1) (:feature2) (:feature3) (:app) full name package import with namespacing

Slide 75

Slide 75 text

G E T S T R E A M . I O Library & SDK Lifecycles Design Develop Prepare Release

Slide 76

Slide 76 text

G E T S T R E A M . I O Preparation Documentation (KDoc)

Slide 77

Slide 77 text

G E T S T R E A M . I O Preparation Documentation (Dokka) ./gradlew dokkaHtml ./gradlew dokkaHtmlMultiModule ./gradlew dokkaJavadoc

Slide 78

Slide 78 text

G E T S T R E A M . I O Preparation Documentation (README)

Slide 79

Slide 79 text

G E T S T R E A M . I O Library & SDK Lifecycles Design Develop Prepare Release

Slide 80

Slide 80 text

G E T S T R E A M . I O Release Maven

Slide 81

Slide 81 text

G E T S T R E A M . I O Release Maven repositories mavenCentral() google() jcenter()

Slide 82

Slide 82 text

G E T S T R E A M . I O Release Maven central repository 1. Registering a Sonatype account 2. Generating a GPG key pair 3. Setting up publication in your project a. Maven publishing setup with Gradle b. Signing artifacts with GPG key c. Configure pom files d. Per-module Gradle setup 4. Publish to sonatype repository 5. Evaluate and close the ticket on staging repositories

Slide 83

Slide 83 text

G E T S T R E A M . I O Release Maven central repository 🔗 https://bit.ly/386yJt1

Slide 84

Slide 84 text

G E T S T R E A M . I O Release Jitpack maven { url 'https://jitpack.io' }

Slide 85

Slide 85 text

G E T S T R E A M . I O Library & SDK Lifecycles Design Develop Prepare Release Verification

Slide 86

Slide 86 text

G E T S T R E A M . I O Verifying and Marketing Community

Slide 87

Slide 87 text

G E T S T R E A M . I O Verifying and Marketing Technical contents

Slide 88

Slide 88 text

G E T S T R E A M . I O Verifying and Marketing Example projects Codes speak louder than words!

Slide 89

Slide 89 text

G E T S T R E A M . I O Blog Post 🔗 https://bit.ly/3Qim5ZB

Slide 90

Slide 90 text

G E T S T R E A M . I O https://github.com/skydoves jaewoong.eum@getstream.io https://twitter.com/github_skydoves https://medium.com/@skydoves Contact

Slide 91

Slide 91 text

G E T S T R E A M . I O Thank you.