Transisi dari Native (Kotlin/Java) ke Cross-Platform (Flutter): Sebuah Retrospektif

I Nyoman Donostia 798 kata
Transisi dari Native (Kotlin/Java) ke Cross-Platform (Flutter): Sebuah Retrospektif

Latar Belakang

Awalnya saya adalah Android developer murni — 2 tahun kerja dengan Kotlin dan Java. Lalu proyek perusahaan memerlukan aplikasi iOS dan Android secara bersamaan dengan waktu development yang ketat. Flutter tampil sebagai solusi. Transisi ini bukan hanya ganti bahasa pemrograman, tapi pergeseran mindset arsitektur.

Artikel ini adalah retrospektif tulus tentang pengalaman transisi tersebut.

Kecepatan Development: Hot Reload Changes Everything

Native (Android Studio)

Waktu iterasi tipikal saat develop fitur di native:

  1. Edit Kotlin code
  2. Build project (~30-60 detik untuk project besar)
  3. Install APK (~10-20 detik)
  4. Restart app (~5 detik)
  5. Navigate ke screen yang diedit

Total waktu per iterasi: ~1-2 menit.

Flutter

Flutter dengan hot reload: edit code → tekan r → lihat perubahan dalam < 1 detik. State tetap dipertahankan!

// Ubah warna background di mana saja dalam widget tree
Container(
  color: Colors.blue,  // ← Ubah ke Colors.red
  child: Text('Hello'),
)
// Tekan 'r' → Hasil langsung terlihat

Selama 6 bulan pertama, saya merasa produktivitas naik 3-4x dibanding native. Untuk iterasi UI eksperimental, Flutter menang mutlak.

Native Module Integration: Ketika Turun ke Low-Level

Tidak semua bisa diselesaikan dengan Dart. Saat butuh akses hardware spesifik, kita harus menggunakan Platform Channels.

Contoh: Akses Bluetooth Low Energy (BLE)

Kotlin (Native Android):

// Native code lebih straightforward
val bluetoothManager = getSystemService(BluetoothManager::class.java)
val adapter = bluetoothManager.adapter
adapter.bluetoothLeScanner.startScan(scanCallback)

Flutter dengan Platform Channel:

// Flutter side
import 'package:flutter/services.dart';

class BleService {
  static const platform = MethodChannel('com.app/ble');
  
  Future<List<BluetoothDevice>> scan() async {
    final devices = await platform.invokeMethod('scan');
    return (devices as List).map((d) => BluetoothDevice.fromMap(d)).toList();
  }
}
// Android side - MainActivity.kt
class MainActivity : FlutterActivity() {
  override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.app/ble")
      .setMethodCallHandler { call, result ->
        when (call.method) {
          "scan" -> startBleScan(result)
          else -> result.notImplemented()
        }
      }
  }
}

Trade-off: integrasi native di Flutter butuh boilerplate. Untuk fitur yang 80% biasanya non-UI (camera, sensors, BLE, NFC), native lebih straightforward.

Trade-off Performa

1. Smooth Scrolling 60fps

Native dengan RecyclerView + ViewHolder: butter smooth 60fps, tidak ada Pertanyaan.

Flutter dengan ListView.builder dan const widgets: bisa mencapai 60fps, tapi lebih sensitive terhadap widget complexity. Widget tree yang dalam dan rebuild yang tidak terkontrol akan drop ke 30-45fps.

// 🚫 Rebuild semua item di list
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, i) {
    return ListTile(
      title: Text(items[i].name),
      // Setiap rebuild, semua dipanggil ulang
    );
  },
)

// ✅ Wrap dengan const untuk hindari rebuild
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, i) {
    return ListTile(
      title: Text(items[i].name),
      key: ValueKey(items[i].id),
    );
  },
)

2. Animasi 60fps

Native: AnimProperty dan Lottie native — sangat halus.

Flutter: AnimatedContainer dan AnimationController — juga 60fps, tetapi perlu hati-hati dengan setState() yang trigger rebuild global.

3. Memory Usage

Native Android app: ~30-50MB baseline.

Flutter app: ~80-120MB baseline (karena Flutter engine di-embed). Trade-off untuk unified codebase.

Ekosistem: Pub.dev vs Gradle/Maven

Native Android

  • Library sangat mature (terutama Google libraries: CameraX, Room, WorkManager)
  • Integrasi native services (Google Maps, Firebase) official dan first-class
  • Tapi banyak vendor library hanya untuk Android

Flutter

  • Library cross-platform (pub.dev)
  • Vendor seperti Google Maps, Firebase punya official plugin, tapi kualitas bisa bervariasi
  • Untuk hal yang niche (e.g., video editor NATIF), jarang ada plugin matang
  • Plugin populer 4-5 tahun lalu kadang tidak maintained

Verdict: Native menang untuk library maturity dan integrasi vendor spesifik. Flutter menang untuk produktivitas lintas platform.

Code Samples Side-by-Side

Hello World Card dengan Click Listener

Kotlin:

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val card = CardView(this).apply {
     .cardElevation = 8f
      addView(TextView(context).apply {
        text = "Click me"
        setOnClickListener { Toast.makeText(context, "Clicked!", LENGTH_SHORT).show() }
      })
    }
    setContentView(card)
  }
}

Flutter:

@override
Widget build(BuildContext context) {
  return Card(
    elevation: 8,
    child: InkWell(
      onTap: () => ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Clicked!'))),
      child: Text('Click me'),
    ),
  );
}

Flutter lebih concise. Plus, kode yang sama berjalan di iOS tanpa modifikasi.

Kapan Tetap di Native?

Pilih native (Kotlin/Java) jika:

  • Aplikasi very performance-critical (game, video processing real-time)
  • Butuh integrasi hardware yang spesifik (BLE, NFC, kamera advanced)
  • Tim Anda adalah specialist Android
  • Aplikasi internal enterprise dengan integrasi service Google spesifik (e.g., Android Management API)

Kapan Pilih Flutter?

  • Cross-platform priority (perlu iOS + Android)
  • Iterasi UI cepat / eksperimen desain
  • Tim kecil dengan banyak domain (fullstack)
  • Content-driven app (e-commerce, social media, news)
  • Startup dengan MVP cepat

Kesimpulan

Setelah 1 tahun+ dengan Flutter, saya tidak akan kembali ke pure native untuk project cross-platform. Produktivitas, hot reload, dan codebase tunggal terlalu valuable. Tapi saya tetap memelihara skill Kotlin — karena saat perlu turun ke native modules, skill itu irreplaceable.

Flutter bukan pengganti native. Flutter adalah penambah skill — buah: native adalah pondasi, Flutter adalah multiplier produktivitas. Menguasai keduanya adalah sweet spot.

I Nyoman Donostia

I Nyoman Donostia

Fullstack Developer - Bali, Indonesia

Artikel Terkait