Flutter集成Android項(xiàng)目及踩坑記錄

在現(xiàn)有項(xiàng)目上集成Flutter

1.在andorid工程目錄上級(jí)目錄下執(zhí)行命令:

flutter create -t module xxxx(想要?jiǎng)?chuàng)建的flutter項(xiàng)目名)

執(zhí)行完后,一個(gè)和Android項(xiàng)目平級(jí)的flutter項(xiàng)目就已經(jīng)創(chuàng)建好了。

2.添加flutter到當(dāng)前Android項(xiàng)目:
在Android項(xiàng)目根目錄下的settings.gradle文件中,添加如下代碼:

setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        "flutter_hybrid/.android/include_flutter.groovy"
))

然后,在項(xiàng)目的app目錄下,build.gradle文件中,添加如下dependency:

implementation project(':flutter')

如上,添加完之后,準(zhǔn)備工作就完成了。

集成Flutter頁(yè)面跳轉(zhuǎn)

通過(guò)繼承FlutterActivity跳到默認(rèn)頁(yè)面

1.Application:初始化Flutter

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        FlutterMain.startInitialization(this);
    }
}

2.Activity:繼承FlutterActivity

/**
 * debug模式原生跳轉(zhuǎn)到flutter界面會(huì)出現(xiàn)白屏,release包就不會(huì)出現(xiàn)白屏了
 */
public class MainFlutterActivity extends FlutterActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
  }

這樣以后,我們就可以跳轉(zhuǎn)這個(gè)MainFlutterActivity,實(shí)現(xiàn)在Android工程里面進(jìn)入Flutter工程的默認(rèn)頁(yè)面了。

通過(guò)FlutterView跳到指定頁(yè)面

首先通過(guò)Flutter.createFlutterView方法來(lái)創(chuàng)建一個(gè)FlutterView類型的View。它有三個(gè)構(gòu)造參數(shù):

public static FlutterView createView(Activity activity, Lifecycle lifecycle, String initialRoute)

三個(gè)參數(shù)分別是:
1.Activity,即當(dāng)前附著的Activity

2.LifeCycle,且是不能為空(NonNull)的,這也就要求我們必須用AppCompatActivity來(lái)承載FlutterView了,如果我們的Activity繼承自android.app.Activity是沒(méi)有g(shù)etLifeCycle()這個(gè)方法的。

public class FlutterViewActivity extends AppCompatActivity 復(fù)制代碼

3.initialRoute這是一個(gè)String類型的變量,根據(jù)不同的標(biāo)識(shí)跳轉(zhuǎn)不同的Flutter頁(yè)面:

Widget _widgetForRoute(String route) {
  switch (route) {
    case 'route1':
      return  MyHomePage(title: 'Flutter Demo Home Page1');
    case 'route2':
      return  MyHomePage(title: 'Flutter Demo Home Page2');
    default:
        return  MyHomePage(title: 'Flutter Demo Home Page2');
  }
}

然后在當(dāng)前Activity的OnCreate方法中,執(zhí)行:

FlutterView flutterView = Flutter.createView(this, getLifecycle(), "route1");   
setContentView(flutterView);

//或者:

setContentView(R.layout.activity_flutter);
rlContainer = findViewById(R.id.rl_container);
rlContainer.addView(flutterView)

集成到現(xiàn)有項(xiàng)目遇到的坑

Check failed: vm. Must be able to initialize the VM:

E/flutter: [ERROR:flutter/runtime/dart_vm_data.cc(19)] VM snapshot invalid and could not be inferred from settings.
    [ERROR:flutter/runtime/dart_vm.cc(241)] Could not setup VM data to bootstrap the VM from.
    [ERROR:flutter/runtime/dart_vm_lifecycle.cc(89)] Could not create Dart VM instance.
 A/flutter: [FATAL:flutter/shell/common/shell.cc(218)] Check failed: vm. Must be able to initialize the VM.

SIGABRT
    0x146b
    #00    pc 0002210c    /system/lib/libc.so (tgkill+12) [armeabi-v7a::ac712d92afdda143205c7d7c8befc336]
    #01    pc 00013165    /system/lib/libc.so (pthread_kill+48) [armeabi-v7a::ac712d92afdda143205c7d7c8befc336]
    #02    pc 00013379    /system/lib/libc.so (raise+10) [armeabi-v7a::ac712d92afdda143205c7d7c8befc336]
    #03    pc 000120a3    /system/lib/libc.so [armeabi-v7a::ac712d92afdda143205c7d7c8befc336]
    #04    pc 000219c0    /system/lib/libc.so (abort+4) [armeabi-v7a::ac712d92afdda143205c7d7c8befc336]
    #05    pc 00af85ab    /data/app-lib/xxx.debug-1/libflutter.so [armeabi-v7a::a12434e0b53806a35730000001000000]

經(jīng)github上#24679及其他issue參考,得出以下解決方案:

Import flutter module to your HOST app(set binding, implementation, and instantiate view/fragment)
When you clean/rebuild from HOST app, flutter module does not generate properly
You need to open your flutter module in a separate AS
flutter clean
cd .android
./gradlew clean
./gradlew assembleDebug
Return to host app and run app(do not sync or rebuild) :)

翻譯過(guò)來(lái)就是:

本項(xiàng)目執(zhí)行清理命令。./gradlew clean
進(jìn)入 flutter module 項(xiàng)目執(zhí)行清理命令。flutter packages get;flutter clean
進(jìn)入 flutter module 的 .android 項(xiàng)目執(zhí)行清理命令和打包操作。./gradlew clean;./gradlew assemble
回到本項(xiàng)目執(zhí)行打包命令。./gradlew assemble

直接執(zhí)行下面命令即可:

$ ./gradlew clean;cd ../flutter_module;flutter packages get;flutter clean;cd .android/;./gradlew clean;./gradlew assemble;cd /d/workspace/app_proj/;./gradlew installDebug

后續(xù)假設(shè)你 flutter module 沒(méi)有更新過(guò),那么以后修改本地項(xiàng)目之后,就直接執(zhí)行./gradlew installDebug。 注意不要用studio工具運(yùn)行、rebuild或clean。

flutter_assets

assets下缺少flutter_assets也有可能造成此問(wèn)題。具體可以參考:http://www.itdecent.cn/p/2d0bba84e57e

混淆

按照上述方式,debug版本沒(méi)問(wèn)題,release卻報(bào)錯(cuò)。需加以下混淆:

-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.* { *; }
-keep class io.flutter.util.* { *; }
-keep class io.flutter.view.* { *; }
-keep class io.flutter.* { *; }
-keep class io.flutter.plugins.* { *; }
-keep class myapp.flutter.*

參考資料

https://github.com/chinaltz/FlutterDemo
https://juejin.im/post/5c74dbeee51d45708f2a20c6
https://github.com/flutter/flutter/issues/24679
https://github.com/flutter/flutter/issues/25147
https://mp.weixin.qq.com/s/OGbH3G3wHVTUt-0EJit8RA

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容