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

[AppdevCon '19] Demystifying Android Libraries

[AppdevCon '19] Demystifying Android Libraries

Building an Android library in the current times is way different than what it used to be earlier. Things have changed considerably and keeping up to date with them is now a necessity rather than just some acquirable knowledge.

In this session, you will dive deeper into best practices and ways of architecting Android libraries. You will get to learn about the common pitfalls and how to overcome them by using the right approach such as leveraging architecture components and making your Android libraries lifecycle-aware. You will also understand how one can leverage Kotlin language when developing Android libraries as well as information around API design and exploring the path to becoming a better Android Library Developer.

By the end of this session, you will be all set to build Android libraries that scale and have API which contributes to the developer's happiness.

Event Link: https://web.archive.org/web/20190315154423/https://appdevcon.nl/session/demystifying-android-libraries/

Nishant Srivastava

March 15, 2019
Tweet

More Decks by Nishant Srivastava

Other Decks in Programming

Transcript

  1. OSS Android libraries developed
    2

    View full-size slide

  2. How does Gradle process
    Android Libraries
    @nisrulz 3

    View full-size slide

  3. How does Gradle process
    Android Libraries
    repositories {
    jCenter()
    }
    dependencies {
    implementation 'com.github.nisrulz:awesomelib:1.0'
    ...
    }
    4
    @nisrulz

    View full-size slide

  4. How does Gradle process
    Android Libraries
    repositories {
    jCenter()
    }
    dependencies {
    implementation 'com.github.nisrulz:awesomelib:1.0'
    ...
    }
    5
    @nisrulz
    // Dependency Notation

    View full-size slide

  5. How does Gradle process
    Android Libraries
    repositories {
    jCenter()
    }
    dependencies {
    implementation 'com/github/nisrulz/awesomelib/1.0'
    ...
    }
    6
    @nisrulz

    View full-size slide

  6. How does Gradle process
    Android Libraries
    implementation 'com.github.nisrulz:awesomelib:1.0'
    7
    @nisrulz

    View full-size slide

  7. How does Gradle process
    Android Libraries
    implementation 'com/github/nisrulz/awesomelib/1.0'
    8
    @nisrulz

    View full-size slide

  8. How does Gradle process
    Android Libraries
    implementation 'com/github/nisrulz/awesomelib/1.0'
    9
    @nisrulz

    View full-size slide

  9. How does Gradle process
    Android Libraries
    implementation 'com/github/nisrulz/awesomelib/1.0'
    10
    @nisrulz

    View full-size slide

  10. How does Gradle process
    Android Libraries
    implementation 'com.github.nisrulz:awesomelib:1.0'
    11
    @nisrulz

    View full-size slide

  11. Android ARchive(AAR)
    @nisrulz 12

    View full-size slide

  12. AAR = Java ARchive(JAR) + Resources
    15
    @nisrulz

    View full-size slide

  13. AAR = Java ARchive(JAR) + Resources
    Sensey: https://github.com/nisrulz/sensey
    16
    @nisrulz

    View full-size slide

  14. AAR = Java ARchive(JAR) + Resources
    @nisrulz 17

    View full-size slide

  15. Sensey’s build.gradle
    dependencies {
    ...
    // Other testing dependencies
    // Transitive dependency: Support Compat library
    implementation "com.android.support:support-compat:27.0.2"
    }
    18
    @nisrulz

    View full-size slide

  16. Using AAR as dependency
    @nisrulz 19

    View full-size slide

  17. Using an AAR as dependency
    repositories{
    flatDir{
    dirs 'libs'
    }
    }
    dependencies {
    implementation(name:'nameOfYourAARFileWithoutExtension', ext:'aar')
    }
    @nisrulz 20

    View full-size slide

  18. Using an AAR as dependency
    repositories{
    flatDir{
    dirs 'libs'
    }
    }
    dependencies {
    implementation(name:'nameOfYourAARFileWithoutExtension', ext:'aar')
    }
    // No transitive dependencies of the library are downloaded
    21
    @nisrulz

    View full-size slide

  19. Why doesn’t my AAR
    download transitive
    dependencies?
    @nisrulz 22

    View full-size slide

  20. Sensey’s AAR
    23
    @nisrulz

    View full-size slide

  21. Sensey’s AAR
    No build.gradle file
    24
    @nisrulz

    View full-size slide

  22. Maven Artifact
    25
    @nisrulz

    View full-size slide

  23. Maven Artifact
    26
    @nisrulz

    View full-size slide

  24. POM?
    27
    @nisrulz

    View full-size slide

  25. POM
    ● Project Object Model
    ● XML file
    ● Configuration details used by Maven to build the project
    28
    @nisrulz

    View full-size slide

  26. POM
    POM of Sensey Android Library


    4.0.0
    com.github.nisrulzsensey1.8.0
    aarsensey
    Android library which makes playing with sensor events & detecting gestures a breeze.
    https://github.com/nisrulz/sensey


    The Apache Software License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0.txt



    nisrulzNishant [email protected]


    https://github.com/nisrulz/sensey.git
    https://github.com/nisrulz/sensey.git
    https://github.com/nisrulz/sensey



    com.android.support
    support-compat27.0.2
    runtime


    ...



    29
    @nisrulz

    View full-size slide

  27. POM
    POM of Sensey Android Library


    4.0.0
    com.github.nisrulzsensey1.8.0
    aarsensey
    Android library which makes playing with sensor events & detecting gestures a breeze.
    https://github.com/nisrulz/sensey


    The Apache Software License, Version 2.0http://www.apache.org/licenses/LICENSE-2.0.txt



    nisrulzNishant [email protected]


    https://github.com/nisrulz/sensey.git
    https://github.com/nisrulz/sensey.git
    https://github.com/nisrulz/sensey



    com.android.support
    support-compat27.0.2
    runtime


    ...



    30
    @nisrulz

    View full-size slide

  28. POM
    POM of Sensey Android Library


    ...


    com.android.support
    support-compat27.0.2
    runtime


    ...



    31
    @nisrulz

    View full-size slide

  29. Bundled Proguard Configs
    32
    @nisrulz

    View full-size slide

  30. Bundled Proguard Configs
    android {
    release {
    minifyEnabled true
    // Rules to be used during the AAR generation
    proguardFiles 'proguard-rules-for-building-library.pro'
    }
    ...
    }
    33
    @nisrulz

    View full-size slide

  31. Bundled Proguard Configs
    android {
    release {
    minifyEnabled true
    // Rules to be used during the AAR generation
    proguardFiles 'proguard-rules-for-building-library.pro'
    // Rules appended to the integrating app
    consumerProguardFiles 'proguard-rules-for-using-library.pro'
    }
    ...
    }
    34
    @nisrulz

    View full-size slide

  32. Bundled Proguard Configs
    35
    @nisrulz

    View full-size slide

  33. Bundled Proguard Configs
    36
    @nisrulz

    View full-size slide

  34. Bundled Proguard Configs
    # Fuel’s bundled Proguard file
    # Without specifically keeping this class,
    # callbacks on android don't function properly.
    -keep class com.github.kittinunf.fuel.android.util.AndroidEnvironment
    37
    @nisrulz

    View full-size slide

  35. Bundled Proguard Configs
    # DON'T DO THIS
    # Do not obfuscate the input class files
    -dontobfuscate
    # Optimizes variable allocation on the local variable frame.
    -optimizations !code/allocation/variable
    # Preserved as entry points
    -keep public class * {
    public protected *;
    }
    38
    @nisrulz

    View full-size slide

  36. Bundled Proguard Configs
    # DON'T DO THIS
    # Adding the below in library proguard rules disables
    # the optimizations in the Android app
    -dontoptimize
    39
    @nisrulz

    View full-size slide

  37. Bundled Proguard Configs
    # To check the merged configuration
    # Add the below to your app’s current proguard rules
    -printconfiguration proguard-merged-config.txt
    40
    @nisrulz

    View full-size slide

  38. Bundled Proguard Configs
    41
    @nisrulz

    View full-size slide

  39. Modularization
    42
    @nisrulz

    View full-size slide

  40. Modularization
    43
    @nisrulz

    View full-size slide

  41. Modularization
    EasyDeviceInfo: https://github.com/nisrulz/easydeviceinfo
    44
    @nisrulz

    View full-size slide

  42. Modularization
    dependencies {
    def libVer = {latest_version}
    // Base + Ads Bundled Library
    implementation "com.github.nisrulz:easydeviceinfo:$libVer"
    // Base Library
    implementation "com.github.nisrulz:easydeviceinfo-base:$libVer"
    // Ads Library
    implementation "com.github.nisrulz:easydeviceinfo-ads:$libVer"
    }
    45
    @nisrulz

    View full-size slide

  43. Modularization


    ...


    com.github.nisrulz
    easydeviceinfo-ads 2.5.0
    compile


    com.github.nisrulz
    easydeviceinfo-base 2.5.0
    compile

    ...


    46
    @nisrulz

    View full-size slide

  44. Modularization


    ...


    com.github.nisrulz
    easydeviceinfo-ads 2.5.0
    compile


    com.github.nisrulz
    easydeviceinfo-base 2.5.0
    compile

    ...


    47
    @nisrulz

    View full-size slide

  45. Modularization


    ...


    com.github.nisrulz
    easydeviceinfo-ads 2.5.0
    compile


    com.github.nisrulz
    easydeviceinfo-base 2.5.0
    compile

    ...


    48
    @nisrulz

    View full-size slide

  46. Modularization


    ...


    com.github.nisrulz
    easydeviceinfo-common2.5.0
    compile


    com.google.android.gms
    play-services-ads-identifier16.0.0
    runtime

    ...


    49
    @nisrulz

    View full-size slide

  47. Modularization


    ...


    com.github.nisrulz
    easydeviceinfo-common2.5.0
    compile


    com.google.android.gms
    play-services-ads-identifier16.0.0
    runtime

    ...


    50
    @nisrulz

    View full-size slide

  48. Avoiding Resource Name
    Conflicts
    51
    @nisrulz

    View full-size slide

  49. Conflict occurs between a library & app resource
    > Project will not compile
    What happens when...
    52
    @nisrulz

    View full-size slide

  50. Conflict occurs between 2 libraries integrated in the app
    > Resources from library defined first in build.gradle gets
    included
    What happens when...
    53
    @nisrulz

    View full-size slide

  51. Solution?
    54
    @nisrulz

    View full-size slide

  52. Add a prefix to all your resources.
    Solution?
    55
    @nisrulz

    View full-size slide

  53. Add a prefix to all your resources.
    How?
    Solution?
    56
    @nisrulz

    View full-size slide

  54. Add a prefix to all your resources.
    How?
    ● Enforce this in Android Studio
    Solution?
    57
    @nisrulz

    View full-size slide

  55. Add a prefix to all your resources.
    How?
    ● Enforce this in Android Studio
    ● Declare in build.gradle of library
    android {
    resourcePrefix 'YOUR_PREFIX_' // i.e 'sensey_'
    }
    Solution?
    58
    @nisrulz

    View full-size slide

  56. Solution?
    Resource named ‘app_name’ does not start with the project’s
    resource prefix ‘sensey_’;
    Rename to `sensey_app_name`?
    59
    @nisrulz

    View full-size slide

  57. minSdkVersion Restriction
    60
    @nisrulz

    View full-size slide

  58. minSdkVersion of app >= minSdkVersion of library
    minSdk Restriction
    61
    @nisrulz

    View full-size slide

  59. minSdk Restriction
    62
    @nisrulz

    View full-size slide

  60. Manifest merger failed : uses-sdk:minSdkVersion 14 cannot be smaller
    than version 21 declared in library [:sensey]
    Suggestion:
    + Use a compatible library with a minSdk of at most 14
    + Increase this project's minSdk version to at least 21
    + Use tools:overrideLibrary="com.github.nisrulz.sensey" to force
    usage (may lead to runtime failures)
    minSdk Restriction
    63
    @nisrulz

    View full-size slide

  61. Manifest merger failed : uses-sdk:minSdkVersion 14 cannot be smaller
    than version 21 declared in library [:sensey]
    Suggestion:
    + Use a compatible library with a minSdk of at most 14
    + Increase this project's minSdk version to at least 21
    + Use tools:overrideLibrary="com.github.nisrulz.sensey" to force
    usage (may lead to runtime failures)
    minSdk Restriction
    64
    @nisrulz

    View full-size slide

  62. Manifest merger failed : uses-sdk:minSdkVersion 14 cannot be smaller
    than version 21 declared in library [:sensey]
    Suggestion:
    + Use a compatible library with a minSdk of at most 14
    + Increase this project's minSdk version to at least 21
    + Use tools:overrideLibrary="com.github.nisrulz.sensey" to force
    usage (may lead to runtime failures)
    minSdk Restriction
    65
    @nisrulz

    View full-size slide

  63. xmlns:tools="http://schemas.android.com/tools"
    package="com.github.nisrulz.senseysample">


    ...


    minSdk Restriction
    66
    @nisrulz

    View full-size slide

  64. xmlns:tools="http://schemas.android.com/tools"
    package="com.github.nisrulz.senseysample">


    ...


    minSdk Restriction
    67
    @nisrulz

    View full-size slide

  65. Access Visibility
    vs
    Code Organization
    68
    @nisrulz

    View full-size slide

  66. Visibility vs Organization
    69
    @nisrulz

    View full-size slide

  67. Visibility vs Organization
    ● Code organized in individual packages; everything is
    public
    70
    @nisrulz

    View full-size slide

  68. Visibility vs Organization
    ● Code organized inside one package; Classes and methods
    are package private and only public on demand
    71
    @nisrulz

    View full-size slide

  69. Visibility vs Organization
    ● Code organized inside the module i.e individual packages
    Classes and methods are internal and only public on
    demand (in Kotlin land)
    72
    @nisrulz

    View full-size slide

  70. Visibility vs Organization
    ● internal and only public on demand (in Kotlin land)
    73
    @nisrulz

    View full-size slide

  71. Visibility vs Organization
    ● Code organized inside the module i.e individual packages
    Classes and methods are internal and only public on
    demand (in Kotlin land)
    ● Drawback
    ○ Need dependency on kotlin std library
    74
    @nisrulz

    View full-size slide

  72. Lifecycle-Aware
    Android Library
    75
    @nisrulz

    View full-size slide

  73. Lifecycle Components
    Classes designed to help deal with Android
    lifecycle
    ● Lifecycle
    ● LifecycleOwner
    ● LifecycleObserver
    76
    @nisrulz

    View full-size slide

  74. Lifecycle Owner
    77
    @nisrulz

    View full-size slide

  75. Lifecycle Owner + Lifecycle
    78
    @nisrulz

    View full-size slide

  76. Lifecycle Owner + Lifecycle




    79
    @nisrulz

    View full-size slide

  77. Lifecycle Owner + Lifecycle
    class MainActivity extends AppCompatActivity() {...}
    80
    @nisrulz

    View full-size slide

  78. Lifecycle Owner + Lifecycle
    class MainActivity extends AppCompatActivity() {...}
    public class AppCompatActivity extends FragmentActivity{...}
    81
    @nisrulz

    View full-size slide

  79. Lifecycle Owner + Lifecycle
    class MainActivity extends AppCompatActivity() {...}
    public class AppCompatActivity extends FragmentActivity{...}
    public class FragmentActivity extends SupportActivity {...}
    82
    @nisrulz

    View full-size slide

  80. Lifecycle Owner + Lifecycle
    class MainActivity extends AppCompatActivity() {...}
    public class AppCompatActivity extends FragmentActivity{...}
    public class FragmentActivity extends SupportActivity {...}
    public class SupportActivity extends Activity implements LifecycleOwner,
    Component {
    ...
    public Lifecycle getLifecycle() {return this.mLifecycleRegistry();}
    ...
    }
    83
    @nisrulz

    View full-size slide

  81. Lifecycle Owner + Lifecycle
    class MainActivity extends AppCompatActivity() {...}
    public class AppCompatActivity extends FragmentActivity{...}
    public class FragmentActivity extends SupportActivity {...}
    public class SupportActivity extends Activity implements LifecycleOwner,
    Component {
    ...
    public Lifecycle getLifecycle() {return this.mLifecycleRegistry();}
    ...
    }
    84
    @nisrulz

    View full-size slide

  82. Lifecycle Observer
    85
    @nisrulz

    View full-size slide

  83. Lifecycle Observer
    86
    @nisrulz

    View full-size slide

  84. LifecycleObserver
    dependencies {
    def lifecycleVer = "2.0.0"
    // Runtime
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycleVer"
    // Annotation Support
    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycleVer"
    ...
    }
    87
    @nisrulz

    View full-size slide

  85. LifecycleObserver
    public class AwesomeLib implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    public void init() { ... }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void libOnStart() { ... }
    ...
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void cleanup() { ... }
    }
    88
    @nisrulz

    View full-size slide

  86. LifecycleOwner
    class MainActivity : AppCompatActivity() {
    val awesomeLib = AwesomeLib()
    override fun onStart() {
    ...
    // Add lifecycle observer
    lifecycle.addObserver(awesomeLib)
    }
    override fun onStop() {
    ...
    // Remove lifecycle observer
    lifecycle.removeObserver(awesomeLib)
    }
    }
    89
    @nisrulz

    View full-size slide

  87. LifecycleAware Library
    90
    @nisrulz

    View full-size slide

  88. ProcessLifecycleOwner
    Class that tracks the lifecycle of
    whole application process
    91
    @nisrulz

    View full-size slide

  89. ProcessLifecycleOwner
    dependencies {
    // For ProcessLifecycleOwner
    implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
    ...
    }
    92
    @nisrulz

    View full-size slide

  90. ProcessLifecycleOwner
    Does something weird…
    93
    @nisrulz

    View full-size slide

  91. ProcessLifecycleOwner
    Does something weird…
    Adding lifecycle-extensions artifact
    > automatically adds element to the merged
    manifest
    94
    @nisrulz

    View full-size slide

  92. ProcessLifecycleOwner
    95
    @nisrulz

    View full-size slide

  93. ProcessLifecycleOwner


    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="com.example.app.lifecycle-process"
    android:exported="false"
    android:multiprocess="true" />


    96
    @nisrulz

    View full-size slide

  94. ProcessLifecycleOwner


    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="com.example.app.lifecycle-process"
    android:exported="false"
    android:multiprocess="true" />


    97
    @nisrulz

    View full-size slide

  95. ProcessLifecycleOwner


    ...
    android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="com.example.app.lifecycle-trojan"
    android:exported="false"
    android:multiprocess="true" />


    98
    @nisrulz
    Pre-AndroidX

    View full-size slide

  96. ProcessLifecycleOwner


    ...
    android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="com.example.app.lifecycle-trojan"
    android:exported="false"
    android:multiprocess="true" />


    99
    @nisrulz
    Pre-AndroidX

    View full-size slide

  97. ProcessLifecycleOwner
    100
    @nisrulz
    Pre-AndroidX

    View full-size slide

  98. ProcessLifecycleOwner


    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="com.example.app.lifecycle-process"
    android:exported="false"
    android:multiprocess="true" />


    101
    @nisrulz
    AndroidX

    View full-size slide

  99. ProcessLifecycleOwner


    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="com.example.app.lifecycle-process"
    android:exported="false"
    android:multiprocess="true" />


    102
    @nisrulz
    AndroidX

    View full-size slide

  100. ProcessLifecycleOwner
    // Internal class to initialize Lifecycles.
    public class ProcessLifecycleOwnerInitializer extends ContentProvider {
    @Override
    public boolean onCreate() {
    ...
    ProcessLifecycleOwner.init(getContext());
    return true;
    }
    ...
    }
    103
    @nisrulz

    View full-size slide

  101. ProcessLifecycleOwner
    Why?
    To invoke ProcessLifecycleOwner as soon as process
    starts
    104
    @nisrulz

    View full-size slide

  102. ProcessLifecycleOwner
    Why?
    To invoke ProcessLifecycleOwner as soon as process
    starts
    Drawback?
    Initializes ProcessLifecycleOwner even if your app
    does not use it!
    105
    @nisrulz

    View full-size slide

  103. ProcessLifecycleOwner
    How to get rid of it in app?
    106
    @nisrulz

    View full-size slide

  104. ProcessLifecycleOwner
    How to get rid of it in app?
    Use Merge rule marker in app’s AndroidManifest.xml:
    // Remove marked element from the merged manifest
    tools:node="remove"
    107
    @nisrulz

    View full-size slide

  105. ProcessLifecycleOwner

    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="${applicationId}.lifecycle-process"
    xmlns:tools="http://schemas.android.com/tools"
    tools:node="remove"
    />

    108
    @nisrulz
    App’s AndroidManifest.xml

    View full-size slide

  106. ProcessLifecycleOwner

    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="${applicationId}.lifecycle-process"
    xmlns:tools="http://schemas.android.com/tools"
    tools:node="remove"
    />

    109
    @nisrulz
    App’s AndroidManifest.xml

    View full-size slide

  107. ProcessLifecycleOwner

    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="${applicationId}.lifecycle-process"
    xmlns:tools="http://schemas.android.com/tools"
    tools:node="remove"
    />

    110
    @nisrulz
    App’s AndroidManifest.xml

    View full-size slide

  108. ProcessLifecycleOwner

    ...
    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="${applicationId}.lifecycle-process"
    xmlns:tools="http://schemas.android.com/tools"
    tools:node="remove"
    />

    111
    @nisrulz
    App’s AndroidManifest.xml

    View full-size slide

  109. Auto Initialize
    Android Library
    112
    @nisrulz

    View full-size slide

  110. AutoInit Android Library
    Android Libraries need Android context to handle simple tasks such as
    ● Hook into Android Runtime
    ● Access app resources
    ● Use System Services
    ● Register BroadcastReceiver
    113
    @nisrulz

    View full-size slide

  111. AutoInit Android Library
    public class MyApplication extends Application {
    @Override
    public void onCreate() {
    super.onCreate();
    // Init android library
    AwesomeLib.getInstance().init(this);
    }
    }
    114
    @nisrulz

    View full-size slide

  112. AutoInit Android Library
    public class MyApplication extends Application {
    @Override
    public void onCreate() {
    super.onCreate();
    // Init android library
    AwesomeLib.getInstance().init(this);
    }
    }
    115
    @nisrulz

    View full-size slide

  113. AutoInit Android Library
    public class MyApplication extends Application {
    @Override
    public void onCreate() {
    super.onCreate();
    // Init android library
    AwesomeLib.getInstance().init(this);
    }
    }
    116
    @nisrulz

    View full-size slide

  114. AutoInit Android Library
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:name=".MyApplication"
    ... >
    117
    @nisrulz

    View full-size slide

  115. AutoInit Android Library
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:name=".MyApplication"
    ... >
    118
    @nisrulz

    View full-size slide

  116. AutoInit Android Library
    ContentProvider can be used to simplify the process.
    119
    @nisrulz

    View full-size slide

  117. AutoInit Android Library
    ContentProvider can be used to simplify the process.
    Simply because ContentProvider
    ● Is created and initialized (on the main thread)
    before all other components
    ● Participate in manifest merging at build time.
    120
    @nisrulz

    View full-size slide

  118. AutoInit Android Library
    public class AwesomeLibInitProvider extends ContentProvider {
    ...
    @Override
    public boolean onCreate() {
    // get the context (Application context)
    Context context = getContext();
    // initialize AwesomeLib here
    AwesomeLib.getInstance().init(context);
    return false;
    }
    ...
    }
    121
    @nisrulz

    View full-size slide

  119. AutoInit Android Library
    public class AwesomeLibInitProvider extends ContentProvider {
    ...
    @Override
    public boolean onCreate() {
    // get the context (Application context)
    Context context = getContext();
    // initialize AwesomeLib here
    AwesomeLib.getInstance().init(context);
    return false;
    }
    ...
    }
    122
    @nisrulz

    View full-size slide

  120. AutoInit Android Library
    package="github.nisrulz.sample.awesomelib">

    android:name=".AwesomeLibInitProvider"
    android:authorities="${applicationId}.awesomelibinitprovider"
    android:enabled="true"
    android:exported="false"/>


    123
    @nisrulz

    View full-size slide

  121. AutoInit Android Library
    package="github.nisrulz.sample.awesomelib">

    android:name=".AwesomeLibInitProvider"
    android:authorities="${applicationId}.awesomelibinitprovider"
    android:enabled="true"
    android:exported="false"/>


    124
    @nisrulz

    View full-size slide

  122. AutoInit Android Library
    package="github.nisrulz.sample.awesomelib">

    android:name=".AwesomeLibInitProvider"
    android:authorities="${applicationId}.awesomelibinitprovider"
    android:enabled="true"
    android:exported="false"/>


    125
    @nisrulz

    View full-size slide

  123. AutoInit Android Library
    package="github.nisrulz.sample.awesomelib">

    android:name=".AwesomeLibInitProvider"
    android:authorities="${applicationId}.awesomelibinitprovider"
    android:enabled="true"
    android:exported="false"/>


    126
    @nisrulz

    View full-size slide

  124. AutoInit Android Library
    ContentProvider can be used to simplify the process.
    127
    @nisrulz

    View full-size slide

  125. AutoInit Android Library
    ContentProvider can be used to simplify the process.
    Challenges:
    ● There can be only one Content Provider with a given
    “authority” string
    ● Only run on main thread
    128
    @nisrulz

    View full-size slide

  126. AutoInit Android Library
    ContentProvider can be used to simplify the process.
    129
    @nisrulz

    View full-size slide

  127. AutoInit Android Library
    ContentProvider can be used to simplify the process.
    Why this is a bad idea:
    ● Increases startup time
    ● Bloats applications even when not used
    ● Abusing functionality of ContentProvider
    130
    @nisrulz

    View full-size slide

  128. AutoInit Android Library
    ContentProvider can be used to simplify the process.
    Why this is a bad idea:
    ● Increases startup time (Solution: async initialize)
    ● Bloats applications even when not used
    ● Abusing functionality of ContentProvider
    131
    @nisrulz

    View full-size slide

  129. AutoInit Android Library
    Some android libraries that use this...
    132
    @nisrulz

    View full-size slide

  130. AutoInit Android Library
    ProcessLifecycleOwner
    [androidx.lifecycle:lifecycle-extensions:2.0.0]

    android:name="androidx.lifecycle.ProcessLifecycleOwnerInitializer"
    android:authorities="${applicationId}.lifecycle-process"
    android:exported="false"
    android:multiprocess="true" />

    133
    @nisrulz

    View full-size slide

  131. AutoInit Android Library
    Firebase
    [com.google.firebase:firebase-common:16.0.5]

    android:name="com.google.firebase.provider.FirebaseInitProvider"
    android:authorities="${applicationId}.firebaseinitprovider"
    android:exported="false"
    android:initOrder="100" />

    134
    @nisrulz

    View full-size slide

  132. AutoInit Android Library
    Facebook-Core
    [com.facebook.android:facebook-core:4.34.0]

    android:name="com.facebook.internal.FacebookInitProvider"
    android:authorities="${applicationId}.FacebookInitProvider"
    android:exported="false" />

    135
    @nisrulz

    View full-size slide

  133. AutoInit Android Library
    Facebook-Marketing
    [com.facebook.android:facebook-marketing:4.34.0]

    android:name="com.facebook.marketing.internal.MarketingInitProvider"
    android:authorities="${applicationId}.MarketingInitProvider"
    android:exported="false" />

    136
    @nisrulz

    View full-size slide

  134. AutoInit Android Library
    Crashlytics
    [com.crashlytics.sdk.android:crashlytics:2.9.5]

    android:name="com.crashlytics.android.CrashlyticsInitProvider"
    android:authorities="${applicationId}.crashlyticsinitprovider"
    android:exported="false"
    android:initOrder="90" />

    137
    @nisrulz

    View full-size slide

  135. AutoInit Android Library
    Picasso
    // Pre - v2.71828
    Picasso.with(this).load("......").into(imageView);
    // After - v2.71828
    Picasso.get().load("......").into(imageView);
    138
    @nisrulz

    View full-size slide

  136. AutoInit Android Library
    Picasso
    // Pre - v2.71828
    Picasso.with(this).load("......").into(imageView);
    // After - v2.71828
    Picasso.get().load("......").into(imageView);
    139
    @nisrulz

    View full-size slide

  137. AutoInit Android Library
    Picasso
    [com.squareup.picasso:picasso:2.71828]

    android:name=".PicassoContentProvider"
    android:authorities="${applicationId}.com.squareup.picasso3"
    android:exported="false"/>

    140
    @nisrulz

    View full-size slide

  138. Links/References
    Android Libraries I have built:
    https://github.com/nisrulz/nisrulz.github.io#open-source-co
    ntributions
    Auto initialize android library example:
    https://github.com/nisrulz/android-examples/tree/develop/Au
    toInitLibrary
    Lifecycle Aware android library example:
    https://github.com/nisrulz/android-examples/tree/develop/Li
    feCycleCompForLib
    141
    @nisrulz

    View full-size slide

  139. 142
    twitter.com/nisrulz
    github.com/nisrulz
    www.nisrulz.com

    View full-size slide

  140. twitter.com/nisrulz
    github.com/nisrulz
    www.nisrulz.com
    143

    View full-size slide