Membuat Modularization di Android, Resume GDG Depok, Sabtu 23 Februari 2019

Muhammad Firdaus
6 min readFeb 23, 2019

--

  1. Monolith

Bagi pemula kita biasa menggunakan metode ini, dengan mengumpulkan semua fitur ke dalam satu tempat kumpul

Mari kita lihat, bagaimana Gojek bekerja dengan berbagai fitur, akan ada satu tempat yang besar dimana terkumpulnya fitur aplikasi gojek

Ini berdampak akan menambah berat, apabila perusahaan menjadi besar, otomatis, kompleksitas fitur akan lebih bertambah.

2. Microservice

Maka solusinya adalah semua fitur yang banyak tadi di breakdown menjadi bagian kecil kecil, dibagi bagi berdasarkan bisnis modelnya, membuat aplikasi Tix.id membutuhkan 16 orang, dibagi bagi contoh bagian desain, membership, content, agar bisa menjadi lebih fokus

Mengapa perlu Modularization

Karena kita ingin membuat aplikasi yang bisa di maintance jangka panjang, jangan memiliki pemikiran asal jadi, tapi memang benar benar harus dipikirkan bagaimana aplikasi ini bisa dikembangkan dengan jangka panjang

Suatu developer yang bagus harus memiliki guideline, salah satunya membaca buku uncle Bob “clean code”, Computational thinking, Matemathic thinking

Sekarang tidak mudah untuk bergabung dengan startup besar seperti gojek, mereka memiliki syarat knowledge yang harus kita pelajari dulu

Motivasi mengembangkan modularitaztion

Biasanya kita di dalam aplikasi di awali dengan :app di dalamnya ada, login, content, apiclient

Monolith seperti satu gudang yang penuh dengan buku

MVP atau MVVM untuk memisah ketergantungan

Modulerize, di dalam gudang memiliki rak rak buku yang berbeda beda, teratur dan tertata, seperti di perpustakaan, kita mau mencari biologi, maka kita tinggal mencari rak buku khusus biologi dan ll

Untuk membuat modulatiztion, kita harus membuat layer core, atau inti perintah/fungsi yang sepesifik dimasukkan di dalam satu tempat yaitu core, di dalam core contoh seperti ini :

  1. Core module
  2. Common
  3. Service module

Multi project build

Manfaat modularization

  1. Per module memiliki clear API

2. Di antara team memiliki kejelasan tanggung jawab

3. Maintance menjadi mudah

4. Waktu compile menjadi menurun

Perbedaan API dan Implementation

satu mendependency menggunakan api maka yang diataas tidak perlu menggunakan dependency yang sudah kita gunakan di bawah dengan api, kalau implementation, parent dan child harus dependency lagi

S.O.L.I.D, Dependency Injection, Open close principle= harus tahu agar menjadi android developer professional

tix://detail/item/78 -> URI

https://tix..id/item/78 -> utl

cara menggunakan URI dengan DEEP LINK

App Size & The Impact

Android Application Deliverables

  1. Single apk
  2. App Bundle = Instant App, Dynamic Delivery

Legacy APK = mengambil semua resource walaupun tidak dibutuhkan device

Dynamic Delivery = mengambil resource yang dibutuhkan oleh device

Gojek 29+ module

Tokoped 84+ module

How to use, Bundle

Bagi team dengan banyak programmer

Group Epic :

Membership, Catalog, Order, Payment, Delivery, Settlement

Sprint Planning : Membership Buyer

→ Wireframe

→ Story

→ Story Review = Mencocokan gambar dengan story

→ Story Carding = Menentukan fibonacy, berapa lama durasi untuk menyelesaikan pekerjaan

→ Development in a sprint : 14 Hari kerja, pertama membuat Mock API dulu dengan menggunakan swagger

→ Retro

Hands On!

Ikuti codelab berikut ini https://codelabs.developers.google.com/codelabs/your-first-dynamic-app/

  1. Membuat project baru dengan nama MyAppBundle
  2. Masukkan koding dibawah ini untuk dapat mensetting bundle
bundle {
language {
enableSplit = true
}
density {
enableSplit = true
}
abi {
enableSplit = true
}
}

Ke dalam BuildGradle, di dalam kurawal android

3. Lalu klik Build, build bundle, maka akan menghasilkan .aab

4. Lalu download bundle tool https://github.com/google/bundletool/releases/download/0.3.3/bundletool-all-0.3.3.jar

Itu tadi untuk membuat bundle, selanjutnya kita lanjutkan untuk bagaimana cara membuat aplikasi dengan Modularization

5. Membuat module, File → New Module → Dynamic Feature Module → Namakan Login → Next →Namakan Login

6. Lalu edit tampilan pada module app, di MainActivty.xml, dengan kode di bawah ini

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:gravity="center">

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/btnLogin"
android:text="Buka Login"
android:layout_margin="16dp"/>

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/btnProfile"
android:text="Buka Profile"
android:layout_margin="16dp"/>

</LinearLayout>

7. Membuat File kotlin, pada module app

8. Membuat EmptyActivity pada module login dengan nama LoginActivity pada modul profil dengan nama ProfilActvity

Maka akan merah atau error pada empty activity kita

8. Perhatikan pada BuildGradle Module:App, ubah dependency yang awalnya menggunakan Implementation dengan api

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api 'com.android.support:appcompat-v7:28.0.0'
api 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

Kenapa sepeti itu, karena kalau kita menggunakan implementation, module yang di bawah app tidak mewarisi dependency yang ada di dalam module app, maka harus di ubah ke api agar semua module dapat mewarisi depencency yang dimiliki oleh module app

9. Lalu pada layout xml pada module login activity_login.xml, edit koding seperti dibawah ini

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:text="Hello i am from module Login"
android:gravity="center"/>

</android.support.constraint.ConstraintLayout>

10. lalu pada layout xml pada module profil activity_profil.xml, edit menjadi seperti berikut

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:text="Hello i am from module Profil"
android:gravity="center"/>

</android.support.constraint.ConstraintLayout>

11. Perhatikan pada module app, kita sudah membuat file kotlin AppNavigationRouter.kt, disini kita akan mengatur untuk mempersiapkan nama package module yang ingin kita gunakan, serta membuat function untuk kita gunakan pada MainActivity untuk menjalankan Intent

masukkan koding dibawah ini ke dalam AppNavigationRouter.kt

*WARNING UNTUK NAMA PACKAGE MENYESUAIKAN DENGAN NAMA PACKAGE KALIAN :D

// Mempersiapkan variable dengan nama package project kita// HARUS DIGANTI DENGAN NAMA PACKAGE KALIAN!!!! JANGAN COPAS!!! KARENA NAMA PACKAGE KAMU DAN AKU BERBEDA :D
const val PARENT_PACKAGE = "me.firdaus1453"
const val PACKAGE_PROFILE = "$PARENT_PACKAGE.profil"
const val PACKAGE_LOGIN = "$PARENT_PACKAGE.login"
const val BUNDLE_KEY = "bundlekey"

fun openLoginActivity(context: Context, text: String){
try {

// Membuat intent
val intent = Intent(context,
Class.forName("$PACKAGE_LOGIN.LoginActivity"))
// Menambahkan data menuju activity selanjutnya
intent.putExtra(BUNDLE_KEY,text)
context.startActivity(intent)

}catch (e: Exception){
Log.d("navigation", "Activity not found")
}
}

fun openProfileActivity(context: Context){
// Berpindah activity dengan membawa DEEP LINK
val uri = Uri
.parse("appbundle://page/firdaus")

// Berpindah activity
val intent = Intent(Intent.ACTION_VIEW,uri)
context.startActivity(intent)
}

12. Lalu kita gunakan function yang sudah kita buat tadi ke dalam MainActivity.kt, masukkan koding dibawah ini ke dalam MainActivity.kt

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// Membuat button onClickListener
btnLogin.setOnClickListener {
// Menjalankan function yang sudah dibuat pada AppNavigationRouter
// Untuk berpindah Activity
openLoginActivity(this@MainActivity,"HELLO FROM BAWA DATA LOGIN")
}

// Membuat button onClickListener
btnProfile.setOnClickListener {
// Menjalankan function yang sudah dibuat pada AppNavigationRouter
// Untuk berpindah Activity
openProfileActivity(this@MainActivity)
}
}
}

13. Selanjutnya kita masukkan perintah untuk menerima data dari intent ,pada LoginActivity.kt, masukkan koding dibawah ini ke dalam LoginActivity.kt

class LoginActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)

// Menangkap data dari Intent
val data = intent.getStringExtra(BUNDLE_KEY)
// Menampilkan data yang sudah di ambil ke toast
Toast.makeText(this, data, Toast.LENGTH_SHORT).show()
}
}

14. Selanjutnya pada ProfilActivity.kt juga kita masukkan perintah untuk menerima data dari Intent

class ProfilActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profil)

// Menangkap data uri dari intent
val name = intent.data.lastPathSegment
// Menampilkan data yang sudah di ambil ke toast
Toast.makeText(this, name, Toast.LENGTH_SHORT).show()
}
}

15. Lalu terakhir, kita harus menambahkan intent filter ke dalam AndroidManifest, Activity yang sudah kita buat, karena pada saat menggunakan Intent, kita menambahkan action.VIEW, maka pada masing-masing Activity harus sudah memiliki perintah IntentFilter action.VIEW pada manifestnya, silahkan tambahkan intent filter dibawah ini ke dalam AndroidManifest di module login dan profil

<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>

Contoh ss :

16. Silahkan Run App atau Shift + F10, untuk menjalankan aplikasi kita

17. Selamat anda sudah berhasil membuat aplikasi dengan modularization :D

18. Oke cukup sekian, terima kasih banyak atas perhatiannya, keep learning and never give up, see you ❤

Yang mau source code hasil kerajinan saya, silahkan di link berikut ini :

Untuk source code dari Mas Sidiq Permana, di link berikut ini :

https://github.com/sidiqpermana/DemoDynamicFeatureModule

--

--