Android App From Scratch Part 2 — Implementing Must Have Libraries
In this tutorial series, I will try to create an RSS Reader app step by step. Through this series I will explain:
- How to use Model-View-Presenter in an Android App
- Implementing must have libraries
- Implementing App Logic
- Creating unit tests with JUnit
- Creating Android Instrumentations tests with Espresso
- Continuous Integration with Travis-CI
This article is the second part of a series.
Open source libraries make life easier. There are many awesome libraries we should use in our apps.
We will use these libraries:
- Dagger2
- Retrofit
- OkHttp Logging Interceptor
- RetrofitRssConverterFactory
- Leakcanary
- Picasso
- Chrome Custom Tabs
Dagger2
Dagger2 is a Dependency Injection library. I will implement it to this RSS Reader app. At first add these dependencies to app gradle file:
implementation "com.google.dagger:dagger:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
implementation "com.google.code.findbugs:jsr305:$findbugs_version"
Passing DaggerActivityComponent to ActivitiesBaseActivity.kt
abstract class BaseActivity : AppCompatActivity(), BaseView {
/**
* Layout resource to be inflated
*
* @return layout resource
*/
@get:LayoutRes
protected abstract val layoutResource: Int
abstract fun inject(component: ActivityComponent)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(layoutResource)
inject(DaggerActivityComponent.builder()
.appComponent(NewsApp.component())
.activityModule(ActivityModule(this))
.build())
init(savedInstanceState)
}
/**
* Initializations
*/
protected abstract fun init(state: Bundle?)
}
Now I create the presenter by injecting it. This approach is better than we did in part1. Each activity must implement the inject()
method to make injections.
class MainActivity : BaseActivity(), MainContract.View {
@Inject
lateinit var mPresenter: MainContract.Presenter
private lateinit var wrapper: ChromeTabsWrapper
override val layoutResource = R.layout.activity_main
override fun inject(component: ActivityComponent) {
component.inject(this)
}
override fun init(state: Bundle?) {
mPresenter.attach(this)
mPresenter.loadHelloText()
tvHello.setOnClickListener {
mPresenter.loadHelloText()
}
wrapper = ChromeTabsWrapper(this)
}
override fun onTextLoaded(text: String) {
tvHello.text = text
}
override fun onStart() {
super.onStart()
wrapper.bindCustomTabsService()
}
override fun onStop() {
super.onStop()
wrapper.unbindCustomTabsService()
}
override fun onDestroy() {
super.onDestroy()
mPresenter.detach()
}
}
But the magic is here in DI Components and Modules:
@ActivityScope
@Component(dependencies = [AppComponent::class], modules = [ActivityModule::class])
interface ActivityComponent {
fun mainPresenter(): MainContract.Presenter
fun inject(mainActivity: MainActivity)
}
Module: Defining the injection
It is important that provideMainPresenter()
method’s return type is MainContract.Presenter
NOT MainPresenter
We do abstraction by returning interface instead of the class.
@Module
class ActivityModule(private val activity: FragmentActivity) {
@Provides
@ActivityScope
fun provideMainPresenter(service: RssService): MainContract.Presenter = MainPresenter(service)
}
Run the app. You can see that the behaviour is the same.
For more detailed explanation of Dagger2 you can see:
Retrofit
This awesome library is the most used Networking library. Retrofit is a type-safe Http client for Android and Java.
OkHttp Logging Interceptor
Logger for OkHttp request/responses.
RetrofitRssConverterFactory
A Retrofit 2 converter which parses Rss feeds. Optimized for RSS feed. Parses better than SimpleXmlConverterFactory.
LeakCanary
A memory leak detection library for Android and Java.
“A small leak will sink a great ship.” — Benjamin Franklin
This is an awesome library for leak detection. Start using it when you build the project. If you make a mistake that leaks, you would find as early as possible.
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
In Application class:
public class RssApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
Picasso
Picasso is a great Image downloading and caching library. It has some alternatives. But we will use this.
compile 'com.squareup.picasso:picasso:2.5.2'
Chrome Custom Tabs
Chrome Custom Tabs give apps more control over their web experience, and make transitions between native and web content more seamless without having to resort to a WebView.
I will use this to browse RSS urls. I created a wrapper named ChromeTabsWrapper
for Chrome Custom tabs operation. It is injected into MainActivity
private lateinit var wrapper: ChromeTabsWrapper...override fun onStart() {
super.onStart()
wrapper.bindCustomTabsService()
}
override fun onStop() {
super.onStop()
wrapper.unbindCustomTabsService()
}...
Here is the source code for part2:
You can go on reading with Part3
Continue reading the next part?
If you liked the article, please 👏👏👏 so more people can see it! Also, you can follow me on Medium