Flutter 踩坑記(Android)

Flutter 混合開發進展:

持續更新中 …

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/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:\Users\jiangdongbo\flutter\bin\flutter.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 的版本,同步到 混合工程 再試試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章