MVP design pattern is the best design pattern in Android for building Android applications. We have already practiced MVP architecture design pattern in Android with Java library.
If You are still not using this design pattern then I would be recommended to start using this pattern from today onwards. It solves the best code practice and easy to test and maintenance of your code. Any developer can easily understand the code and easily add any new feature or changes to code in the future if required. Here is the post was written about the best design pattern for Android.
1. MVP design pattern in Android Java
2. MVVM design pattern in Android Java.
In this tutorial, we will learn MVP best design pattern in Kotlin by using awesome library Retrofit, Dagger2 dependency injection, Anko – SQLite database wrapper and Reactive RxJava and RxAndroid. If you want to know more about these libraries then I recommended checking these posts. It will help you to understand better.
Retrofit: Retrofit is the awesome library for networking operation in android. It can handle multiple requests, Cashing feature and easy to handle an error. Please check this post API call easy by Retrofit to get more detail about to how to use Retrofit in Kotlin android?
Dagger2: Dagger 2 is awesome Java library which provides the alternative way of Object instantiation. You do not worry about the constructor with a different type of argument. Dagger 2 will take care automatically based on the qualifier. Please check this post Dagger2 Dependency Injection to get more detail about the Dagger2.
Anko – SQLite database: Anko is the kotlin library for android SQLite database for better, easier and faster Android development. Please check this post Integration of Anko – SQLite database wrapper to get more detail about the Anko – SQLite.
Reactive Nature: RxJava and RxAndroid are getting popular to use in the Android application. Many of the developers they are supporting to use RxJava in building an Android app. They are getting the good response to find that it taking the Android app up to next level. Please check these post of reactive nature to better understand. RxJava2 in Android Part-1, RxJava in Android part-2 and Understanding Java 8 Stream and RxJava2 Observable in Android.
MVP in Kotlin is also not very tough to use. All are similar to Java as we used earlier. Ok, let’s see how we can use same design pattern in Kotlin? MVP is Model View Presenter. Every Module has separate model and presenter. A presenter is responsible for communicating with Model and View. All model and business logic will be in presenter class.
First of all, we need to create the base contract class of interface with Presenter and View.
class BaseContract { interface Presenter<in T>{ fun subscribe() fun unSubscribe() fun attachView(view : T) } interface View { } }
Now I need to implement this BaseContract class with each of Module contract. For example In one of my module for getting friend’s detail from the list of friends is used.
class FriendsDetailContract { interface Presenter : BaseContract.Presenter<View>{ fun loadUserDetail(userID : String) } interface View : BaseContract.View{ fun onLoadUserDetailOk(friends : Friends.User) fun showLoadErrorMessage(error : String) } }
Now I need to implement this in Presenter class and Fragment or Activity class.
class FriendsDetailPresenter : FriendsDetailContract.Presenter{ private val subscriptions = CompositeDisposable() private lateinit var view: FriendsDetailContract.View override fun subscribe() { } override fun unSubscribe() { subscriptions.clear() } override fun attachView(view: FriendsDetailContract.View) { this.view = view } override fun loadUserDetail(userId: String) { var observableUser = DbManager().detailFriend(userId) var subscribe = observableUser.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({user: Friends.User? -> view.onLoadUserDetailOk(user!!) }, { t: Throwable? -> view.showLoadErrorMessage(t!!.message.toString())}) subscriptions.add(subscribe) } }
Reactive nature will avoid the memory leak because it interacts with the view when presenter will be subscribed. If the subscription will not available then it will not update the view or you will not get notify event to update the view. What do we need to do for that? we just need to subscribe presenter when view created and unsubscribe when view or activity is detached or destroyed.
class FriendsDetailFragment : Fragment(), FriendsDetailContract.View{ @Inject lateinit var presenter: FriendsDetailContract.Presenter private lateinit var mRootView : View @BindView(R.id.name) @JvmField var nameTextView: TextView? = null @BindView(R.id.email) @JvmField var emailTextView : TextView? = null private var friendId : String? = null fun newInstance(): FriendsDetailFragment { return FriendsDetailFragment() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) injectDependency() presenter.attachView(this) val bundle = this.arguments if (bundle != null) { friendId = bundle.getString("UserId") } } private fun injectDependency() { val friendsDetailComponent = DaggerFriendsDetailComponent.builder() .friendsDetailModule(FriendsDetailModule()) .build() friendsDetailComponent.inject(this) } override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) presenter.subscribe() } override fun onDestroyView() { super.onDestroyView() presenter.unSubscribe() } override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View { mRootView = inflater!!.inflate(R.layout.fragment_user_detail, container, false) ButterKnife.bind(this, mRootView) initView() return mRootView } private fun initView(){ presenter.loadUserDetail(friendId!!) } override fun onLoadUserDetailOk(friends: Friends.User) { nameTextView!!.text = friends.name // property concept emailTextView!!.text = friends.email } override fun showLoadErrorMessage(error: String) { Toast.makeText(activity, error, Toast.LENGTH_LONG).show() } }
In above FreindsDetailFragment class, we have seen that presenter is injected by Dagger2 for an object instantiated as based on the qualifier.
Wrapping Up: MVP is best architectural based design pattern. It provides the best code practice, easy to use and maintenance and easy for the JUnit testing for a developer. You can build an awesome Android application by using MVP design pattern with all these libraries.
Here is the Github of full source code for practice more.
Please do subscribe email to get all newsletters of this blog and if you feel that this post will help you to better understand then do not forget to subscribe, share and comment below. Ok, then I will see you in my next tutorial till then enjoy your life and coding 🙂
I am a very enthusiastic Android developer to build solid Android apps. I have a keen interest in developing for Android and have published apps to the Google Play Store. I always open to learning new technologies. For any help drop us a line anytime at contact@mobologicplus.com