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

Becoming an Android Librarian

Becoming an Android Librarian

Becoming an Android Librarian.

Jaewoong

May 14, 2022
Tweet

More Decks by Jaewoong

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  8. G E T S T R E A M . I O
    Library & SDK Lifecycles Design process
    1. Define the problem
    2. Research overall solutions
    3. Verify the feasibility of the solutions
    4. Define dependency relationships
    5. Draw blueprints of the final usage in real-world projects
    6. Design the interfaces

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. 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)
    }
    }

    View Slide

  21. 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)
    }
    }

    View Slide

  22. 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)

    View Slide

  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()
    }
    val px = context.dp2Px(dp = 22) // Unresolved reference
    val sp = context.px2Sp(px = 22) // Unresolved reference

    View Slide

  24. 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);

    View Slide

  25. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  37. 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/

    View Slide

  38. 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)
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="skydoves"
    android:textColor="@color/yellow" />

    View Slide

  39. 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)
    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!

    View Slide

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

    View Slide

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


    View Slide

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


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. 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.

    View Slide

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

    View Slide

  51. G E T S T R E A M . I O
    Development Strategies Exposing resources
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:padding="10dp">
    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)
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:padding="10dp">
    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" />
    ...

    View Slide

  52. G E T S T R E A M . I O
    Development Strategies Exposing resources
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:padding="10dp">
    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!
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:padding="10dp">
    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" />
    ...

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  62. 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)

    View Slide

  63. 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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  67. 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!

    View Slide

  68. 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))

    View Slide

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

    View Slide

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

    View Slide

  71. 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
    (:library)
    com.google.android.material.R
    (:material)
    com.my.app.R
    (:app)
    Refer to its own resources without pulling resources from
    dependencies.

    View Slide

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

    View Slide

  73. 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 projects
    2260540000 bytes -> 2145380000 bytes (≈115 MB reduced)
    100,000 projects
    22605400000 bytes -> 21453800000 bytes (≈1.1 GB reduced)
    1,000,000 projects
    226054000000 bytes -> 214538000000 bytes (≈10 GB reduced)
    100,000,000 end-users
    22605400000000 bytes -> 21453800000000 bytes (≈1 TB reduced)

    View Slide

  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)
    Unresolved reference

    View Slide

  75. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  83. G E T S T R E A M . I O
    Release Maven central repository
    mavenCentral()

    View Slide

  84. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  88. G E T S T R E A M . I O
    Management Code formatting

    View Slide

  89. G E T S T R E A M . I O
    Management Code formatting

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  93. 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

    View Slide

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

    View Slide