天天看點

android activity根節點addview_Flutter 踩坑記(Android)

android activity根節點addview_Flutter 踩坑記(Android)
持續更新中 ...

14,Flutter工程,裝置選擇中一直loading;

原因:插拔資料線的時候,莫名卡死了;

  • 解決方案:把 Android Studio 關閉,在安裝 Flutter 的路徑下進入bin/cache,然後把 lockfile 删除,然後重新開機AS;

13,同步截取兩張圖檔儲存本地時,彈出授權彈框後,點選确定,第二張圖檔截圖不全;

原因:權限彈框,導緻 Flutter 頁面 dispose, 點選确定之後,Flutter 頁面還來不及 resume,導緻第二張圖不全;

  • 解決方案:在第二張截圖之前,延時一會,await new Future.delayed(new Duration(milliseconds: 300));

12,Row 嵌套 SingleChildScrollView ,會超出像素;

  • 解決方案:SingleChildScrollView 嵌套下 Expanded,設定 flex: 1;

11,混合開發,Error: Duplicate resources;

  • 解決方案: 1,删除 flutter工程 build目錄,并且删除 flutter工程/.andorid/Flutter/build目錄; 2,根本原因是 Gradle插件版本過低,更新到 classpath 'com.android.tools.build:gradle:3.2.1';

10,混合開發,退出頁面&退出應用?

  • 解決方案:
final ModalRoute<dynamic> cRoute = ModalRoute.of(context);
    if (cRoute.canPop) {
      Navigator.pop(context); // 正常Flutter頁面回退
    } else {
      SystemNavigator.pop(); // 嘗試 Android 傳回(iOS不支援,需要單獨寫通信)
    }
           

9,相對布局?

  • 解決方案:全部可以用 Stack + Positioned 搞定;

8,利用 Padding 增加點選範圍,但是沒有效果;

  • 解決方案:

是因為預設情況下透明區域不響應事件;

需要給 GestureDetector 加上 behavior: HitTestBehavior.translucent;

還要注意設定寬高;

7,隐藏|顯示一個Widget?

  • 解決方案:建議用 Offstage 包裹一層,這樣成本是較小的;

6,FlutterFragment 放到 ViewPager 中,切換 Fragment 偶爾會黑屏;

  • 解決方案:根本原因還是 SurfaceView 的原因;
@Override
    public FlutterView onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FlutterView view = Flutter.createView(getActivity(), getLifecycle(), mRoute);
        view.setZOrderOnTop(true);
        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getView() != null) {
            getView().setVisibility(isVisibleToUser ? View.VISIBLE : View.INVISIBLE);
        }
    }
           

5,Flutter 首次加載,會黑屏一下;

  • 解決方案:https://juejin.im/entry/5b39d24f51882574eb599a3f
/**
     * 提前加載 Flutter,防止黑屏一下
     * 先建立一個隻有1個像素的視窗,完成 FlutterView 首幀渲染
     * 可以放到 LauncherActivity 裡面;
     */
    public void preInit(FragmentActivity activity) {
        FragmentActivity mFakeActivity = activity;
        final FlutterView flutterView = Flutter.createView(mFakeActivity, mFakeActivity.getLifecycle(), FlutterConst.Route.FIRST);
        final WindowManager wm = mFakeActivity.getWindowManager();
        final FrameLayout root = new FrameLayout(mFakeActivity);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(1, 1);
        root.addView(flutterView, params);
        WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
        wlp.width = 1;
        wlp.height = 1;
        wlp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        wlp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        wm.addView(root, wlp);
        final FlutterView.FirstFrameListener[] listenerRef = new FlutterView.FirstFrameListener[1];
        listenerRef[0] = new FlutterView.FirstFrameListener() {
            @Override
            public void onFirstFrame() {
                LogUtils.d("httpclientimp", "onFirstFrame");
                //首幀渲染完後取消視窗
                wm.removeView(root);
                flutterView.removeFirstFrameListener(listenerRef[0]);
            }
        };
        flutterView.addFirstFrameListener(listenerRef[0]);
//        String appBundlePath = FlutterMain.findAppBundlePath(mFakeActivity.getApplicationContext());
//        flutterView.runFromBundle(appBundlePath, null, "main", true);
    }
           

4,flutter混合開發運作報錯:VM snapshot must be valid. /Check failed: vm. Must be able to initialize the VM;

  • 解決方案:https://www.jianshu.com/p/9b96999fc385

1.在 flutter module/.android/Flutter/build.gradle,android 節點添加:

project.android.libraryVariants.all { variant ->
            def targetAssets = "${project.buildDir}/intermediates/flutter/${variant.name}"
            def customSourceSet = variant.getSourceSets()[0]
            if (customSourceSet instanceof com.android.build.gradle.internal.api.DefaultAndroidSourceSet) {
                customSourceSet = (com.android.build.gradle.internal.api.DefaultAndroidSourceSet)customSourceSet
                customSourceSet.getAssets().srcDirs(targetAssets)
            }
        }
           

接着修改 flutter_sdk 目錄下 packages/flutter_tools/gradle/flutter.gradle:

修改
        variant.outputs[0].processResources.dependsOn(copyFlutterAssetsTask)
        成
        variant.outputs[0].processResources.dependsOn(flutterTask)
           

2,根本原因是 Gradle插件版本過低,更新到 classpath 'com.android.tools.build:gradle:3.2.1';

3,pub 指令找不到;

  • 解決方案:pub 指令是 Dart SDK裡面的,找到它,再添加環境變量就行了;

    正常在 Flutter目錄下的,./bin/cache/dart-sdk/bin/裡面;

2,Realse包,打開就崩潰,報錯:[FATAL:flutter/shell/platform/android/http://library_loader.cc(24)] Check failed: result.;

  • 解決方案:Flutter混淆問題,添加混淆代碼:
-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.**  { *; }
           

1,别人建立的 Module,在我這編譯同步的時候報錯;Process 'command 'C:Usersjiangdongboflutterbinflutter.bat'' finished with non-zero exit value 1;

  • 解決方案:

1,單獨以純 Flutter 工程的方法打開 flutter Module,

2,删除 flutter Module目錄下的 .android .ios .idea build .flutter-plugins .packages,再點下 packages get,再試試能否 純 Flutter 工程 運作起來;

3,如果還不行,更新下 Flutter SDK,跟别人的一緻,再試試上面的操作;

4,如果純 Flutter工程 可以運作,但是到 混合工程不行,可以看看純 Flutter 工程 .android 目錄下 gradle 的版本,同步到 混合工程 再試試。

繼續閱讀