tutorials2026-11-087 menit

Arsitektur WebView Offline-First di Android & Komunikasi JS Bridge Aman

Panduan praktis menyajikan korpus data besar 100% offline di dalam APK menggunakan WebViewAssetLoader dan antarmuka Java-JS yang terisolasi.

#Android

Mengapa Hindari file:///android_asset/ Langsung?

Banyak aplikasi hybrid lawas memuat file:///android_asset/index.html, yang sering menabrak aturan CORS pada <script type="module">, Fetch API lokal, maupun localStorage lintas rute. Solusi modern di AndroidX WebKit adalah WebViewAssetLoader.

MainActivity.java JAVA
WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
    .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this))
    .build();

webView.setWebViewClient(new WebViewClientCompat() {
    @Override
    public WebResourceResponse shouldInterceptRequest(
            WebView view, WebResourceRequest request) {
        return assetLoader.shouldInterceptRequest(request.getUrl());
    }
});

webView.loadUrl("https://appassets.androidplatform.net/assets/www/index.html");

Mengamankan JavascriptInterface untuk Ekspor File & TTS

Pada aplikasi seperti AHM OmniJuris, Web UI memicu Android Text-to-Speech native serta penyimpanan file .md ke folder Download/. Pastikan hanya metode eksplisit dengan @JavascriptInterface yang terekspos dan validasi setiap input string sebelum menyentuh MediaStore.

NativeBridge.java JAVA
@JavascriptInterface
public void speakIndonesian(String text, float rate) {
    if (text == null || text.length() > 8000) return;
    float safeRate = Math.max(0.75f, Math.min(1.75f, rate));
    mainHandler.post(() -> ttsManager.speak(text, safeRate));
}

Checklist Produksi APK Hybrid

  1. Nonaktifkan setAllowFileAccessFromFileURLs(false) dan setAllowUniversalAccessFromFileURLs(false).
  2. Gunakan https://appassets.androidplatform.net/ agar ES Modules, WebAssembly, dan Worker lokal berjalan seperti HTTPS standar.
  3. Simpan seluruh aset font dan korpus JSON/JS di app/src/main/assets/ agar tetap berfungsi tanpa sinyal internet.