概述
移动开发的方式:混合开发,一套代码,多端运行。
目前比较的成熟的方案是:ReactNative和Flutter,各有优劣,开源社区也都非常活跃。
Flutter 应用产品
ReactNative:
实现方式:使用JS代码构建一个跨平台APP,RN 把应用的JS代码(包括依赖的framework)编译成一个js文件,IOS上直接使用内置的javascriptcore, 在Android 则使用webkit.org官方开源的jsc.so来运行js脚本文件。
如果是js 扩展的API, 则直接通过bridge调用native方法;
如果是UI界面, 通过bridge (JS和Nactive 的通信桥梁)把数据传递传递到native , 然后根据数据属性设置各个对应的真实native的View,也就是界面控件会映射原生控件去加载。
缺点:原生控件承载界面渲染,系统升级和api变化会带来不稳定性。
Flutter框架:
Flutter框架包含了:frameWork层是一个UISDK,Engine层有Skia图像渲染引擎和Dart的接口,Embedder 是操作系统适配层。总而言之:flutter 一个纯UI渲染框架;
下面从四个方面分享使用futter实现混合开发的过程:
1、flutter的应用是什么样子,如何构建UI
2、第三方开源框架是否全面
3、flutter如何与原生应用混编
4、如何实现调用系统原生的能力
一、flutter的应用是什么样子,如何构建UI
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp()); //应用入口:main.dart文件下的main函数
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) { //_counter对象改变,回调build
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Flutter 界面的核心设计思想便是:一切皆 Widget ,从最顶层的app就是widget,到下面任何的ui元素都可以封装成widget,像客户端常用的视图(View)、视图控制器(View Controller)、活动(Activity)等,在 Flutter 中都是 Widget。
界面的改变通过state设置状态来实现。
Flutter应用通过Dart语言编写:支持运行时编译(JIT)模式,修改代码后可直接热重载。
二:flutter目前的开源库
Dart和Flutter应用程序的官方软件包存储库:Dart packages
SVGA,RxDart ,HTTP,shared_preferences等等,
使用网络请求数据,加载到列表的常见需求:
pubspec.yaml【flutter应用工程配置文件】导入相关的库
dio: ^3.0.7 //网络请求json_annotation: ^2.4.0 //json
class _SampleAppPageState extends State<SampleAppPage> {
List widgets = [];
@override
void initState() {
super.initState();
loadData();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Sample App"),
),
body: new ListView.builder(
itemCount: widgets.length,
itemBuilder: (BuildContext context, int position) {
return Container(
//内容文字
child: new Text(" ${widgets[position]["id"]}"
+ "${widgets[position]["title"]}"),
//下横线
decoration: BoxDecoration(border:
Border(bottom: BorderSide(width: 1, color: Color(0xffe5e5e5)))),
//边距
padding: new EdgeInsets.all(10.0),
);
}));
}
loadData() async {
String dataURL = "https://jsonplaceholder.typicode.com/posts";
http.Response response = await http.get(dataURL);
setState(() {
widgets = json.decode(response.body);
});
}
}
实现的效果就是如下:
三:flutter混编入原生工程
方式:将flutter模块打包成aar,供原生android调用(iOS 使用 pod),三端代码分离;
操作:
a、在安卓app同级目录下可以创建 Flutter 模块:Flutter create -t module flutter_library
b、flutter模块实现功能后打包aar(Flutter build apk --debug)
打包aar的项目结构如下:原生工程导入aar,添加依赖即可使用
四:flutter调用系统原生的能力
Flutter 并没有提供对原生页面操作的方法,所以通过:
在flutter界面打开一个安卓原生界面的流程,查看flutter调用原生系统的方式
1、首先在android应用打开一个flutter界面:
安卓将flutter界面打包成flutterView加载
public class FlutterPageActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
FlutterView flutterView = Flutter.createView(this,getLifecycle(),"defaultRoute");
setContentView(flutterView);
}
}
2、flutter应用操作:
a、打开aroute对应界面 ;
b、通过注册方法通道(MethodChannel)的方式打开安卓界面
void main() => runApp(_widgetForRoute(window.defaultRouteName));
const platform = MethodChannel('samples.demo/navigation'); //注册方法通道
Widget _widgetForRoute(String route) {
switch (route) {
default: //对应路由类型
return MaterialApp(
home:DefaultPage(showBack: true),
);
}
}
class DefaultPage extends StatelessWidget {
DefaultPage({Key key, this.showBack=false }) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Flutter Default Page"),),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text("Go Page A"),
//通过注册的方法:openNativePage 点击打开安卓界面
onPressed: ()=>platform.invokeMethod('openNativePage')
)
],
),
)
);
}
}
3、android应用实现方法通道,并响应打开界面
public class FlutterPageActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
FlutterView flutterView = Flutter.createView(this,getLifecycle(),"defaultRoute");
//注册方法通道 --方法通道识别:samples.demo/navigation--
new MethodChannel(flutterView, "samples.demo/navigation").setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result){
//注册的方法:openNativePage
if(call.method.equals("openNativePage")) {
//打开安卓页面
Intent intent = new Intent(FlutterPageActivity.this, AndroidActivity.class);
startActivity(intent);
//返回数据给flutter
result.success(0);
} else {
//方法未实现
}
}
});
setContentView(flutterView);
}
}
以上demo实现了,在安卓项目中混编flutter模块,实现双方调用的功能。
谢谢!