Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Becoming an Android Librarian (Android World Wi...

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest. →
Jaewoong
February 01, 2023

Becoming an Android Librarian (Android World Wide 2023 Jan)

Becoming an Android Librarian (Android World Wide 2023 Jan)

Jaewoong

February 01, 2023

Transcript

91 slides
  1. G E T S T R E A M .

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

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

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

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

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

    I O Library & SDK Lifecycles Design Develop Prepare Release Design process
  7. 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
  8. G E T S T R E A M .

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

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

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

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

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

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

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

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

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

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

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

    I O Development Strategies Minimize API surfaces class ApiResponseCallAdapter constructor( val resultType: Type ) : CallAdapter<Type, Call<ApiResponse<Type>>> { override fun responseType(): Type { return resultType } override fun adapt(call: Call<Type>): Call<ApiResponse<Type>> { return ApiResponseCallDelegate(call) } } Client
  20. 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<Type, Call<ApiResponse<Type>>> { override fun responseType(): Type { return resultType } override fun adapt(call: Call<Type>): Call<ApiResponse<Type>> { return ApiResponseCallDelegate(call) } } Client
  21. 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)
  22. 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
  23. 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);
  24. 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
  25. G E T S T R E A M .

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

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

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

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

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

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

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

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

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

    I O Development Strategies Metalava
  35. 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
  36. 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/
  37. G E T S T R E A M .

    I O Development Strategies Exposing resources <resources> <color name="white">#FFFFFF</color> <color name="black">#000000</color> <color name="blue">#57A8D8</color> <color name="yellow">#FBC02D</color> </resources> Library (colors.xml) Project val whiteColor = ContextCompat.getColor(this, R.color.white) binding.myView.setBackgroundColor(whiteColor) <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="skydoves" android:textColor="@color/yellow" />
  38. G E T S T R E A M .

    I O Development Strategies Exposing resources <resources> <color name="white">#FFFFFF</color> <color name="black">#000000</color> <color name="blue">#57A8D8</color> <color name="yellow">#FBC02D</color> </resources> Library (colors.xml) val whiteColor = ContextCompat.getColor(this, R.color.white) binding.myView.setBackgroundColor(whiteColor) <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="skydoves" android:textColor="@color/yellow" /> Project compile error!
  39. G E T S T R E A M .

    I O Development Strategies Exposing resources <public />
  40. G E T S T R E A M .

    I O Development Strategies Exposing resources <?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools"> <!-- Definitions of layouts to be exposed as public ⟶ <public name="balloon_layout_body" type="layout" /> <public name="balloon_layout_overlay" type="layout" /> <!-- Definitions of attributes to be exposed as public ⟶ <public name="balloon_drawableStart" type="attr" /> <public name="balloon_drawableEnd" type="attr" /> <public name="balloon_drawableTop" type="attr" /> <public name="balloon_drawableBottom" type="attr" /> <public name="balloon_drawablePadding" type="attr" /> <public name="balloon_drawableTintColor" type="attr" /> <public name="balloon_drawableWidth" type="attr" /> <public name="balloon_drawableHeight" type="attr" /> <public name="balloon_drawableSquareSize" type="attr" /> Library (/res/values/public.xml)
  41. G E T S T R E A M .

    I O Development Strategies Exposing resources <?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools"> <!-- Definitions of layouts to be exposed as public ⟶ <public name="balloon_layout_body" type="layout" /> <public name="balloon_layout_overlay" type="layout" /> <!-- Definitions of attributes to be exposed as public ⟶ <public name="balloon_drawableStart" type="attr" /> <public name="balloon_drawableEnd" type="attr" /> <public name="balloon_drawableTop" type="attr" /> <public name="balloon_drawableBottom" type="attr" /> <public name="balloon_drawablePadding" type="attr" /> <public name="balloon_drawableTintColor" type="attr" /> <public name="balloon_drawableWidth" type="attr" /> <public name="balloon_drawableHeight" type="attr" /> <public name="balloon_drawableSquareSize" type="attr" /> Library (/res/values/public.xml) res/drawable res/layout res/menu res/values res/xml res/raw res/anim res/animator res/mipmap res/font String.xml attrs.xml colors.xml styles.xml dimens.xml arrays.xml /res/ /res/values/
  42. G E T S T R E A M .

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

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

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

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

    I O Development Strategies Exposing resources Library (layout_balloon.xml) Library (Balloon.Builder.kt)
  47. 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.
  48. G E T S T R E A M .

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

    I O Development Strategies Exposing resources <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:clipChildren="false" android:clipToPadding="false" android:padding="10dp"> <com.skydoves.balloon.vectortext.VectorTextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_vertical" android:textColor="@android:color/white" /> … Library (layout_balloon.xml) Project (layout_balloon.xml) <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:clipChildren="false" android:clipToPadding="false" android:padding="10dp"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="12dp" android:text="skydoves" android:textSize="16sp" android:textStyle="bold" /> ...
  50. G E T S T R E A M .

    I O Development Strategies Exposing resources <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:clipChildren="false" android:clipToPadding="false" android:padding="10dp"> <com.skydoves.balloon.vectortext.VectorTextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_vertical" android:textColor="@android:color/white" /> … Library (layout_balloon.xml) // wrong behaviors Project (layout_balloon.xml) // runtime error! <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:clipChildren="false" android:clipToPadding="false" android:padding="10dp"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="12dp" android:text="skydoves" android:textSize="16sp" android:textStyle="bold" /> ...
  51. G E T S T R E A M .

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

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

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

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

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

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

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

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

    I O Development Strategies Non transitive R class :app :library :material (MDC) implementation implementation
  60. 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
  61. 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
  62. 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
  63. 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
  64. G E T S T R E A M .

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

    I O Development Strategies Non transitive R class
  66. 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!
  67. 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))
  68. G E T S T R E A M .

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

    I O Development Strategies Non transitive R class android.nonTransitiveRClass=true gradle.properties
  70. 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)
  71. G E T S T R E A M .

    I O Development Strategies Non transitive R class Before After (enabled non transitive R class)
  72. 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)
  73. 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
  74. 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
  75. G E T S T R E A M .

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

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

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

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

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

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

    I O Release Maven repositories mavenCentral() google() jcenter()
  82. 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
  83. G E T S T R E A M .

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

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

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

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

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

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

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

    I O https://github.com/skydoves [email protected] https://twitter.com/github_skydoves https://medium.com/@skydoves Contact
  91. G E T S T R E A M .

    I O Thank you.

More Decks by Jaewoong

Other Decks in Programming