Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

OSS Android libraries developed

Slide 3

Slide 3 text

Android ARchive(AAR) @nisrulz

Slide 4

Slide 4 text

AAR = Java ARchive(JAR) + Resources @nisrulz

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

AAR = Java ARchive(JAR) + Resources @nisrulz

Slide 7

Slide 7 text

Using an AAR as dependency @nisrulz

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Sensey’s AAR @nisrulz

Slide 13

Slide 13 text

Sensey’s AAR @nisrulz No build.gradle file

Slide 14

Slide 14 text

Maven Artifact @nisrulz

Slide 15

Slide 15 text

@nisrulz Maven Artifact

Slide 16

Slide 16 text

POM? @nisrulz

Slide 17

Slide 17 text

POM @nisrulz + Stands for Project Object Model + Is a XML file + Contains + Information about the project + Configuration details used by Maven to build the project

Slide 18

Slide 18 text

POM @nisrulz 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 ...

Slide 19

Slide 19 text

POM @nisrulz 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 ...

Slide 20

Slide 20 text

POM @nisrulz POM of Sensey Android Library ... com.android.support support-compat27.0.2 runtime ...

Slide 21

Slide 21 text

Bundled Proguard Configs @nisrulz

Slide 22

Slide 22 text

Bundled Proguard Configs @nisrulz 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' } ... }

Slide 23

Slide 23 text

Bundled Proguard Configs @nisrulz Fuel: https://github.com/kittinunf/Fuel

Slide 24

Slide 24 text

Bundled Proguard Configs @nisrulz

Slide 25

Slide 25 text

Bundled Proguard Configs @nisrulz # 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

Slide 26

Slide 26 text

Bundled Proguard Configs @nisrulz # To check the merged configuration # Add the below to your current config -printconfiguration proguard-merged-config.txt

Slide 27

Slide 27 text

Bundled Proguard Configs @nisrulz # DON'T DO THIS -dontobfuscate -optimizations !code/allocation/variable # Effectively no optimizations -keep public class * { public protected *; }

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Modularization @nisrulz

Slide 30

Slide 30 text

Modularization @nisrulz

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

Modularization @nisrulz 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" }

Slide 33

Slide 33 text

Modularization @nisrulz ... com.github.nisrulz easydeviceinfo-ads 2.4.1 compile com.github.nisrulz easydeviceinfo-base 2.4.1 compile ...

Slide 34

Slide 34 text

Modularization @nisrulz ... com.github.nisrulz easydeviceinfo-ads 2.4.1 compile com.github.nisrulz easydeviceinfo-base 2.4.1 compile ...

Slide 35

Slide 35 text

Modularization @nisrulz ... com.github.nisrulz easydeviceinfo-ads 2.4.1 compile com.github.nisrulz easydeviceinfo-base 2.4.1 compile ...

Slide 36

Slide 36 text

Modularization @nisrulz ... com.github.nisrulz easydeviceinfo-common2.4.1 compile com.google.android.gms play-services-basement11.8.0 runtime ...

Slide 37

Slide 37 text

Modularization @nisrulz ... com.github.nisrulz easydeviceinfo-common2.4.1 compile com.google.android.gms play-services-basement11.8.0 runtime ...

Slide 38

Slide 38 text

Avoiding Resource Name Conflicts @nisrulz

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

@nisrulz Add a prefix to all your resources. Enforce this in Android Studio android { resourcePrefix 'YOUR_PREFIX_' // i.e 'sensey_' } Solution?

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

minSdkVersion Restriction @nisrulz

Slide 45

Slide 45 text

@nisrulz minSdkVersion of app >= minSdkVersion of library minSdk Restriction

Slide 46

Slide 46 text

@nisrulz minSdk Restriction

Slide 47

Slide 47 text

@nisrulz 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

Slide 48

Slide 48 text

@nisrulz 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

Slide 49

Slide 49 text

@nisrulz 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

Slide 50

Slide 50 text

@nisrulz ... minSdk Restriction

Slide 51

Slide 51 text

@nisrulz ... minSdk Restriction

Slide 52

Slide 52 text

Access Visibility vs Code Organization @nisrulz

Slide 53

Slide 53 text

Visibility vs Organization @nisrulz + Code organized in individual packages; everything is public

Slide 54

Slide 54 text

Visibility vs Organization @nisrulz + Code organized in individual packages; everything is public + Code organized inside one package; everything is package private and only public on demand

Slide 55

Slide 55 text

Visibility vs Organization @nisrulz + Code organized in individual packages; everything is public + Code organized inside one package; everything is package private and only public on demand But if in Kotlin land, + Code organized in individual packages; everything is internal and only public on demand

Slide 56

Slide 56 text

Visibility vs Organization @nisrulz // file name: exampleLibrary.kt // module name: example package com.example.library

Slide 57

Slide 57 text

Visibility vs Organization @nisrulz // file name: exampleLibrary.kt // module name: example package com.example.library // visible inside exampleLibrary.kt private fun setup() { ... }

Slide 58

Slide 58 text

Visibility vs Organization @nisrulz // file name: exampleLibrary.kt // module name: example package com.example.library // visible inside exampleLibrary.kt private fun setup() { ... } // property is visible everywhere public var name: String = "ExampleLib" // setter is visible only in exampleLibrary.kt private set{...}

Slide 59

Slide 59 text

Visibility vs Organization @nisrulz // file name: exampleLibrary.kt // module name: example package com.example.library // visible inside exampleLibrary.kt private fun setup() { ... } // property is visible everywhere public var name: String = "ExampleLib" // setter is visible only in exampleLibrary.kt private set{...} // visible inside the module i.e example internal val debugTag = "Example-Debug"

Slide 60

Slide 60 text

Lifecycle-Aware Android Library @nisrulz

Slide 61

Slide 61 text

Lifecycle Components @nisrulz Classes designed to help deal with Android lifecycle + Lifecycle + LifecycleOwner + LifecycleObserver

Slide 62

Slide 62 text

Lifecycle Components @nisrulz Classes designed to help deal with Android lifecycle

Slide 63

Slide 63 text

Lifecycle Components @nisrulz Classes designed to help deal with Android lifecycle i.e Activity, Fragment, Service, Custom

Slide 64

Slide 64 text

LifecycleObserver @nisrulz dependencies { def lifecycleVer = "1.1.1" // Runtime implementation "android.arch.lifecycle:runtime:$lifecycleVer" // Annotation Support annotationProcessor "android.arch.lifecycle:compiler:$lifecycleVer" ... }

Slide 65

Slide 65 text

LifecycleObserver @nisrulz object AwesomeLibrary : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun init() { ... } @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onStart() { ... } ... @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun cleanup() { ...} }

Slide 66

Slide 66 text

LifecycleOwner @nisrulz class MainActivity : AppCompatActivity() { // LifecycleOwner override fun onResume() { // Add lifecycle observer lifecycle.addObserver(AwesomeLibrary.INSTANCE) } override fun onStop() { // Remove lifecycle observer lifecycle.removeObserver(AwesomeLibrary.INSTANCE) } }

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

ProcessLifecycleOwner @nisrulz dependencies { def lifecycleVer = "1.1.1" // For ProcessLifecycleOwner implementation "android.arch.lifecycle:extensions:$lifecycleVer" ... }

Slide 69

Slide 69 text

ProcessLifecycleOwner @nisrulz extension artifact automatically adds element to your manifest

Slide 70

Slide 70 text

ProcessLifecycleOwner @nisrulz ...

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

Auto Initialize Android Library @nisrulz

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

AutoInit Android Library @nisrulz

Slide 79

Slide 79 text

AutoInit Android Library @nisrulz ContentProvider “can be” used to simplify the process. How? ContentProvider is + Created and initialized (on the main thread) before all other components + Participate in manifest merging at build time.

Slide 80

Slide 80 text

AutoInit Android Library @nisrulz 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; } ... }

Slide 81

Slide 81 text

AutoInit Android Library @nisrulz 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; } ... }

Slide 82

Slide 82 text

AutoInit Android Library @nisrulz

Slide 83

Slide 83 text

AutoInit Android Library @nisrulz

Slide 84

Slide 84 text

AutoInit Android Library @nisrulz

Slide 85

Slide 85 text

AutoInit Android Library @nisrulz

Slide 86

Slide 86 text

AutoInit Android Library @nisrulz ContentProvider “can be” used to simplify the process. Why it shouldn’t be + There can be only one Content Provider with a given “authority” string + Only run on main thread; does not support multi process

Slide 87

Slide 87 text

Links/References @nisrulz 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

Slide 88

Slide 88 text

twitter.com/nisrulz github.com/nisrulz www.nisrulz.com

Slide 89

Slide 89 text

twitter.com/nisrulz github.com/nisrulz www.nisrulz.com