You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter是否支持Dynamic Delivery?基于Flutter如何实现该功能?

Absolutely! Flutter apps do support Dynamic Delivery via Android App Bundles (AAB) — this is a fully supported workflow for Android-targeted Flutter apps. Let’s walk through how to make it work, step by step:

Can Flutter Apps Use Dynamic Delivery?

Short answer: Yes. Flutter’s default build pipeline supports generating Android App Bundles, which is the prerequisite for Google Play’s Dynamic Delivery system. This means you can leverage features like on-demand module delivery, feature-based APK splitting, and language/device-specific asset delivery just like native Android apps.

Step-by-Step Implementation Guide

1. Start with the Android App Bundle

First, make sure you’re building an AAB instead of a universal APK. Flutter makes this easy:

  • Run the command:
    flutter build appbundle
    

This generates an AAB in build/app/outputs/bundle/release/ — this file is what you’ll upload to Google Play to enable Dynamic Delivery.

2. Add a Dynamic Feature Module

Dynamic Delivery relies on splitting your app into modules. Since this is an Android-specific feature, you’ll need to configure this in the Android portion of your Flutter project:

  • Open your Flutter project in Android Studio, right-click the android/app module > New > Module
  • Select Dynamic Feature Module from the list, then follow the wizard:
    • Name your module (e.g., dynamic_payments or advanced_features)
    • Choose the module type (e.g., "Feature module with empty activity" if you’re adding native UI, or "Empty dynamic feature module" for assets/libraries)
    • Link it to your main app module
  • In your dynamic module’s build.gradle file, add dependencies for the Play Core library (required for module loading) and Flutter:
    dependencies {
        implementation project(':app')
        implementation 'com.google.android.play:core:1.10.3' // Use the latest version
        implementation flutterDependencies
    }
    

3. Connect Flutter to Dynamic Module Loading

Since Flutter runs on a separate thread, you’ll use a MethodChannel to call Android native code that handles module installation:

Android Native Side (Kotlin)

In your MainActivity.kt, set up the channel to handle module load requests:

import com.google.android.play.core.splitinstall.SplitInstallManagerFactory
import com.google.android.play.core.splitinstall.SplitInstallRequest
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "your.app.package/dynamic_module"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "loadModule" -> {
                    val moduleName = call.argument<String>("moduleName") ?: run {
                        result.error("INVALID_ARG", "Module name cannot be null", null)
                        return@setMethodCallHandler
                    }

                    val splitInstallManager = SplitInstallManagerFactory.create(this)
                    val request = SplitInstallRequest.newBuilder()
                        .addModule(moduleName)
                        .build()

                    splitInstallManager.startInstall(request)
                        .addOnSuccessListener { result.success("Module $moduleName loaded successfully") }
                        .addOnFailureListener { result.error("LOAD_FAILED", it.message, null) }
                }
                else -> result.notImplemented()
            }
        }
    }
}

Flutter Side (Dart)

Create a helper class to invoke the native method:

import 'package:flutter/services.dart';

class DynamicModuleLoader {
  static const _channel = MethodChannel('your.app.package/dynamic_module');

  static Future<String?> loadModule(String moduleName) async {
    try {
      return await _channel.invokeMethod('loadModule', {'moduleName': moduleName});
    } on PlatformException catch (e) {
      return 'Error loading module: ${e.message}';
    }
  }
}

You can call this from your Flutter UI (e.g., a button press) to trigger on-demand module loading.

4. Test the Workflow

  • Local Testing: Use Android Studio’s App Bundle Explorer to inspect your AAB and generate device-specific APKs. You can also use bundletool to install split APKs directly:
    bundletool build-apks --bundle=build/app/outputs/bundle/release/app-release.aab --output=app.apks
    bundletool install-apks --apks=app.apks
    
  • Play Store Testing: For full on-demand delivery testing, upload your AAB to Google Play’s internal testing channel and install it via the Play Store app — this replicates the real-world user experience.

Key Considerations

  • Dynamic Flutter Code: If you want to dynamically load Dart code (not just native modules), you’ll need additional tools like Flutter’s Module Federation or third-party code-splitting libraries. Android’s Dynamic Delivery handles native modules/assets, while Flutter’s own tools manage Dart code splitting.
  • Play Core Updates: Always use the latest version of the Play Core library to avoid compatibility issues with newer Android versions.
  • Module Constraints: Dynamic modules can’t contain components required by your main app (e.g., launch activities). Stick to optional features, assets, or libraries.

内容的提问来源于stack exchange,提问作者Prasanth PK

火山引擎 最新活动