好久没有更新点东西了,最近有点丧,可能每个月总有那么几天吧,哈哈哈。
言归正传,上一篇写了关于原生 App
项目源码集成 Flutter
,链接直通车:原生App项目集成Flutter混合开发超详细指南,最近看别人博客的时候,总是一系列一系列的,感觉很棒,期待自己不懒,也能这样搞,于是就有了这一篇,正文:
一. 生成 aar 包
1. 创建 Flutter
项目
我间接用的 Android Studio
。需安装 Dart
和 Flutter
插件(Android Studio -> Preferences -> Plugins,搜索安装)
,之后重启即可。
注:我用的操作系统为:MacBook Pro
File -> New -> New Flutter Project -> Flutter Module
2. 代码修改
app/build.gradle
中的 apply plugin: ‘com.android.application'
改为 apply plugin: ‘com.android.library'
,并注释 defaultConfig
中的 applicationId
;
注释清单文件 <applicationId> </application>
标签中全部内容;
并且将清单文件修改为:
<manifest package="com.example.yin.flutter_product"/>
删除 package 后面的 .host
3. 生成 aar
打开 Android Studio
下面的 Terminal
执行命令:
cd .android
./gradlew assembleRelease
注:如果失败的话,用命令行: ./gradlew clean 清一下之后在重试。
生成的 aar
路径:
flutter_app/.android/Flutter/build/outputs/aar/flutter-release.aar
手动把文件名改成 app-release.aar
注:之前参考了许多博客,说直接打 aar 会缺少 assets 下的 flutter_shared/icudt.dat 文件
可能由于 flutter sdk 的升级,已经不需要额外的手动配置了。
上述打包成功的 aar
就可以作为普通的 aar
集成到 Android
项目中了。
4. 集成到原生 Android 项目中
拷贝 aar
到现有 android
项目中,拷贝到 libs
目录下;
配置 app
文件夹下的 build.gradle
:
repositories {
flatDir { dirs 'libs' }
}
dependencies {
compile(name: 'app-release', ext: 'aar')
}
新建一个 Application
继承 FlutterApplication
并在 manifest
中注册:
public class App extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
FlutterMain.startInitialization(this);
}
}
注:为减少 app 冷启动时 Application 中初始化耗费的时间,还可以在 Activity 中初始化 Flutter
5. 展示 Flutter 界面
新建一个 Activity
对象,并继承 FlutterActivity
:
public class FlutterMainActivity extends FlutterActivity {
//跳转该页面的时候可以传要跳转的页面,参数名固定为route
private static final String ROUTE_PAGE = "route";
public static Intent makeIntent(Context context, String routePage) {
if (routePage == null || routePage.equals("")) {
routePage = "/";
}
Intent intent = new Intent(context, FlutterMainActivity.class);
intent.setAction(Intent.ACTION_RUN);
intent.putExtra(ROUTE_PAGE, routePage);
return intent;
}
public void onCreate(@Nullable Bundle savedInstanceState) {
//或者在这里初始化Flutter
//FlutterMain.startInitialization(this);
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}
然后就能展示 Flutter void main() => runApp(new MyApp());
这句话对应的界面了。
可以看到我们还有传参,那么这个参数就可以在 flutter
里面接收到,我们可以根据这个参数的值来跳转对应的界面。
void main() => runApp(_widgetForRoute(window.defaultRouteName));
Widget _widgetForRoute(String route) {
switch (route) {
case 'route1':
return SomeWidget(...);
case 'route2':
return SomeOtherWidget(...);
default:
return Center(
child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
);
}
}
二. 产物集成方式
1. 以 Activity 为单位的展示 Flutter
2. 以 View 为单位展示
上面就是以 Activity
为单位的展示 Flutter
,下面为以 View
为单位展示:
package com.example.androidflutterproduct;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import io.flutter.facade.Flutter;
import io.flutter.view.FlutterView;
public class FlutterViewActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FlutterView flutterView = Flutter.createView(
this,
getLifecycle(),
"route1");
setContentView(flutterView);
}
}
注:这次我把引入的包也倒进来了,大家注意是项目已经迁移到了 AndroidX
需额外引入 lifecycle 依赖:implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"
其实以 View 为单位,类似于源码集成,剩下的 flutter 代码就和上面的一样了。
可能会有一些疑问:有啥区别?见下面截图:
flutter_activity.jpg flutter_view.jpg
以
View
为单位来展示 Flutter
的视图了,这个方案还是蛮灵活的。
三. 第三方依赖问题
关于怎么添加第三方的插件(即三方库),可以参考:Flutter添加第三方库
网友评论