basica4 android显示窗口 show,Flutter学习中遇到的问题:已有项目加入Flutter模块

本文主要尝试解决如下几个问题:

如何在在已经项目加入Flutter

混合跳转

混合栈问题

混合栈数据问题

跳转黑屏是因为debug的缘故,打release包则没有。

5aa4f2a7ed0e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

af.gif

1. 如何在在已经项目加入Flutter

2. 混合跳转

首先:Android跳转到Flutter

创建一个FlutterActivity

直接继承FlutterActivity或者自定义一个CustomFlutterActivity,我用的自定义,是做了一些封装和flutter插件注册

public abstract class CustomFlutterActivity extends AppCompatActivity implements FlutterView.Provider, PluginRegistry, FlutterActivityDelegate.ViewFactory {

private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);

private final FlutterActivityEvents eventDelegate;

private final FlutterView.Provider viewProvider;

private final PluginRegistry pluginRegistry;

public CustomFlutterActivity() {

this.eventDelegate = this.delegate;

this.viewProvider = this.delegate;

this.pluginRegistry = this.delegate;

}

@Override

protected void onCreate(Bundle savedInstanceState) {

if (injectRouter())

ARouter.getInstance().inject(this);

super.onCreate(savedInstanceState);

this.eventDelegate.onCreate(savedInstanceState);

GeneratedPluginRegistrant.registerWith(this);

registerCustomPlugin(this);

}

protected boolean injectRouter() {

return false;

}

//省略部分代码

.........

.........

private static void registerCustomPlugin(PluginRegistry registrar) {

FlutterPluginJumpToAct.registerWith(registrar.registrarFor(FlutterPluginJumpToAct.CHANNEL));

}

}

做一个Flutter用的容器,通过容器统一管理需要跳转的Flutter界面

@Route(path = RouterPath.MainPath.MAIN_FLUTTER_CONTAINER, name = "FlutterContainerActivity")

public class FlutterContainerActivity extends CustomFlutterActivity {

private static String CHANNEL = "com.jzhu.msg/plugin";

private static int TIME_ONE_SECOND = 1000;

@Autowired(name = "path")

String path;

@Override

protected boolean injectRouter() {

return true;

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

initBasicMessageChannel();

}

@Override

public FlutterView createFlutterView(Context context) {

WindowManager.LayoutParams matchParent = new WindowManager.LayoutParams(-1, -1);

FlutterNativeView nativeView = this.createFlutterNativeView();

FlutterView flutterView = new FlutterView(FlutterContainerActivity.this, (AttributeSet) null, nativeView);

flutterView.setInitialRoute(path);

flutterView.setLayoutParams(matchParent);

this.setContentView(flutterView);

return flutterView;

}

private void initBasicMessageChannel() {

switch (path) {

case RouterPath.ModuleFlutterPath.FLUTTER_HOME:

initHomeBasicMessage();

break;

case RouterPath.ModuleFlutterPath.FLUTTER_TEST:

initTestBasicMessage();

break;

}

}

private void initTestBasicMessage() {

BasicMessageChannel channel = new BasicMessageChannel(

getFlutterView(), CHANNEL, StringCodec.INSTANCE);

channel.setMessageHandler((o, reply) -> {

ToastUtils.show((String)o,3000);

reply.reply("FlutterContainerActivity:回条消息给你");

});

new Handler().postDelayed(() -> channel.send("FlutterContainerActivity:发条消息给你"), TIME_ONE_SECOND);

}

private void initHomeBasicMessage() {

//todo

}

}

Flutter提供的页面

void main() {

runApp(new MaterialApp(

routes: {

'/homepage': (BuildContext context) => new MyHomePage(),

'/testpage': (BuildContext context) => new TestPage(),

}, home: new MyHomePage()));

}

路由

public interface RouterPath {

interface MainPath{

String MAIN_FLUTTER_CONTAINER = "/main/FlutterContainerActivity";

String MAIN_TEST= "/main/TestActivity";

}

interface ModuleFlutterPath{

String FLUTTER_HOME= "/homepage";

String FLUTTER_TEST= "/testpage";

}

}

点击跳转

ARouter.getInstance()

.build(RouterPath.MainPath.MAIN_FLUTTER_CONTAINER)

.withString("path", RouterPath.ModuleFlutterPath.FLUTTER_HOME)

.navigation();

最后:Flutter跳转到Android

3. 混合栈问题

如果是Android的页面跳转到Android页面,所以就是普通的Activity栈。

如果是Android的页面跳转到Flutter页面,那么都使用了我们的容器FlutterContainerActivity,所以就是普通的Activity栈,这里面遇到个坑,下面会提出并尝试解决。

如果是Flutter的页面跳转到Flutter页面,那么由Flutter自己内部的栈管理。

如果是Flutter的页面跳转到Android页面,那么自己管自己就好啦。

如果你把Flutter的页面全装到到容器FlutterContainerActivity展示,那就都是普通的Activity栈,省事!

混合跳转注意:

Android某些页面的启动模式Standard,SingleTop,SingleTask,SingleInstance

Flutter页面也存在一些特殊的跳转,popAndPushNamed,pushNamedAndRemoveUntil,popUntil,pushReplacementNamed

以上需要根据实际情况处理,存在特殊跳转,销毁等逻辑

开发中需要特别需要注意的一个问题:

跳转顺序:Android页面 -> Flutter页面(使用了FlutterContainerActivity)-> Flutter页面(原始)

期望结果:Flutter页面(原始)-> Flutter页面(使用了FlutterContainerActivity)-> Android页面

真实结果:Flutter页面(原始)-> Flutter页面(使用了FlutterContainerActivity)-> Flutter页面(homepage) -> Android页面

得到疑问:我们并没有启动homepage,为什么多了一个homepage?

代码猜想:Flutter栈里初始化了一个homepage, 其他Flutter的页面都在这个栈之上。

void main() {

runApp(new MaterialApp(

routes: {

............

}, home: new MyHomePage()));

}

如何解决:使用SystemNavigator.pop(),

Tells the operating system to close the application, or the closest equivalent.

WillPopScope参考这篇Flutter学习中的问题记录: 如何监听实体/虚拟返回键和AppBar返回键

class _MyHomePageState extends State {

static const jumpPlugin = const MethodChannel('com.jzhu.jump/plugin');

Future _jumpToNative() async {

Map map = {"path": "/main/TestActivity"};

String result = await jumpPlugin.invokeMethod('jump2act', map);

print(result);

}

Future _requestPop() {

SystemNavigator.pop();

return new Future.value(false);

}

@override

Widget build(BuildContext context) {

return new WillPopScope(

child: new Scaffold(

appBar: new AppBar(

title: new Text("Home Page"),

),

body: new Center(

child: new RaisedButton(

child: new Text("跳到TestActivity"), onPressed: _jumpToNative),

),

// This trailing comma makes auto-formatting nicer for build methods.

),

onWillPop: _requestPop);

}

}

4. 混合栈数据问题,以插件的方式解决 。

MethodChannel,EventChanneld的数据传输,用法参考我之前写一篇Flutter知识点: Flutter与原生(Android)的交互

主要举例BasicMessageChannel和BinaryMessages

5aa4f2a7ed0e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1_Sd6s3EDGkU8TBS9xLc4Zvw.png

FlutterContainerActivity中初始化,监听,发送

为什么要延迟发送?

因为FlutterView可能还没初始化,这时候无法接收消息

private static String CHANNEL = "com.jzhu.msg/plugin";

private static String CHANNEL_BINARY = "com.jzhu.msg.binary/plugin";

private static int TIME_ONE_SECOND = 1000;

private void initTestBasicMessage() {

BasicMessageChannel channel = new BasicMessageChannel(

getFlutterView(), CHANNEL, StringCodec.INSTANCE);

channel.setMessageHandler((o, reply) -> {

ToastUtils.show((String)o,3000);

reply.reply("FlutterContainerActivity:回条消息给你");

});

new Handler().postDelayed(() -> channel.send("FlutterContainerActivity:发条消息给你"), TIME_ONE_SECOND);

ByteBuffer message = ByteBuffer.allocateDirect(256);

message.putDouble(3.14);

message.putInt(123456789);

new Handler().postDelayed(() -> getFlutterView().send(CHANNEL_BINARY,message), TIME_ONE_SECOND);

getFlutterView().setMessageHandler(CHANNEL_BINARY, (byteBuffer, binaryReply) -> {

byteBuffer.order(ByteOrder.nativeOrder());

double x = byteBuffer.getDouble();

int n = byteBuffer.getInt();

Log.i("zj", "Received: "+x+ " and "+ n);

binaryReply.reply(message);

});

}

Flutter中监听,发送

static const channel = const BasicMessageChannel('com.jzhu.msg/plugin', StringCodec());

static const String channelBinary = 'com.jzhu.msg.binary/plugin';

void _sendMsg2Android() async {

_replyMsg = await channel.send('TestPage:发条消息给你');

setState(() {});

final WriteBuffer buffer = WriteBuffer()

..putFloat64(3.14)

..putInt32(123456789);

final ByteData message = buffer.done();

_replyBinaryMsg = await BinaryMessages.send(channelBinary, message);

_decodeData(message);

}

void _initMessageHandler() {

channel.setMessageHandler((String message) async {

_receivedMsg = message;

setState(() {});

});

BinaryMessages.setMessageHandler(channelBinary, (ByteData message) async {

_decodeData(message);

});

}

void _decodeData(ByteData message){

final ReadBuffer readBuffer = ReadBuffer(message);

final double x = readBuffer.getFloat64();

final int n = readBuffer.getInt32();

print('Received $x and $n');

}

疑问:已有项目集成到Flutter,自定义插件应该放在哪注册,什么时机注册?有想法的私信留言谢谢!

已有项目集成到Flutter,后续遇到问题解决后会整理发布,或者你们觉得可能存在的问题,可以私信我,留言,空余时间会尽力尝试解决。

已有项目集成到Flutter代码已经上传到我的GITHUB

知乎日报Flutter版代码已经上传到我的GITHUB

基础学习过程中的代码都放在GITHUB

每天学一点,学到Flutter发布正式版!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值