Flutter 踩坑记(Android)

Flutter 混合开发进展:

持续更新中 …

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 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 的版本,同步到 混合工程 再试试。

你可能感兴趣的:(Flutter)