Sensey’s build.gradle
dependencies {
...
// Other testing dependencies
// Transitive dependency: Support Compat library
implementation "com.android.support:support-compat:27.0.2"
}
13
@nisrulz
Slide 14
Slide 14 text
Using an AAR as dependency
@nisrulz 14
Slide 15
Slide 15 text
Using an AAR as dependency
repositories{
flatDir{
dirs 'libs'
}
}
dependencies {
implementation(name:'nameOfYourAARFileWithoutExtension', ext:'aar')
}
@nisrulz 15
Slide 16
Slide 16 text
Using an AAR as dependency
repositories{
flatDir{
dirs 'libs'
}
}
dependencies {
implementation(name:'nameOfYourAARFileWithoutExtension', ext:'aar')
}
// No transitive dependencies of the library are downloaded
16
@nisrulz
Slide 17
Slide 17 text
Why doesn’t my AAR
download transitive
dependencies?
@nisrulz 17
Slide 18
Slide 18 text
Sensey’s AAR
18
@nisrulz
Slide 19
Slide 19 text
Sensey’s AAR
No build.gradle file
19
@nisrulz
Slide 20
Slide 20 text
Maven Artifact
20
@nisrulz
Slide 21
Slide 21 text
Maven Artifact
21
@nisrulz
Slide 22
Slide 22 text
POM?
22
@nisrulz
Slide 23
Slide 23 text
POM
● Project Object Model
● XML file
● Configuration details used by Maven to build the project
23
@nisrulz
Slide 24
Slide 24 text
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 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
...
24
@nisrulz
Slide 25
Slide 25 text
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 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
...
25
@nisrulz
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'
}
...
}
28
@nisrulz
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
31
@nisrulz
Slide 32
Slide 32 text
Bundled Proguard Configs
# To check the merged configuration
# Add the below to your current config
-printconfiguration proguard-merged-config.txt
32
@nisrulz
Slide 33
Slide 33 text
Bundled Proguard Configs
# DON'T DO THIS
-dontobfuscate
-optimizations !code/allocation/variable
# Effectively no optimizations
-keep public class * {
public protected *;
}
33
@nisrulz
Slide 34
Slide 34 text
Bundled Proguard Configs
# DON'T DO THIS
# Adding the below in library proguard rules disables
# the optimizations in the Android app
-dontoptimize
34
@nisrulz
Conflict occurs between a library & app resource
> Project will not compile
What happens when...
45
@nisrulz
Slide 46
Slide 46 text
Conflict occurs between 2 libraries integrated in the app
> Resources from library defined first in build.gradle gets
included
What happens when...
46
@nisrulz
Slide 47
Slide 47 text
Solution?
47
@nisrulz
Slide 48
Slide 48 text
Add a prefix to all your resources.
Solution?
48
@nisrulz
Slide 49
Slide 49 text
Add a prefix to all your resources.
How?
Solution?
49
@nisrulz
Slide 50
Slide 50 text
Add a prefix to all your resources.
How?
● Enforce this in Android Studio
Solution?
50
@nisrulz
Slide 51
Slide 51 text
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?
51
@nisrulz
Slide 52
Slide 52 text
Solution?
Resource named ‘app_name’ does not start with the project’s
resource prefix ‘sensey_’;
Rename to `sensey_app_name`?
52
@nisrulz
Slide 53
Slide 53 text
minSdkVersion Restriction
53
@nisrulz
Slide 54
Slide 54 text
minSdkVersion of app >= minSdkVersion of library
minSdk Restriction
54
@nisrulz
Slide 55
Slide 55 text
minSdk Restriction
55
@nisrulz
Slide 56
Slide 56 text
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
56
@nisrulz
Slide 57
Slide 57 text
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
57
@nisrulz
Slide 58
Slide 58 text
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
58
@nisrulz
Slide 59
Slide 59 text
...
minSdk Restriction
59
@nisrulz
Slide 60
Slide 60 text
...
minSdk Restriction
60
@nisrulz
Slide 61
Slide 61 text
Access Visibility
vs
Code Organization
61
@nisrulz
Slide 62
Slide 62 text
Visibility vs Organization
62
@nisrulz
Slide 63
Slide 63 text
Visibility vs Organization
● Code organized in individual packages; everything is
public
63
@nisrulz
Slide 64
Slide 64 text
Visibility vs Organization
● Code organized inside one package; everything is package
private and only public on demand
64
@nisrulz
Slide 65
Slide 65 text
Visibility vs Organization
● Code organized inside the module i.e individual
packages; everything is internal and only public on
demand (in Kotlin land)
● Drawback
○ Need dependency on kotlin std library
65
@nisrulz
Slide 66
Slide 66 text
Visibility vs Organization
// file name: exampleLibrary.kt
// module name: example
package com.example.library
66
@nisrulz
Slide 67
Slide 67 text
Visibility vs Organization
// file name: exampleLibrary.kt
// module name: example
package com.example.library
// visible inside exampleLibrary.kt
private fun setup() { ... }
67
@nisrulz
Slide 68
Slide 68 text
Visibility vs Organization
// 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{...}
68
@nisrulz
Slide 69
Slide 69 text
Visibility vs Organization
// 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"
69
@nisrulz
Slide 70
Slide 70 text
Lifecycle-Aware
Android Library
70
@nisrulz
Slide 71
Slide 71 text
Lifecycle Components
Classes designed to help deal with Android
lifecycle
● Lifecycle
● LifecycleOwner
● LifecycleObserver
71
@nisrulz
Slide 72
Slide 72 text
Lifecycle Components
Classes designed to help deal with Android
lifecycle
72
@nisrulz
Slide 73
Slide 73 text
Lifecycle Components
Classes designed to help deal with Android
lifecycle
i.e Activity, Fragment, Service, Custom
73
@nisrulz
Slide 74
Slide 74 text
Lifecycle
class MainActivity extends AppCompatActivity() {...}
74
@nisrulz
Slide 75
Slide 75 text
Lifecycle
class MainActivity extends AppCompatActivity() {...}
public class AppCompatActivity extends FragmentActivity{...}
75
@nisrulz
Slide 76
Slide 76 text
Lifecycle
class MainActivity extends AppCompatActivity() {...}
public class AppCompatActivity extends FragmentActivity{...}
public class FragmentActivity extends SupportActivity {
...
public Lifecycle getLifecycle() {
return super.getLifecycle();
}
...
}
76
@nisrulz
ProcessLifecycleOwner
// Internal class to initialize Lifecycles.
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
...
ProcessLifecycleOwner.init(getContext());
return true;
}
...
}
93
@nisrulz
Slide 94
Slide 94 text
ProcessLifecycleOwner
Why?
To invoke ProcessLifecycleOwner as soon as process
starts
94
@nisrulz
Slide 95
Slide 95 text
ProcessLifecycleOwner
Why?
To invoke ProcessLifecycleOwner as soon as process
starts
Drawback?
Initializes ProcessLifecycleOwner even if your app
does not use it!
95
@nisrulz
Slide 96
Slide 96 text
ProcessLifecycleOwner
How to get rid of it in app?
96
@nisrulz
Slide 97
Slide 97 text
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"
97
@nisrulz
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
103
@nisrulz
Slide 104
Slide 104 text
AutoInit Android Library
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Init android library
MyAwesomeLibrary.init(this);
}
}
104
@nisrulz
Slide 105
Slide 105 text
AutoInit Android Library
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Init android library
MyAwesomeLibrary.init(this);
}
}
105
@nisrulz
Slide 106
Slide 106 text
AutoInit Android Library
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Init android library
MyAwesomeLibrary.init(this);
}
}
106
@nisrulz
Slide 107
Slide 107 text
AutoInit Android Library
107
@nisrulz
Slide 108
Slide 108 text
AutoInit Android Library
108
@nisrulz
Slide 109
Slide 109 text
AutoInit Android Library
ContentProvider can be used to simplify the process.
109
@nisrulz
Slide 110
Slide 110 text
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.
110
@nisrulz
Slide 111
Slide 111 text
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;
}
...
}
111
@nisrulz
Slide 112
Slide 112 text
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;
}
...
}
112
@nisrulz
Slide 113
Slide 113 text
AutoInit Android Library
113
@nisrulz
Slide 114
Slide 114 text
AutoInit Android Library
114
@nisrulz
Slide 115
Slide 115 text
AutoInit Android Library
115
@nisrulz
Slide 116
Slide 116 text
AutoInit Android Library
116
@nisrulz
Slide 117
Slide 117 text
AutoInit Android Library
ContentProvider can be used to simplify the process.
117
@nisrulz
Slide 118
Slide 118 text
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
118
@nisrulz
Slide 119
Slide 119 text
AutoInit Android Library
ContentProvider can be used to simplify the process.
119
@nisrulz
Slide 120
Slide 120 text
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
120
@nisrulz
Slide 121
Slide 121 text
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
121
@nisrulz
Slide 122
Slide 122 text
AutoInit Android Library
Some android libraries that use this...
122
@nisrulz