今天给大家介绍的是如何传递从android原生传递给flutter初始化数据,这是最新版的哦,满满的干货!
漫长的未来里,无数的时间会一点一点地改变人生以为不可顽抗的轨道,让相爱的人分离,让曾经的誓言变成虚无的回忆,让年少的诗琴积上岁月的风沙,让念到的名字刻在墓地的石碑上。漫长到足够让你我相遇,相爱,然后。让你再爱上另一个人。
先来看看今天要完成的效果吧:
(效果图1.1):
分析:
- Android布局一个按钮,一个文本框
- flutter布局:一个Text()来接收android发送的数据
android布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ToFlutterDataActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点我进入Flutter"/>
<EditText
android:id="@+id/edit"
android:hint="给Flutter的一句话"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:background="#42aabbcc"
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
效果:
效果图(1.2):
java代码:(ToFlutterDataActivity类)
public class ToFlutterDataActivity extends AppCompatActivity {
public final static String INIT_PARAMS = "initParams";
BasicMessageChannelPlugin basicMessageChannelPlugin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText edit = findViewById(R.id.edit);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FlutterAppActivity.start(ToFlutterDataActivity.this,edit.getText().toString());
}
});
}
}
java代码:(FlutterAppActivity类);
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.Log;
import io.flutter.embedding.android.FlutterActivity;
public class FlutterAppActivity extends FlutterActivity {
public final static String INIT_PARAMS = "initParams";
public static void start(Context context, String initParams) {
Intent intent = new Intent(context, FlutterAppActivity.class);
intent.putExtra(INIT_PARAMS, initParams);
context.startActivity(intent);
}
String mInitParam;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mInitParam = getIntent().getStringExtra(INIT_PARAMS);
}
/**
通过getInitialRoute方法来进行传递初始化参数
*/
@NonNull
@Override
public String getInitialRoute() {
return mInitParam == null ? super.getInitialRoute() : mInitParam;
}
// 使用在MyApplication预先初始化好的Flutter引擎以提升Flutter页面打开速度,
// 注意:在这种模式下回导致getInitialRoute 不被调用所以无法设置初始化参数
// @Override
// public String getCachedEngineId() {
// return App.ENG_INED;
// }
}
可以看到,布局中非常简单但是有朋友可能会问了,为什么MianActivity不直接继承自FlutterActivity呢?
这里就涉及到了生命周期的问题,因为咋们是点击按钮将数据传递给flutter,上一章中我们也提到了,FlutterActivity就是Flutter执行的main方法,说大白话FlutterActivity就是Flutter页面,咋们实现的效果是点击按钮才跳转到flutter页面.如果说直接让ToFlutterDataActivity继承自FlutterActivity的话,刚启动时,他里面的传递初始化参数的方法(getInitialRoute)就执行了,再点击按钮传递参数的方法则不会执行.咋们重新写一个类(FlutterAppActivity)继承自FlutterActivity的话即可完美的避开传递参数不执行的问题
FlutterAppActivity在这个类中操作非常简单:只有获取到ToFlutterDataActivity的传递的参数,然后通过getInitialRoute()这个方法传递给Flutter即可
/**
* 传递初始化参数给Flutter
* @return
*/
@NonNull
@Override
public String getInitialRoute() {
return mInitParam == null ? super.getInitialRoute() : mInitParam;
}
这里需要注意的是:
必须在Application中初始化Flutter引擎(FlutterEngine())
public class App extends Application {
private FlutterEngine fe;
public static String ENG_INED ="engined";
@Override
public void onCreate() {
super.onCreate();
//Flutter引擎
fe = new FlutterEngine(this);
/**
* 设置要缓存的页面
*/
// fe.getNavigationChannel().setInitialRoute("text_page");
//通过engine_id唯一标识来缓存fe.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
FlutterEngineCache
.getInstance()
.put(ENG_INED, fe);
}
/**
* onTerminate()当App销毁时执行
*/
@Override
public void onTerminate() {
//销毁flutter引擎
fe.destroy();
super.onTerminate();
}
}
记得在AndroidMainifest.xml中声明App和Activity哦
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="demo.ht.com.androidproject">
<application
android:name=".App"
......
>
.....
<activity android:name=".FlutterAppActivity"/>
<activity android:name="io.flutter.embedding.android.FlutterActivity" />
</application>
</manifest>
走到这里Android端的代码就结束了,接下来看看Flutter的代码吧:
import 'dart:ui';
void main() => runApp(MyApp(window.defaultRouteName));
window.defaultRouteName的导包为import ‘dart:ui’;
Flutter通过window.defaultRouteName来获取Android端发送过来的数据;
来看看效果图吧:
效果图(1.3)
可以看到效果以及实现了,可是呢,在跳转的过程中有1s-2s的黑屏状态,在上一篇中讲到了可以使用Flutter引擎,先将页面缓存下来,然后在跳转时就不会有黑屏问题,可是在上面代码中也使用了Flutter引擎(FlutterEngine),依然没有效果…
解决办法:
在FlutterAppActivity重写getCachedEngineId()方法,返回App.ENG_INED参数,使用缓存
// 使用在MyApplication预先初始化好的Flutter引擎以提升Flutter页面打开速度,
// 注意:在这种模式下会导致getInitialRoute 不被调用所以无法设置初始化参数
@Override
public String getCachedEngineId() {
return App.ENG_INED;
}
效果图(1.5):
通过效果图可以看到,黑屏问题是解决的,但是flutter并没有获取到android发送的数据, 因为,在这种模式下会导致getInitialRoute() 不被调用所以无法设置初始化参数
得出结论:
传递初始化参数和缓存页面只能选择一个,我建议选择缓存页面,因为啥大家都清除.
本章注意事项:
Android端:
- getInitalRoute()传递初始化参数和getCachedEngineId()缓存页面只能选择一个
- 注意在Androidmainifest.xml中添加Activity四大组件声明
- 足以在androidMainifest.xml中添加Appcation声明
Flutter端:
- 通过window.defaultRouteName来接收Android发送的数据
- window.defaultRoute添加导包为:Nameimport ‘dart:ui’;
猜你喜欢:
FLutter混合开发 Android跳转Flutter页面,Flutter引擎等(4.1)
Flutter混合开发 BasicMessageChannel与原生android通信(4.3)
Flutter混合开发 EventChannel单向传递数据(4.4)
Flutter混合开发 MethodChannel单向传递消息(4.5)
Flutter混合开发 如何将Flutter项目变成Module导入Android项目(4.6)
原创不易,您的点赞就是对我最大的支持,留下您的点赞吧~