Flutter混合开发Android app技巧
在Windows上搭建Flutter开发环境
1.下载Flutter SDK (Channel stable, v1.17.1, on Microsoft Windows [Version 10.0.18363.1256], locale zh-CN),不要下载最新的SDK,兼容混合开发框架 flutter_boost: ^1.17.1。
2.下载四个插件,分别为 Flutter、Dart、FishReduxTemplate、Flutter Intl。流程图如下:
File | Settings | Plugins
3.检查三个SDK的配置,分别为Androd SDK、Flutter SDK、
Dart SDK. 流程图如下:
File | Settings | Appearance & Behavior | System Settings | Android SDK
File | Settings | Languages & Frameworks | Flutter
File | Settings | Languages & Frameworks | Dart
Windows上搭建Flutter开发环境
Android Flutter混合开发
创建module
1.在Android项目的同级目录新建Flutter Module
File | New | New Flutter Project… | Flutter Module
2.Flutter module项目集成FlutterBoost
在flutter_module项目的pubspec.yaml文件中添加依赖插件配置
dependencies:
flutter_boost: ^1.17.1
1
2
配置完成后执行flutter packages get命令下载依赖插件到本地
需要了解 pub get 和 pub upgrade 命令 , 打开pubspec.yaml这两个命令就能显示出来
pub get
在项目中配置了pubspec文件后,就可以在项目根目录中执行pub get命令
pub upgrade
第一次获取依赖时,Pub 会下载依赖及其兼容的最新版本。然后通过创建lockfile 锁定依赖,以始终使用这个版本。 Pub会在pubspec旁创建并存储一个名为pubspec.lock文件。它列出了使用的每个依赖包的指定版本(当前包或传递包的版本)。
3.运行代码
1.直接点击绿色的箭头Run就能独立运行到手机里面。
2.Build | Flutter | Build AAR ,就能编译出AAR文件,并生成Android集成日志
安卓原生项目中集成FlutterBoost
1.将文件夹的名改为app
将文件夹的名改为app, 否则会报错。
2.修改 settings.gradle 文件
include ':app', ':MiHomeSDK'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_module/.android/include_flutter.groovy'
))
include ':flutter_module'
project(':flutter_module').projectDir = new File('../flutter_module')
3.修改最外层目录下的build.gradle 文件
1.增加 maven {url ‘http://download.flutter.io’}
buildscript {
...
repositories {
...
maven {url 'http://download.flutter.io'}
}
dependencies {
...
}
}
allprojects {
repositories {
...
maven {url 'http://download.flutter.io'}
}
}
4.修改app目录下的build.gradle 文件
repositories {
maven {url '../../flutter_module/build/host/outputs/repo'}
}
debugImplementation 'com.xiaoyi.flutter_module:flutter_debug:1.0'
profileImplementation 'com.xiaoyi.flutter_module:flutter_profile:1.0'
releaseImplementation 'com.xiaoyi.flutter_module:flutter_release:1.0'
5.修改app目录下的AndroidManifest.xml文件
<activity
android:name="com.idlefish.flutterboost.containers.BoostFlutterActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" >
</activity>
6. 增加Flutter文件
里面包含三个Java 文件, 是自己封装,主要是初始化、通道、路由等功能
FlutterUtil.java
package com.ants360.yicamera.flutter;
import android.app.Application;
import android.os.Build;
import com.ants360.yicamera.base.UserManager;
import com.ants360.yicamera.bean.User;
import com.google.gson.Gson;
import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Platform;
import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.interfaces.INativeRouter;
import java.util.HashMap;
import java.util.Map;
import io.flutter.embedding.android.FlutterView;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.StandardMessageCodec;
public class FlutterUtil {
public static void init(Application app) {
INativeRouter router = (context, url, urlParams, requestCode, exts) -> {
String assembleUrl = Utils.assembleUrl(url, urlParams);
PageRouter.openPageByUrl(context, assembleUrl, urlParams);
};
FlutterBoost.BoostLifecycleListener boostLifecycleListener = new FlutterBoost.BoostLifecycleListener() {
@Override
public void beforeCreateEngine() {
}
@Override
public void onEngineCreated() {
// 注册MethodChannel,监听flutter侧的getPlatformVersion调用
MethodChannel methodChannel = new MethodChannel(FlutterBoost.instance().engineProvider().getDartExecutor(), "flutter_native_channel");
methodChannel.setMethodCallHandler((call, result) -> {
if (call.method.equals("getPlatformVersion")) {
result.success(Build.VERSION.RELEASE);
} else if (call.method.equals("getUser")) {
User user = UserManager.getInstance().getUser();
Map<String, String> map = new HashMap<>();
Gson gson = new Gson();
map.put("user", gson.toJson(user));
result.success(map);
}else {
result.notImplemented();
}
});
EventChannel methodChannel2 = new EventChannel(FlutterBoost.instance().engineProvider().getDartExecutor(), "native_flutter_channel");
methodChannel2.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
events.success("msg");
}
@Override
public void onCancel(Object arguments) {
}
});
// 注册PlatformView viewTypeId要和flutter中的viewType对应
FlutterBoost
.instance()
.engineProvider()
.getPlatformViewsController()
.getRegistry()
.registerViewFactory("plugins.test/view", new TextPlatformViewFactory(StandardMessageCodec.INSTANCE));
}
@Override
public void onPluginsRegistered() {
}
@Override
public void onEngineDestroy() {
}
};
Platform platform = new FlutterBoost
.ConfigBuilder(app, router)
.isDebug(true)
.whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
.renderMode(FlutterView.RenderMode.texture)
.lifecycleListener(boostLifecycleListener)
.build();
FlutterBoost.instance().init(platform);
}
}
PageRouter.java
package com.ants360.yicamera.flutter;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.ants360.yicamera.activity.camera.share.DeviceShareResultActivity;
import com.ants360.yicamera.constants.KeyConst;
import com.idlefish.flutterboost.containers.BoostFlutterActivity;
import java.util.HashMap;
import java.util.Map;
public class PageRouter {
public final static Map<String, String> pageName = new HashMap<String, String>() {{
put("notification", "notification");
put("device_login_message", "device_login_message");
put("device_Share_message", "device_Share_message");
put("first", "first");
put("second", "second");
put("tab", "tab");
put("sample://flutterPage", "flutterPage");
}};
public static final String NATIVE_PAGE_URL_DEVICE_SHARE_RESULT_ACTIVITY = "yicamera://DeviceShareResultActivity";
public static final String NATIVE_PAGE_URL = "sample://nativePage";
public static final String FLUTTER_PAGE_URL = "sample://flutterPage";
public static final String FLUTTER_FRAGMENT_PAGE_URL = "sample://flutterFragmentPage";
public static boolean openPageByUrl(Context context, String url, Map params) {
return openPageByUrl(context, url, params, 0);
}
public static boolean openPageByUrl(Context context, String url, Map params, int requestCode) {
String path = url.split("\?")[0];
Log.i("openPageByUrl",path);
try {
if (pageName.containsKey(path)) {
Intent intent = BoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params)
.backgroundMode(BoostFlutterActivity.BackgroundMode.opaque).build(context);
if(context instanceof Activity){
Activity activity = (Activity) context;
activity.startActivityForResult(intent,requestCode);
}else{
context.startActivity(intent);
}
return true;
} else if (url.startsWith(NATIVE_PAGE_URL_DEVICE_SHARE_RESULT_ACTIVITY)) {
Intent intent = new Intent(context, DeviceShareResultActivity.class);
if( null != params) {
intent.putExtra(KeyConst.DEVICE_SHARE_WAY, params.get(KeyConst.DEVICE_SHARE_WAY).toString());
intent.putExtra(KeyConst.DEVICE_SHARE_MESSAGE_ID, params.get(KeyConst.DEVICE_SHARE_MESSAGE_ID).toString());
intent.putExtra(KeyConst.DEVICE_SHARE_TOKEN, params.get(KeyConst.DEVICE_SHARE_TOKEN).toString());
intent.putExtra(KeyConst.DEVICE_SHARE_OWNER_NAME, params.get(KeyConst.DEVICE_SHARE_OWNER_NAME).toString());
}
if(context instanceof Activity){
Activity activity = (Activity) context;
activity.startActivityForResult(intent, requestCode);
}else{
context.startActivity(intent);
}
return true;
} else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) {
// context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
// TODO
return true;
} else if (url.startsWith(NATIVE_PAGE_URL)) {
// context.startActivity(new Intent(context, NativePageActivity.class));
// TODO
return true;
}
return false;
} catch (Throwable t) {
return false;
}
}
}
TextPlatformViewFactory.java
package com.ants360.yicamera.flutter;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import io.flutter.plugin.common.MessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
public class TextPlatformViewFactory extends PlatformViewFactory {
public TextPlatformViewFactory(MessageCodec<Object> createArgsCodec) {
super(createArgsCodec);
}
@Override
public PlatformView create(Context context, int i, Object o) {
return new TextPlatformView(context);
}
private static class TextPlatformView implements PlatformView {
private TextView platformTv;
public TextPlatformView(Context context) {
platformTv = new TextView(context);
platformTv.setText("PlatformView Demo");
}
@Override
public View getView() {
return platformTv;
}
@Override
public void dispose() {
}
}
}
7. Application 初始化
@Override
public void onCreate() {
super.onCreate();
FlutterUtil.init(this);
}
8. 打开Flutter界面
PageRouter.openPageByUrl(getActivity(), PageRouter.pageName.get("notification") , null);
9.混淆
@Keep
public class User implements IUser {
}
————————————————
版权声明:本文为CSDN博主「weixin_38951817」的原创文章
原文链接:https://blog.csdn.net/weixin_38951817/article/details/111151950
来千语创想移动应用开发平台学习更多免费APP开发知识:app开发 app开发源码下载 app开发视频教程 app制作模板等免费获取。千语创想支持一键网站自动生成app、网站转app、网站封装app,有网站即可生成自己的app。
立即免费在线制作一个APP,新手注册即送开发大礼包
提交app定制需求,了解报价和周期:
电脑请点击https://www.qianyuthink.com/?url=/index?uzchannel=500
手机请点击https://www.qianyuthink.com/?url=/m/quickaddcustom