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 Srivastavanisrulz@gmail.com
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 Srivastavanisrulz@gmail.com
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
...
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'
}
...
}
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
@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
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