Commit 092117c2 authored by yangwu.jia's avatar yangwu.jia

Merge branch 'master' into v0.1.61-androidx-hotfixes

# Conflicts:
#	README.md
#	README_CN.md
#	android/src/main/java/com/idlefish/flutterboost/FlutterBoostPlugin.java
#	android/src/main/java/com/idlefish/flutterboost/FlutterViewContainerManager.java
parents 8adac44a 1720a621
---
name: Bug report
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''
---
<!-- Thank you for using Flutter Boost!
If you are looking for support about how to get start, please read README first
-->
## Steps to Reproduce
**A small application to reproduce the bug(最小化可复现的demo)**
<!--
Please tell us exactly how to reproduce the problem you are running into.
Please attach a small application (ideally just one main.dart file) that
reproduces the problem. You could use https://gist.github.com/ for this.
If the problem is with your application's rendering, then please attach
a screenshot and explain what the problem is.
-->
1. ...
2. ...
3. ...
<!--
Please tell us which target platform(s) the problem occurs (Android / iOS / Web / macOS / Linux / Windows)
Which target OS version, for Web, browser, is the test system running?
Does the problem occur on emulator/simulator as well as on physical devices?
-->
**Flutter Boost Version**
**Target Platform:**
**Target OS version/browser:**
**Devices:**
## Logs
add your crash log or something else.
<!-- Finally, paste the output of running `flutter doctor -v` here. -->
```
```
...@@ -9,6 +9,35 @@ The main changes are as following: ...@@ -9,6 +9,35 @@ The main changes are as following:
4. We did some code refactoring, the main logic became more straightforward. 4. We did some code refactoring, the main logic became more straightforward.
## 0.1.60
A better implementation to support Flutter v1.9.1+hotfixes
Change the content
android:
1. based on the v1.9.1+hotfixes branch of flutter
2. Solve major bugs, such as page parameter passing
3. Support platformview
4. Support androidx branch :feature/flutter_1.9_androidx_upgrade
5. Resolve memory leaks
6. Rewrite part of the code
7. API changes
8. Improved demo and added many demo cases
ios:
1.based on the v1.9.1+hotfixes branch of flutter
2.bugfixed
## 0.1.61
android:
Fixed bugs
iOS:
no change
### API changes ### API changes
From the point of API changes, we did some refactoring as following: From the point of API changes, we did some refactoring as following:
#### iOS API changes #### iOS API changes
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# Release Note # Release Note
Please checkout the release note for the latest 0.1.54 to see changes [0.1.54 release note](https://github.com/alibaba/flutter_boost/releases) Please checkout the release note for the latest 0.1.61 to see changes [0.1.61 release note](https://github.com/alibaba/flutter_boost/releases)
# FlutterBoost # FlutterBoost
A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of FlutterBoost is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. FlutterBoost takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL).  A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of FlutterBoost is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. FlutterBoost takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL). 
...@@ -16,399 +16,59 @@ A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plug ...@@ -16,399 +16,59 @@ A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plug
# Prerequisites # Prerequisites
You need to add Flutter to your project before moving on.The version of the flutter SDK requires v1.9.1+hotfixes, or it will compile error. You need to add Flutter to your project before moving on.The version of the flutter SDK requires v1.9.1+hotfixes, or it will compile error.
# Getting Started
## Add a dependency in you Flutter project.
Open you pubspec.yaml and add the following line to dependencies:
support branch
```json
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'feature/flutter_1.9_upgrade'
```
androidx branch
```json
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'feature/flutter_1.9_androidx_upgrade'
```
## Integration with Flutter code.
Add init code to you App
```dart
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
FlutterBoost.singleton.registerPageBuilders({
'first': (pageName, params, _) => FirstRouteWidget(),
'second': (pageName, params, _) => SecondRouteWidget(),
'tab': (pageName, params, _) => TabRouteWidget(),
'platformView': (pageName, params, _) => PlatformRouteWidget(),
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params),
'flutterPage': (pageName, params, _) {
print("flutterPage params:$params");
return FlutterRouteWidget(params:params);
},
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Boost example',
builder: FlutterBoost.init(postPush: _onRoutePushed),
home: Container());
}
void _onRoutePushed(
String pageName, String uniqueId, Map params, Route route, Future _) {
}
}
```
## Integration with iOS code.
Note: You need to add libc++ into "Linked Frameworks and Libraries"
### objective-c:
Use FLBFlutterAppDelegate as the superclass of your AppDelegate
```objectivec
@interface AppDelegate : FLBFlutterAppDelegate <UIApplicationDelegate>
@end
```
Implement FLBPlatform protocol methods for your App.
```objectivec
@interface PlatformRouterImp : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
@end
@implementation PlatformRouterImp
#pragma mark - Boost 1.5
- (void)open:(NSString *)name
urlParams:(NSDictionary *)params
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
if(completion) completion(YES);
}
- (void)present:(NSString *)name
urlParams:(NSDictionary *)params
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{
if(completion) completion(YES);
}];
}
- (void)close:(NSString *)uid
result:(NSDictionary *)result
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
animated = YES;
FLBFlutterViewContainer *vc = (id)self.navigationController.presentedViewController;
if([vc isKindOfClass:FLBFlutterViewContainer.class] && [vc.uniqueIDString isEqual: uid]){
[vc dismissViewControllerAnimated:animated completion:^{}];
}else{
[self.navigationController popViewControllerAnimated:animated];
}
}
@end
```
Initialize FlutterBoost with FLBPlatform at the beginning of your App, such as AppDelegate.
```objc
PlatformRouterImp *router = [PlatformRouterImp new];
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterEngine *engine) {
}];
```
### swift:
init
```swift
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
let router = PlatformRouterImp.init();
FlutterBoostPlugin.sharedInstance()?.startFlutter(with: router, onStart: { (engine) in
});
self.window = UIWindow.init(frame: UIScreen.main.bounds)
let viewController = ViewController.init()
let navi = UINavigationController.init(rootViewController: viewController)
self.window.rootViewController = navi
self.window.makeKeyAndVisible()
return true;//super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
```
Implement FLBPlatform protocol methods for your App.
```swift
class PlatformRouterImp: NSObject, FLBPlatform {
func open(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let vc = FLBFlutterViewContainer.init();
vc.setName(url, params: urlParams);
self.navigationController().pushViewController(vc, animated: animated);
completion(true);
}
func present(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let vc = FLBFlutterViewContainer.init();
vc.setName(url, params: urlParams);
navigationController().present(vc, animated: animated) {
completion(true);
};
}
func close(_ uid: String, result: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let presentedVC = self.navigationController().presentedViewController;
let vc = presentedVC as? FLBFlutterViewContainer;
if vc?.uniqueIDString() == uid {
vc?.dismiss(animated: animated, completion: {
completion(true);
});
}else{
self.navigationController().popViewController(animated: animated);
}
}
func navigationController() -> UINavigationController {
let delegate = UIApplication.shared.delegate as! AppDelegate
let navigationController = delegate.window?.rootViewController as! UINavigationController
return navigationController;
}
}
```
## Integration with Android code. # boost version description
Init FlutterBoost in Application.onCreate()  1. 0.1.50 is based on the flutter v1.5.4-hotfixes branch, android if other flutter versions or branches will compile incorrectly
```java 2. 0.1.51--0.1.54 is a bugfix for 0.1.50
public class MyApplication extends Application {
@Override 3. 0.1.60 is based on the flutter v1.9.1-hotfixes branch. Android does not support andriodx if other flutter branches will compile incorrectly
public void onCreate() {
super.onCreate();
INativeRouter router =new INativeRouter() {
@Override
public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
String assembleUrl=Utils.assembleUrl(url,urlParams);
PageRouter.openPageByUrl(context,assembleUrl, urlParams);
}
}; 4. 0.1.61 is a bugfix for 0.1.60
NewFlutterBoost.BoostLifecycleListener lifecycleListener= new NewFlutterBoost.BoostLifecycleListener() {
@Override
public void onEngineCreated() {
} 5. Statement of support for androidx
@Override Current androidx branch is feature/flutter_1.9_androidx_upgrade
public void onPluginsRegistered() {
MethodChannel mMethodChannel = new MethodChannel( NewFlutterBoost.instance().engineProvider().getDartExecutor(), "methodChannel");
Log.e("MyApplication","MethodChannel create");
TextPlatformViewPlugin.register(NewFlutterBoost.instance().getPluginRegistry().registrarFor("TextPlatformViewPlugin"));
} Is based on flutter v1.9.1-hotfixes branch, if other branches will compile incorrectly
@Override Synchronize with the 0.1.60 code, and bugfix of 0.1.61 also merge to this branch.
public void onEngineDestroy() {
}
};
Platform platform= new NewFlutterBoost
.ConfigBuilder(this,router)
.isDebug(true)
.whenEngineStart(NewFlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
.renderMode(FlutterView.RenderMode.texture)
.lifecycleListener(lifecycleListener)
.build();
NewFlutterBoost.instance().init(platform);
# Getting Started
} ## Add a dependency in you Flutter project.
}
```
# Basic Usage
## Concepts
All page routing requests are being sent to the native router. Native router communicates with Native Container Manager, Native Container Manager takes care of building and destroying of Native Containers. 
## Use Flutter Boost Native Container to show a Flutter page in native code.
iOS Open you pubspec.yaml and add the following line to dependencies:
```objc support branch
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new; ```json
[vc setName:name params:params]; flutter_boost:
[self.navigationController presentViewController:vc animated:animated completion:^{}]; git:
``` url: 'https://github.com/alibaba/flutter_boost.git'
However, in this way, you cannot get the page data result after the page finished. We suggest you implement the platform page router like the way mentioned above. And finally open/close the VC as following: ref: '0.1.61'
```objc
//push the page
[FlutterBoostPlugin open:@"first" urlParams:@{kPageCallBackId:@"MycallbackId#1"} exts:@{@"animated":@(YES)} onPageFinished:^(NSDictionary *result) {
NSLog(@"call me when page finished, and your result is:%@", result);
} completion:^(BOOL f) {
NSLog(@"page is opened");
}];
//prsent the page
[FlutterBoostPlugin open:@"second" urlParams:@{@"present":@(YES),kPageCallBackId:@"MycallbackId#2"} exts:@{@"animated":@(YES)} onPageFinished:^(NSDictionary *result) {
NSLog(@"call me when page finished, and your result is:%@", result);
} completion:^(BOOL f) {
NSLog(@"page is presented");
}];
//close the page
[FlutterBoostPlugin close:yourUniqueId result:yourdata exts:exts completion:nil];
``` ```
androidx branch
Android ```json
flutter_boost:
```java git:
public class PageRouter { url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'feature/flutter_1.9_androidx_upgrade'
public final static Map<String, String> pageName = new HashMap<String, String>() {{
put("first", "first");
put("second", "second");
put("tab", "tab");
put("sample://flutterPage", "flutterPage");
}};
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 = NewBoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params)
.backgroundMode(NewBoostFlutterActivity.BackgroundMode.opaque).build(context);
context.startActivity(intent);
} else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) {
context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
return true;
} else if (url.startsWith(NATIVE_PAGE_URL)) {
context.startActivity(new Intent(context, NativePageActivity.class));
return true;
} else {
return false;
}
} catch (Throwable t) {
return false;
}
return false;
}
}
``` ```
## Use Flutter Boost to open a page in dart code.
Dart
```objc
FlutterBoost.singleton
.open("pagename")
``` # Boost Integration
## Use Flutter Boost to close a page in dart code.
```objc Please see the boost example for details.
FlutterBoost.singleton.close(uniqueId);
```
# Running the Demo
Please see the example for details.
# License # License
...@@ -423,6 +83,7 @@ This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md ...@@ -423,6 +83,7 @@ This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md
## 关于我们 ## 关于我们
阿里巴巴-闲鱼技术是国内最早也是最大规模线上运行Flutter的团队。 阿里巴巴-闲鱼技术是国内最早也是最大规模线上运行Flutter的团队。
我们在公众号中为你精选了Flutter独家干货,全面而深入。 我们在公众号中为你精选了Flutter独家干货,全面而深入。
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# Release Note # Release Note
请查看最新版本0.1.54的release note 确认变更,[0.1.54 release note](https://github.com/alibaba/flutter_boost/releases) 请查看最新版本0.1.61的release note 确认变更,[0.1.61 release note](https://github.com/alibaba/flutter_boost/releases)
# FlutterBoost # FlutterBoost
...@@ -13,397 +13,75 @@ ...@@ -13,397 +13,75 @@
# 前置条件 # 前置条件
在继续之前,您需要将Flutter集成到你现有的项目中。flutter sdk 的版本需要 v1.9.1-hotfixes,否则会编译失败.
# 安装
## 在Flutter项目中添加依赖项。
打开pubspec.yaml并将以下行添加到依赖项:
support分支
```json
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'feature/flutter_1.9_upgrade'
```
androidx分支
```json
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'feature/flutter_1.9_androidx_upgrade'
```
## Dart代码的集成
将init代码添加到App App
```dart
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
FlutterBoost.singleton.registerPageBuilders({
'first': (pageName, params, _) => FirstRouteWidget(),
'second': (pageName, params, _) => SecondRouteWidget(),
'tab': (pageName, params, _) => TabRouteWidget(),
'platformView': (pageName, params, _) => PlatformRouteWidget(),
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params),
'flutterPage': (pageName, params, _) {
print("flutterPage params:$params");
return FlutterRouteWidget(params:params);
},
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Boost example',
builder: FlutterBoost.init(postPush: _onRoutePushed),
home: Container());
}
void _onRoutePushed(
String pageName, String uniqueId, Map params, Route route, Future _) {
}
}
```
## iOS代码集成。
注意:需要将libc++ 加入 "Linked Frameworks and Libraries" 中。
### objective-c:
使用FLBFlutterAppDelegate作为AppDelegate的超类
```objectivec
@interface AppDelegate : FLBFlutterAppDelegate <UIApplicationDelegate>
@end
```
为您的应用程序实现FLBPlatform协议方法。
```objectivec
@interface PlatformRouterImp : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
@end
@implementation PlatformRouterImp
#pragma mark - Boost 1.5
- (void)open:(NSString *)name
urlParams:(NSDictionary *)params
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
if(completion) completion(YES);
}
- (void)present:(NSString *)name
urlParams:(NSDictionary *)params
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{
if(completion) completion(YES);
}];
}
- (void)close:(NSString *)uid
result:(NSDictionary *)result
exts:(NSDictionary *)exts
completion:(void (^)(BOOL))completion
{
BOOL animated = [exts[@"animated"] boolValue];
animated = YES;
FLBFlutterViewContainer *vc = (id)self.navigationController.presentedViewController;
if([vc isKindOfClass:FLBFlutterViewContainer.class] && [vc.uniqueIDString isEqual: uid]){
[vc dismissViewControllerAnimated:animated completion:^{}];
}else{
[self.navigationController popViewControllerAnimated:animated];
}
}
@end
```
在应用程序开头使用FLBPlatform初始化FlutterBoost。
```objc
PlatformRouterImp *router = [PlatformRouterImp new];
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterEngine *engine) {
}];
```
### swift:
初始化
```swift
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
let router = PlatformRouterImp.init();
FlutterBoostPlugin.sharedInstance()?.startFlutter(with: router, onStart: { (engine) in
});
self.window = UIWindow.init(frame: UIScreen.main.bounds)
let viewController = ViewController.init()
let navi = UINavigationController.init(rootViewController: viewController)
self.window.rootViewController = navi
self.window.makeKeyAndVisible()
return true;//super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
```
为您的应用程序实现FLBPlatform协议方法。
```swift
class PlatformRouterImp: NSObject, FLBPlatform {
func open(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let vc = FLBFlutterViewContainer.init();
vc.setName(url, params: urlParams);
self.navigationController().pushViewController(vc, animated: animated);
completion(true);
}
func present(_ url: String, urlParams: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let vc = FLBFlutterViewContainer.init();
vc.setName(url, params: urlParams);
navigationController().present(vc, animated: animated) {
completion(true);
};
}
func close(_ uid: String, result: [AnyHashable : Any], exts: [AnyHashable : Any], completion: @escaping (Bool) -> Void) {
var animated = false;
if exts["animated"] != nil{
animated = exts["animated"] as! Bool;
}
let presentedVC = self.navigationController().presentedViewController;
let vc = presentedVC as? FLBFlutterViewContainer;
if vc?.uniqueIDString() == uid {
vc?.dismiss(animated: animated, completion: {
completion(true);
});
}else{
self.navigationController().popViewController(animated: animated);
}
}
func navigationController() -> UINavigationController {
let delegate = UIApplication.shared.delegate as! AppDelegate
let navigationController = delegate.window?.rootViewController as! UINavigationController
return navigationController;
}
}
```
在继续之前,您需要将Flutter集成到你现有的项目中。flutter sdk 的版本需要 v1.9.1-hotfixes,否则会编译失败.
## Android代码集成。 # boost 版本说明
在Application.onCreate()中初始化FlutterBoost 1. 0.1.50 是基于flutter v1.5.4-hotfixes 分支,android 如果其他flutter版本或者分支 会编译错误
```java 2. 0.1.51--0.1.54 是对0.1.50的bugfix
public class MyApplication extends Application {
@Override 3. 0.1.60 是基于flutter v1.9.1-hotfixes 分支,android如果其他flutter分支会编译错误,该版本不支持andriodx
public void onCreate() {
super.onCreate();
INativeRouter router =new INativeRouter() {
@Override
public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
String assembleUrl=Utils.assembleUrl(url,urlParams);
PageRouter.openPageByUrl(context,assembleUrl, urlParams);
}
}; 4. 0.1.61 是对0.1.60 的bugfix
NewFlutterBoost.BoostLifecycleListener lifecycleListener= new NewFlutterBoost.BoostLifecycleListener() {
@Override
public void onEngineCreated() {
} 5. 关于androidx 的支持声明
@Override 目前androidx 分支为 feature/flutter_1.9_androidx_upgrade
public void onPluginsRegistered() {
MethodChannel mMethodChannel = new MethodChannel( NewFlutterBoost.instance().engineProvider().getDartExecutor(), "methodChannel");
Log.e("MyApplication","MethodChannel create");
TextPlatformViewPlugin.register(NewFlutterBoost.instance().getPluginRegistry().registrarFor("TextPlatformViewPlugin"));
} 是基于flutter v1.9.1-hotfixes 分支,如果其他分支会编译错误
@Override 和0.1.60代码同步,同时0.1.61的 bugfix 也会合入该分支。
public void onEngineDestroy() {
}
};
Platform platform= new NewFlutterBoost
.ConfigBuilder(this,router)
.isDebug(true)
.whenEngineStart(NewFlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
.renderMode(FlutterView.RenderMode.texture)
.lifecycleListener(lifecycleListener)
.build();
NewFlutterBoost.instance().init(platform);
# 安装
} ## 在Flutter项目中添加依赖项。
}
```
# 基本用法 打开pubspec.yaml并将以下行添加到依赖项:
## 概念
所有页面路由请求都将发送到Native路由器。Native路由器与Native Container Manager通信,Native Container Manager负责构建和销毁Native Containers。 support分支
```json
## 使用Flutter Boost Native Container用Native代码打开Flutter页面。 flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: '0.1.61'
```objc
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
``` ```
但是,这种方式无法获取页面返回的数据,建议你按上面的example实现类似于PlatformRouterImp这样的路由器,然后通过以下方式来打开/关闭页面 androidx分支
```json
```objc flutter_boost:
//push the page git:
[FlutterBoostPlugin open:@"first" urlParams:@{kPageCallBackId:@"MycallbackId#1"} exts:@{@"animated":@(YES)} onPageFinished:^(NSDictionary *result) { url: 'https://github.com/alibaba/flutter_boost.git'
NSLog(@"call me when page finished, and your result is:%@", result); ref: 'feature/flutter_1.9_androidx_upgrade'
} completion:^(BOOL f) {
NSLog(@"page is opened");
}];
//prsent the page
[FlutterBoostPlugin open:@"second" urlParams:@{@"present":@(YES),kPageCallBackId:@"MycallbackId#2"} exts:@{@"animated":@(YES)} onPageFinished:^(NSDictionary *result) {
NSLog(@"call me when page finished, and your result is:%@", result);
} completion:^(BOOL f) {
NSLog(@"page is presented");
}];
//close the page
[FlutterBoostPlugin close:yourUniqueId result:yourdata exts:exts completion:nil];
``` ```
Android
```java
public class PageRouter {
public final static Map<String, String> pageName = new HashMap<String, String>() {{
put("first", "first");
put("second", "second");
put("tab", "tab");
put("sample://flutterPage", "flutterPage"); ## boost集成
}};
public static final String NATIVE_PAGE_URL = "sample://nativePage"; 集成请看boost的Examples
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 = NewBoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params)
.backgroundMode(NewBoostFlutterActivity.BackgroundMode.opaque).build(context);
context.startActivity(intent);
} else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) {
context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
return true;
} else if (url.startsWith(NATIVE_PAGE_URL)) {
context.startActivity(new Intent(context, NativePageActivity.class));
return true;
} else {
return false;
}
} catch (Throwable t) {
return false;
}
return false;
}
}
```
## 使用Flutter Boost在dart代码打开页面。
Dart
```java
FlutterBoost.singleton
.open("sample://flutterFragmentPage")
```
<img width="200" src="https://img.alicdn.com/tfs/TB1JSzVeYY1gK0jSZTEXXXDQVXa-892-1213.jpg">
## 使用Flutter Boost在dart代码关闭页面。
```java
FlutterBoost.singleton.close(uniqueId);
```
# Examples
更详细的使用例子请参考Demo
# 许可证 # 许可证
该项目根据MIT许可证授权 - 有关详细信息,请参阅[LICENSE.md](LICENSE.md)文件 该项目根据MIT许可证授权 - 有关详细信息,请参阅[LICENSE.md](LICENSE.md)文件
<a name="Acknowledgments"> </a> <a name="Acknowledgments"> </a>
# 问题反馈群(钉钉群)
<img width="200" src="https://img.alicdn.com/tfs/TB1JSzVeYY1gK0jSZTEXXXDQVXa-892-1213.jpg">
## 关于我们 ## 关于我们
......
...@@ -5,7 +5,6 @@ import android.content.Context; ...@@ -5,7 +5,6 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import io.flutter.Log; import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding;
import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.BinaryMessenger;
...@@ -46,8 +45,8 @@ class BoostRegistrar implements Registrar, FlutterPlugin, ActivityAware { ...@@ -46,8 +45,8 @@ class BoostRegistrar implements Registrar, FlutterPlugin, ActivityAware {
if(this.activityPluginBinding != null){ if(this.activityPluginBinding != null){
return this.activityPluginBinding.getActivity(); return this.activityPluginBinding.getActivity();
} }
if(NewFlutterBoost.instance().currentActivity()!=null){ if(FlutterBoost.instance().currentActivity()!=null){
return NewFlutterBoost.instance().currentActivity(); return FlutterBoost.instance().currentActivity();
} }
return null; return null;
} }
......
...@@ -154,7 +154,7 @@ public class ContainerRecord implements IContainerRecord { ...@@ -154,7 +154,7 @@ public class ContainerRecord implements IContainerRecord {
map.put("name", mContainer.getContainerUrl()); map.put("name", mContainer.getContainerUrl());
map.put("uniqueId", mUniqueId); map.put("uniqueId", mUniqueId);
NewFlutterBoost.instance().channel().sendEvent("lifecycle", map); FlutterBoost.instance().channel().sendEvent("lifecycle", map);
// mContainer.getBoostFlutterView().onBackPressed(); // mContainer.getBoostFlutterView().onBackPressed();
} }
...@@ -253,7 +253,7 @@ public class ContainerRecord implements IContainerRecord { ...@@ -253,7 +253,7 @@ public class ContainerRecord implements IContainerRecord {
args.put("pageName", url); args.put("pageName", url);
args.put("params", params); args.put("params", params);
args.put("uniqueId", uniqueId); args.put("uniqueId", uniqueId);
NewFlutterBoost.instance().channel().invokeMethod(method, args); FlutterBoost.instance().channel().invokeMethod(method, args);
} }
public void invokeChannelUnsafe(String method, String url, Map params, String uniqueId) { public void invokeChannelUnsafe(String method, String url, Map params, String uniqueId) {
...@@ -261,7 +261,7 @@ public class ContainerRecord implements IContainerRecord { ...@@ -261,7 +261,7 @@ public class ContainerRecord implements IContainerRecord {
args.put("pageName", url); args.put("pageName", url);
args.put("params", params); args.put("params", params);
args.put("uniqueId", uniqueId); args.put("uniqueId", uniqueId);
NewFlutterBoost.instance().channel().invokeMethodUnsafe(method, args); FlutterBoost.instance().channel().invokeMethodUnsafe(method, args);
} }
} }
......
...@@ -60,7 +60,7 @@ public class Debuger { ...@@ -60,7 +60,7 @@ public class Debuger {
public static boolean isDebug(){ public static boolean isDebug(){
try { try {
return NewFlutterBoost.instance().platform().isDebug(); return FlutterBoost.instance().platform().isDebug();
}catch (Throwable t){ }catch (Throwable t){
return false; return false;
} }
......
...@@ -7,13 +7,10 @@ import android.content.Context; ...@@ -7,13 +7,10 @@ import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.idlefish.flutterboost.interfaces.*; import com.idlefish.flutterboost.interfaces.*;
import io.flutter.Log;
import io.flutter.embedding.android.FlutterView; import io.flutter.embedding.android.FlutterView;
import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.dart.DartExecutor; import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry;
import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry;
import io.flutter.view.FlutterMain; import io.flutter.view.FlutterMain;
...@@ -21,7 +18,7 @@ import java.lang.reflect.Method; ...@@ -21,7 +18,7 @@ import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class NewFlutterBoost { public class FlutterBoost {
private Platform mPlatform; private Platform mPlatform;
...@@ -29,20 +26,21 @@ public class NewFlutterBoost { ...@@ -29,20 +26,21 @@ public class NewFlutterBoost {
private FlutterEngine mEngine; private FlutterEngine mEngine;
private Activity mCurrentActiveActivity; private Activity mCurrentActiveActivity;
private PluginRegistry mRegistry; private PluginRegistry mRegistry;
static NewFlutterBoost sInstance = null; static FlutterBoost sInstance = null;
private long FlutterPostFrameCallTime=0; private long FlutterPostFrameCallTime = 0;
public long getFlutterPostFrameCallTime(){ public long getFlutterPostFrameCallTime() {
return FlutterPostFrameCallTime; return FlutterPostFrameCallTime;
} }
public void setFlutterPostFrameCallTime(long FlutterPostFrameCallTime){ public void setFlutterPostFrameCallTime(long FlutterPostFrameCallTime) {
this.FlutterPostFrameCallTime=FlutterPostFrameCallTime; this.FlutterPostFrameCallTime = FlutterPostFrameCallTime;
} }
public static NewFlutterBoost instance() {
public static FlutterBoost instance() {
if (sInstance == null) { if (sInstance == null) {
sInstance = new NewFlutterBoost(); sInstance = new FlutterBoost();
} }
return sInstance; return sInstance;
} }
...@@ -53,19 +51,13 @@ public class NewFlutterBoost { ...@@ -53,19 +51,13 @@ public class NewFlutterBoost {
mPlatform = platform; mPlatform = platform;
mManager = new FlutterViewContainerManager(); mManager = new FlutterViewContainerManager();
platform.getApplication().registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { platform.getApplication().registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override @Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.e("bbbb1", "xxxxx"); mCurrentActiveActivity = activity;
mCurrentActiveActivity=activity;
if (mPlatform.whenEngineStart() == ConfigBuilder.ANY_ACTIVITY_CREATED) { if (mPlatform.whenEngineStart() == ConfigBuilder.ANY_ACTIVITY_CREATED) {
Log.e("bbbb2", "xxxxx");
doInitialFlutter(); doInitialFlutter();
} }
} }
...@@ -133,33 +125,24 @@ public class NewFlutterBoost { ...@@ -133,33 +125,24 @@ public class NewFlutterBoost {
} }
} }
public void doInitialFlutter() { public void doInitialFlutter() {
if(mEngine!=null) return; if (mEngine != null) return;
FlutterEngine flutterEngine = createEngine(); FlutterEngine flutterEngine = createEngine();
if(mPlatform.lifecycleListener!=null){ if (mPlatform.lifecycleListener != null) {
mPlatform.lifecycleListener.onEngineCreated(); mPlatform.lifecycleListener.onEngineCreated();
} }
if (flutterEngine.getDartExecutor().isExecutingDart()) { if (flutterEngine.getDartExecutor().isExecutingDart()) {
// No warning is logged because this situation will happen on every config
// change if the developer does not choose to retain the Fragment instance.
// So this is expected behavior in many cases.
return; return;
} }
// The engine needs to receive the Flutter app's initial route before executing any
// Dart code to ensure that the initial route arrives in time to be applied.
if (mPlatform.initialRoute() != null) { if (mPlatform.initialRoute() != null) {
flutterEngine.getNavigationChannel().setInitialRoute(mPlatform.initialRoute()); flutterEngine.getNavigationChannel().setInitialRoute(mPlatform.initialRoute());
} }
// Configure the Dart entrypoint and execute it.
DartExecutor.DartEntrypoint entrypoint = new DartExecutor.DartEntrypoint( DartExecutor.DartEntrypoint entrypoint = new DartExecutor.DartEntrypoint(
FlutterMain.findAppBundlePath(), FlutterMain.findAppBundlePath(),
"main" "main"
...@@ -167,7 +150,7 @@ public class NewFlutterBoost { ...@@ -167,7 +150,7 @@ public class NewFlutterBoost {
flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint); flutterEngine.getDartExecutor().executeDartEntrypoint(entrypoint);
mRegistry = new BoostPluginRegistry(createEngine()); mRegistry = new BoostPluginRegistry(createEngine());
registerPlugins(); mPlatform.registerPlugins(mRegistry);
} }
...@@ -200,7 +183,11 @@ public class NewFlutterBoost { ...@@ -200,7 +183,11 @@ public class NewFlutterBoost {
private INativeRouter router = null; private INativeRouter router = null;
private BoostLifecycleListener lifecycleListener; private BoostLifecycleListener lifecycleListener;
private BoostPluginsRegister boostPluginsRegister;
public ConfigBuilder(Application app, INativeRouter router) { public ConfigBuilder(Application app, INativeRouter router) {
this.router = router; this.router = router;
...@@ -227,19 +214,24 @@ public class NewFlutterBoost { ...@@ -227,19 +214,24 @@ public class NewFlutterBoost {
return this; return this;
} }
public ConfigBuilder whenEngineStart( int whenEngineStart) { public ConfigBuilder whenEngineStart(int whenEngineStart) {
this.whenEngineStart = whenEngineStart; this.whenEngineStart = whenEngineStart;
return this; return this;
} }
public ConfigBuilder whenEngineDestory( int whenEngineDestory) {
public ConfigBuilder whenEngineDestory(int whenEngineDestory) {
this.whenEngineDestory = whenEngineDestory; this.whenEngineDestory = whenEngineDestory;
return this; return this;
} }
public ConfigBuilder lifecycleListener( BoostLifecycleListener lifecycleListener) { public ConfigBuilder lifecycleListener(BoostLifecycleListener lifecycleListener) {
this.lifecycleListener = lifecycleListener; this.lifecycleListener = lifecycleListener;
return this; return this;
} }
public ConfigBuilder pluginsRegister(BoostPluginsRegister boostPluginsRegister) {
this.boostPluginsRegister = boostPluginsRegister;
return this;
}
public Platform build() { public Platform build() {
Platform platform = new Platform() { Platform platform = new Platform() {
...@@ -277,8 +269,8 @@ public class NewFlutterBoost { ...@@ -277,8 +269,8 @@ public class NewFlutterBoost {
} }
}; };
platform.lifecycleListener=this.lifecycleListener; platform.lifecycleListener = this.lifecycleListener;
platform.pluginsRegister=this.boostPluginsRegister;
return platform; return platform;
} }
...@@ -305,11 +297,11 @@ public class NewFlutterBoost { ...@@ -305,11 +297,11 @@ public class NewFlutterBoost {
return mManager.findContainerById(id); return mManager.findContainerById(id);
} }
public PluginRegistry getPluginRegistry(){ public PluginRegistry getPluginRegistry() {
return mRegistry; return mRegistry;
} }
private FlutterEngine createEngine(){ private FlutterEngine createEngine() {
if (mEngine == null) { if (mEngine == null) {
FlutterMain.startInitialization(mPlatform.getApplication()); FlutterMain.startInitialization(mPlatform.getApplication());
...@@ -324,44 +316,36 @@ public class NewFlutterBoost { ...@@ -324,44 +316,36 @@ public class NewFlutterBoost {
} }
private void registerPlugins() {
try {
Class clz = Class.forName("io.flutter.plugins.GeneratedPluginRegistrant");
Method method = clz.getDeclaredMethod("registerWith", PluginRegistry.class);
method.invoke(null, mRegistry);
} catch (Throwable t) {
throw new RuntimeException(t);
}
if(mPlatform.lifecycleListener!=null){
mPlatform.lifecycleListener.onPluginsRegistered();
}
}
public FlutterEngine engineProvider() { public FlutterEngine engineProvider() {
return mEngine; return mEngine;
} }
public void boostDestroy(){ public void boostDestroy() {
if(mEngine!=null){ if (mEngine != null) {
mEngine.destroy(); mEngine.destroy();
} }
if(mPlatform.lifecycleListener!=null){ if (mPlatform.lifecycleListener != null) {
mPlatform.lifecycleListener.onEngineDestroy(); mPlatform.lifecycleListener.onEngineDestroy();
} }
mEngine=null; mEngine = null;
mRegistry=null; mRegistry = null;
mCurrentActiveActivity=null; mCurrentActiveActivity = null;
} }
public interface BoostLifecycleListener { public interface BoostLifecycleListener {
void onEngineCreated(); void onEngineCreated();
void onPluginsRegistered(); void onPluginsRegistered();
void onEngineDestroy(); void onEngineDestroy();
} }
public interface BoostPluginsRegister {
void registerPlugins(PluginRegistry mRegistry);
}
} }
...@@ -47,13 +47,6 @@ public class FlutterBoostPlugin { ...@@ -47,13 +47,6 @@ public class FlutterBoostPlugin {
a.onChannelRegistered(sInstance); a.onChannelRegistered(sInstance);
} }
// if (NewFlutterBoost.instance() != null) {
// final IStateListener stateListener = NewFlutterBoost.instance().mStateListener;
// if (stateListener != null) {
// stateListener.onChannelRegistered(registrar, sInstance);
// }
// }
sActions.clear(); sActions.clear();
} }
...@@ -196,7 +189,7 @@ public class FlutterBoostPlugin { ...@@ -196,7 +189,7 @@ public class FlutterBoostPlugin {
@Override @Override
public void onMethodCall(MethodCall methodCall, final MethodChannel.Result result) { public void onMethodCall(MethodCall methodCall, final MethodChannel.Result result) {
FlutterViewContainerManager mManager = (FlutterViewContainerManager) NewFlutterBoost.instance().containerManager(); FlutterViewContainerManager mManager = (FlutterViewContainerManager) FlutterBoost.instance().containerManager();
switch (methodCall.method) { switch (methodCall.method) {
case "pageOnStart": { case "pageOnStart": {
Map<String, Object> pageInfo = new HashMap<>(); Map<String, Object> pageInfo = new HashMap<>();
...@@ -215,7 +208,7 @@ public class FlutterBoostPlugin { ...@@ -215,7 +208,7 @@ public class FlutterBoostPlugin {
} }
result.success(pageInfo); result.success(pageInfo);
NewFlutterBoost.instance().setFlutterPostFrameCallTime(new Date().getTime()); FlutterBoost.instance().setFlutterPostFrameCallTime(new Date().getTime());
} catch (Throwable t) { } catch (Throwable t) {
......
...@@ -25,7 +25,6 @@ package com.idlefish.flutterboost; ...@@ -25,7 +25,6 @@ package com.idlefish.flutterboost;
import android.content.Context; import android.content.Context;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.SparseArray;
import com.idlefish.flutterboost.interfaces.IContainerManager; import com.idlefish.flutterboost.interfaces.IContainerManager;
import com.idlefish.flutterboost.interfaces.IContainerRecord; import com.idlefish.flutterboost.interfaces.IContainerRecord;
...@@ -41,7 +40,6 @@ import java.util.LinkedHashMap; ...@@ -41,7 +40,6 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Stack; import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
public class FlutterViewContainerManager implements IContainerManager { public class FlutterViewContainerManager implements IContainerManager {
...@@ -85,8 +83,8 @@ public class FlutterViewContainerManager implements IContainerManager { ...@@ -85,8 +83,8 @@ public class FlutterViewContainerManager implements IContainerManager {
mRecordStack.remove(record); mRecordStack.remove(record);
mRecordMap.remove(record.getContainer()); mRecordMap.remove(record.getContainer());
if(mRecordMap.isEmpty()){ if(mRecordMap.isEmpty()){
if( NewFlutterBoost.instance().platform().whenEngineDestroy()== NewFlutterBoost.ConfigBuilder.All_FLUTTER_ACTIVITY_DESTROY){ if( FlutterBoost.instance().platform().whenEngineDestroy()== FlutterBoost.ConfigBuilder.All_FLUTTER_ACTIVITY_DESTROY){
NewFlutterBoost.instance().boostDestroy(); FlutterBoost.instance().boostDestroy();
} }
} }
...@@ -118,9 +116,9 @@ public class FlutterViewContainerManager implements IContainerManager { ...@@ -118,9 +116,9 @@ public class FlutterViewContainerManager implements IContainerManager {
} }
void openContainer(String url, Map<String, Object> urlParams, Map<String, Object> exts,OnResult onResult) { void openContainer(String url, Map<String, Object> urlParams, Map<String, Object> exts,OnResult onResult) {
Context context = NewFlutterBoost.instance().currentActivity(); Context context = FlutterBoost.instance().currentActivity();
if(context == null) { if(context == null) {
context =NewFlutterBoost.instance().platform().getApplication(); context = FlutterBoost.instance().platform().getApplication();
} }
if(urlParams == null) { if(urlParams == null) {
...@@ -141,7 +139,7 @@ public class FlutterViewContainerManager implements IContainerManager { ...@@ -141,7 +139,7 @@ public class FlutterViewContainerManager implements IContainerManager {
mOnResults.put(currentTopRecord.uniqueId(),onResult); mOnResults.put(currentTopRecord.uniqueId(),onResult);
} }
NewFlutterBoost.instance().platform().openContainer(context,url,urlParams,requestCode,exts); FlutterBoost.instance().platform().openContainer(context,url,urlParams,requestCode,exts);
} }
IContainerRecord closeContainer(String uniqueId, Map<String, Object> result,Map<String,Object> exts) { IContainerRecord closeContainer(String uniqueId, Map<String, Object> result,Map<String,Object> exts) {
...@@ -157,7 +155,7 @@ public class FlutterViewContainerManager implements IContainerManager { ...@@ -157,7 +155,7 @@ public class FlutterViewContainerManager implements IContainerManager {
Debuger.exception("closeContainer can not find uniqueId:" + uniqueId); Debuger.exception("closeContainer can not find uniqueId:" + uniqueId);
} }
NewFlutterBoost.instance().platform().closeContainer(targetRecord,result,exts); FlutterBoost.instance().platform().closeContainer(targetRecord,result,exts);
return targetRecord; return targetRecord;
} }
......
...@@ -2,6 +2,7 @@ package com.idlefish.flutterboost; ...@@ -2,6 +2,7 @@ package com.idlefish.flutterboost;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.util.Log;
import com.idlefish.flutterboost.interfaces.IContainerRecord; import com.idlefish.flutterboost.interfaces.IContainerRecord;
import java.lang.reflect.Method; import java.lang.reflect.Method;
...@@ -17,6 +18,7 @@ public abstract class Platform { ...@@ -17,6 +18,7 @@ public abstract class Platform {
public abstract void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts); public abstract void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts);
public abstract int whenEngineStart(); public abstract int whenEngineStart();
public abstract int whenEngineDestroy(); public abstract int whenEngineDestroy();
public abstract FlutterView.RenderMode renderMode(); public abstract FlutterView.RenderMode renderMode();
...@@ -25,7 +27,9 @@ public abstract class Platform { ...@@ -25,7 +27,9 @@ public abstract class Platform {
public abstract String initialRoute(); public abstract String initialRoute();
public NewFlutterBoost.BoostLifecycleListener lifecycleListener; public FlutterBoost.BoostLifecycleListener lifecycleListener;
public FlutterBoost.BoostPluginsRegister pluginsRegister;
public void closeContainer(IContainerRecord record, Map<String, Object> result, Map<String, Object> exts) { public void closeContainer(IContainerRecord record, Map<String, Object> result, Map<String, Object> exts) {
if (record == null) return; if (record == null) return;
...@@ -34,7 +38,21 @@ public abstract class Platform { ...@@ -34,7 +38,21 @@ public abstract class Platform {
} }
public void registerPlugins(PluginRegistry mRegistry) {
try {
Class clz = Class.forName("io.flutter.plugins.GeneratedPluginRegistrant");
Method method = clz.getDeclaredMethod("registerWith", PluginRegistry.class);
method.invoke(null, mRegistry);
} catch (Throwable t) {
Log.i("flutterboost.platform",t.toString());
}
if(pluginsRegister!=null){
pluginsRegister.registerPlugins(mRegistry);
}
if (lifecycleListener!= null) {
lifecycleListener.onPluginsRegistered();
}
}
} }
...@@ -19,8 +19,7 @@ import androidx.annotation.NonNull; ...@@ -19,8 +19,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import com.idlefish.flutterboost.NewFlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.XFlutterView; import com.idlefish.flutterboost.XFlutterView;
import io.flutter.Log; import io.flutter.Log;
import io.flutter.embedding.android.DrawableSplashScreen; import io.flutter.embedding.android.DrawableSplashScreen;
...@@ -29,13 +28,12 @@ import io.flutter.embedding.android.SplashScreen; ...@@ -29,13 +28,12 @@ import io.flutter.embedding.android.SplashScreen;
import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.plugin.platform.PlatformPlugin; import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.view.FlutterMain;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class NewBoostFlutterActivity extends Activity public class BoostFlutterActivity extends Activity
implements FlutterActivityAndFragmentDelegate.Host, implements FlutterActivityAndFragmentDelegate.Host,
LifecycleOwner { LifecycleOwner {
...@@ -64,38 +62,34 @@ public class NewBoostFlutterActivity extends Activity ...@@ -64,38 +62,34 @@ public class NewBoostFlutterActivity extends Activity
public static NewEngineIntentBuilder withNewEngine() { public static NewEngineIntentBuilder withNewEngine() {
return new NewEngineIntentBuilder(NewBoostFlutterActivity.class); return new NewEngineIntentBuilder(BoostFlutterActivity.class);
} }
public static class NewEngineIntentBuilder { public static class NewEngineIntentBuilder {
private final Class<? extends NewBoostFlutterActivity> activityClass; private final Class<? extends BoostFlutterActivity> activityClass;
private String backgroundMode = DEFAULT_BACKGROUND_MODE; private String backgroundMode = DEFAULT_BACKGROUND_MODE;
private String url = ""; private String url = "";
private Map params = new HashMap(); private Map params = new HashMap();
protected NewEngineIntentBuilder(@NonNull Class<? extends BoostFlutterActivity> activityClass) {
protected NewEngineIntentBuilder(@NonNull Class<? extends NewBoostFlutterActivity> activityClass) {
this.activityClass = activityClass; this.activityClass = activityClass;
} }
public NewEngineIntentBuilder url(@NonNull String url) {
public NewEngineIntentBuilder url (@NonNull String url) {
this.url = url; this.url = url;
return this; return this;
} }
public NewEngineIntentBuilder params (@NonNull Map params) { public NewEngineIntentBuilder params(@NonNull Map params) {
this.params = params; this.params = params;
return this; return this;
} }
public NewEngineIntentBuilder backgroundMode(@NonNull BackgroundMode backgroundMode) { public NewEngineIntentBuilder backgroundMode(@NonNull BackgroundMode backgroundMode) {
this.backgroundMode = backgroundMode.name(); this.backgroundMode = backgroundMode.name();
return this; return this;
...@@ -104,7 +98,7 @@ public class NewBoostFlutterActivity extends Activity ...@@ -104,7 +98,7 @@ public class NewBoostFlutterActivity extends Activity
public Intent build(@NonNull Context context) { public Intent build(@NonNull Context context) {
SerializableMap serializableMap=new SerializableMap(); SerializableMap serializableMap = new SerializableMap();
serializableMap.setMap(params); serializableMap.setMap(params);
return new Intent(context, activityClass) return new Intent(context, activityClass)
...@@ -117,7 +111,7 @@ public class NewBoostFlutterActivity extends Activity ...@@ -117,7 +111,7 @@ public class NewBoostFlutterActivity extends Activity
public static class SerializableMap implements Serializable { public static class SerializableMap implements Serializable {
private Map<String,Object> map; private Map<String, Object> map;
public Map<String, Object> getMap() { public Map<String, Object> getMap() {
return map; return map;
...@@ -133,7 +127,7 @@ public class NewBoostFlutterActivity extends Activity ...@@ -133,7 +127,7 @@ public class NewBoostFlutterActivity extends Activity
@NonNull @NonNull
private LifecycleRegistry lifecycle; private LifecycleRegistry lifecycle;
public NewBoostFlutterActivity() { public BoostFlutterActivity() {
lifecycle = new LifecycleRegistry(this); lifecycle = new LifecycleRegistry(this);
} }
...@@ -175,7 +169,7 @@ public class NewBoostFlutterActivity extends Activity ...@@ -175,7 +169,7 @@ public class NewBoostFlutterActivity extends Activity
public SplashScreen provideSplashScreen() { public SplashScreen provideSplashScreen() {
Drawable manifestSplashDrawable = getSplashScreenFromManifest(); Drawable manifestSplashDrawable = getSplashScreenFromManifest();
if (manifestSplashDrawable != null) { if (manifestSplashDrawable != null) {
return new DrawableSplashScreen(manifestSplashDrawable, ImageView.ScaleType.CENTER,500L); return new DrawableSplashScreen(manifestSplashDrawable, ImageView.ScaleType.CENTER, 500L);
} else { } else {
return null; return null;
} }
...@@ -246,8 +240,8 @@ public class NewBoostFlutterActivity extends Activity ...@@ -246,8 +240,8 @@ public class NewBoostFlutterActivity extends Activity
} }
protected XFlutterView getFlutterView(){ protected XFlutterView getFlutterView() {
return delegate.getFlutterView(); return delegate.getFlutterView();
} }
@Override @Override
...@@ -372,7 +366,6 @@ public class NewBoostFlutterActivity extends Activity ...@@ -372,7 +366,6 @@ public class NewBoostFlutterActivity extends Activity
} }
/** /**
* Returns true if Flutter is running in "debug mode", and false otherwise. * Returns true if Flutter is running in "debug mode", and false otherwise.
* <p> * <p>
...@@ -432,7 +425,7 @@ public class NewBoostFlutterActivity extends Activity ...@@ -432,7 +425,7 @@ public class NewBoostFlutterActivity extends Activity
@Override @Override
public FlutterEngine provideFlutterEngine(@NonNull Context context) { public FlutterEngine provideFlutterEngine(@NonNull Context context) {
// No-op. Hook for subclasses. // No-op. Hook for subclasses.
return NewFlutterBoost.instance().engineProvider(); return FlutterBoost.instance().engineProvider();
} }
/** /**
...@@ -472,9 +465,6 @@ public class NewBoostFlutterActivity extends Activity ...@@ -472,9 +465,6 @@ public class NewBoostFlutterActivity extends Activity
} }
@Override @Override
public String getContainerUrl() { public String getContainerUrl() {
if (getIntent().hasExtra(EXTRA_URL)) { if (getIntent().hasExtra(EXTRA_URL)) {
...@@ -488,11 +478,11 @@ public class NewBoostFlutterActivity extends Activity ...@@ -488,11 +478,11 @@ public class NewBoostFlutterActivity extends Activity
public Map getContainerUrlParams() { public Map getContainerUrlParams() {
if (getIntent().hasExtra(EXTRA_PARAMS)) { if (getIntent().hasExtra(EXTRA_PARAMS)) {
SerializableMap serializableMap= (SerializableMap)getIntent().getSerializableExtra(EXTRA_PARAMS); SerializableMap serializableMap = (SerializableMap) getIntent().getSerializableExtra(EXTRA_PARAMS);
return serializableMap.getMap(); return serializableMap.getMap();
} }
Map<String,String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
return params; return params;
} }
......
...@@ -21,7 +21,7 @@ import java.util.Map; ...@@ -21,7 +21,7 @@ import java.util.Map;
import com.idlefish.flutterboost.BoostPluginRegistry; import com.idlefish.flutterboost.BoostPluginRegistry;
import com.idlefish.flutterboost.NewFlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Utils; import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.XFlutterView; import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.interfaces.IFlutterViewContainer; import com.idlefish.flutterboost.interfaces.IFlutterViewContainer;
...@@ -33,11 +33,10 @@ import io.flutter.embedding.engine.FlutterEngine; ...@@ -33,11 +33,10 @@ import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.platform.PlatformPlugin; import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.view.FlutterMain;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer { public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer {
private static final String TAG = "FlutterActivityAndFragmentDelegate"; private static final String TAG = "FlutterActivityAndFragmentDelegate";
...@@ -59,8 +58,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -59,8 +58,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
protected IOperateSyncer mSyncer; protected IOperateSyncer mSyncer;
FlutterActivityAndFragmentDelegate(@NonNull Host host) { FlutterActivityAndFragmentDelegate(@NonNull Host host) {
this.host = host; this.host = host;
} }
...@@ -78,14 +75,14 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -78,14 +75,14 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
return flutterEngine; return flutterEngine;
} }
XFlutterView getFlutterView(){ XFlutterView getFlutterView() {
return flutterView; return flutterView;
} }
void onAttach(@NonNull Context context) { void onAttach(@NonNull Context context) {
ensureAlive(); ensureAlive();
if (NewFlutterBoost.instance().platform().whenEngineStart() == NewFlutterBoost.ConfigBuilder.FLUTTER_ACTIVITY_CREATED) { if (FlutterBoost.instance().platform().whenEngineStart() == FlutterBoost.ConfigBuilder.FLUTTER_ACTIVITY_CREATED) {
NewFlutterBoost.instance().doInitialFlutter(); FlutterBoost.instance().doInitialFlutter();
} }
// When "retain instance" is true, the FlutterEngine will survive configuration // When "retain instance" is true, the FlutterEngine will survive configuration
// changes. Therefore, we create a new one only if one does not already exist. // changes. Therefore, we create a new one only if one does not already exist.
...@@ -108,8 +105,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -108,8 +105,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
} }
private void setupFlutterEngine() { private void setupFlutterEngine() {
Log.d(TAG, "Setting up FlutterEngine."); Log.d(TAG, "Setting up FlutterEngine.");
...@@ -139,10 +134,10 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -139,10 +134,10 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
); );
mSyncer = NewFlutterBoost.instance().containerManager().generateSyncer(this); mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this);
ensureAlive(); ensureAlive();
flutterView = new XFlutterView(host.getActivity(), NewFlutterBoost.instance().platform().renderMode(), host.getTransparencyMode()); flutterView = new XFlutterView(host.getActivity(), FlutterBoost.instance().platform().renderMode(), host.getTransparencyMode());
flutterSplashView = new FlutterSplashView(host.getContext()); flutterSplashView = new FlutterSplashView(host.getContext());
...@@ -173,7 +168,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -173,7 +168,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
} }
void onResume() { void onResume() {
mSyncer.onAppear(); mSyncer.onAppear();
...@@ -181,9 +175,9 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -181,9 +175,9 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
ensureAlive(); ensureAlive();
flutterEngine.getLifecycleChannel().appIsResumed(); flutterEngine.getLifecycleChannel().appIsResumed();
BoostPluginRegistry registry= (BoostPluginRegistry)NewFlutterBoost.instance().getPluginRegistry(); BoostPluginRegistry registry = (BoostPluginRegistry) FlutterBoost.instance().getPluginRegistry();
ActivityPluginBinding binding=registry.getRegistrarAggregate().getActivityPluginBinding(); ActivityPluginBinding binding = registry.getRegistrarAggregate().getActivityPluginBinding();
if(binding!=null&&(binding.getActivity()!=this.host.getActivity())){ if (binding != null && (binding.getActivity() != this.host.getActivity())) {
flutterEngine.getActivityControlSurface().attachToActivity( flutterEngine.getActivityControlSurface().attachToActivity(
host.getActivity(), host.getActivity(),
host.getLifecycle() host.getLifecycle()
...@@ -196,7 +190,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -196,7 +190,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
void onPostResume() { void onPostResume() {
Log.v(TAG, "onPostResume()"); Log.v(TAG, "onPostResume()");
ensureAlive(); ensureAlive();
Utils.setStatusBarLightMode(host.getActivity(),true); Utils.setStatusBarLightMode(host.getActivity(), true);
} }
...@@ -222,12 +216,16 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -222,12 +216,16 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
mSyncer.onDestroy(); mSyncer.onDestroy();
ensureAlive(); ensureAlive();
BoostPluginRegistry registry= (BoostPluginRegistry)NewFlutterBoost.instance().getPluginRegistry(); BoostPluginRegistry registry = (BoostPluginRegistry) FlutterBoost.instance().getPluginRegistry();
ActivityPluginBinding binding=registry.getRegistrarAggregate().getActivityPluginBinding(); if (registry != null) {
if(binding!=null&&(binding.getActivity()==this.host.getActivity())){ ActivityPluginBinding binding = registry.getRegistrarAggregate().getActivityPluginBinding();
registry.getRegistrarAggregate().onDetachedFromActivityForConfigChanges(); if (binding != null && (binding.getActivity() == this.host.getActivity())) {
flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
registry.getRegistrarAggregate().onDetachedFromActivityForConfigChanges();
flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
}
} }
flutterView.release(); flutterView.release();
} }
...@@ -238,7 +236,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -238,7 +236,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
ensureAlive(); ensureAlive();
// Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment, // Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment,
// and this Fragment's Activity. // and this Fragment's Activity.
if (platformPlugin != null) { if (platformPlugin != null) {
...@@ -288,16 +285,16 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -288,16 +285,16 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
void onActivityResult(int requestCode, int resultCode, Intent data) { void onActivityResult(int requestCode, int resultCode, Intent data) {
mSyncer.onActivityResult(requestCode,resultCode,data); mSyncer.onActivityResult(requestCode, resultCode, data);
Map<String,Object> result = null; Map<String, Object> result = null;
if(data != null) { if (data != null) {
Serializable rlt = data.getSerializableExtra(RESULT_KEY); Serializable rlt = data.getSerializableExtra(RESULT_KEY);
if(rlt instanceof Map) { if (rlt instanceof Map) {
result = (Map<String,Object>)rlt; result = (Map<String, Object>) rlt;
} }
} }
mSyncer.onContainerResult(requestCode,resultCode,result); mSyncer.onContainerResult(requestCode, resultCode, result);
ensureAlive(); ensureAlive();
...@@ -361,7 +358,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -361,7 +358,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
@Override @Override
public Activity getContextActivity() { public Activity getContextActivity() {
return (Activity)this.host.getActivity(); return (Activity) this.host.getActivity();
} }
@Override @Override
...@@ -372,10 +369,10 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -372,10 +369,10 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
@Override @Override
public void finishContainer(Map<String, Object> result) { public void finishContainer(Map<String, Object> result) {
if(result != null) { if (result != null) {
setBoostResult(this.host.getActivity(),new HashMap<>(result)); setBoostResult(this.host.getActivity(), new HashMap<>(result));
this.host.getActivity().finish(); this.host.getActivity().finish();
}else{ } else {
this.host.getActivity().finish(); this.host.getActivity().finish();
} }
...@@ -383,17 +380,17 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -383,17 +380,17 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
} }
public void setBoostResult(Activity activity, HashMap result) {
public void setBoostResult(Activity activity, HashMap result) {
Intent intent = new Intent(); Intent intent = new Intent();
if (result != null) { if (result != null) {
intent.putExtra(IFlutterViewContainer.RESULT_KEY, result); intent.putExtra(IFlutterViewContainer.RESULT_KEY, result);
} }
activity.setResult(Activity.RESULT_OK, intent); activity.setResult(Activity.RESULT_OK, intent);
} }
@Override @Override
public String getContainerUrl() { public String getContainerUrl() {
return this.host.getContainerUrl(); return this.host.getContainerUrl();
} }
@Override @Override
...@@ -413,7 +410,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -413,7 +410,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
} }
/** /**
* The {@link FlutterActivity} or {@link NewFlutterFragment} that owns this * The {@link FlutterActivity} or {@link FlutterFragment} that owns this
* {@code FlutterActivityAndFragmentDelegate}. * {@code FlutterActivityAndFragmentDelegate}.
*/ */
/* package */ interface Host extends SplashScreenProvider, FlutterEngineProvider, FlutterEngineConfigurator { /* package */ interface Host extends SplashScreenProvider, FlutterEngineProvider, FlutterEngineConfigurator {
...@@ -487,12 +484,9 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine ...@@ -487,12 +484,9 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
boolean shouldAttachEngineToActivity(); boolean shouldAttachEngineToActivity();
String getContainerUrl();
Map getContainerUrlParams();
String getContainerUrl() ;
Map getContainerUrlParams() ;
} }
......
...@@ -14,20 +14,18 @@ import android.view.LayoutInflater; ...@@ -14,20 +14,18 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.idlefish.flutterboost.NewFlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.XFlutterView; import com.idlefish.flutterboost.XFlutterView;
import io.flutter.embedding.android.*; import io.flutter.embedding.android.*;
import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener;
import io.flutter.plugin.platform.PlatformPlugin; import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.view.FlutterMain;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class NewFlutterFragment extends Fragment implements FlutterActivityAndFragmentDelegate.Host { public class FlutterFragment extends Fragment implements FlutterActivityAndFragmentDelegate.Host {
private static final String TAG = "NewFlutterFragment"; private static final String TAG = "NewFlutterFragment";
...@@ -94,7 +92,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -94,7 +92,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
* To use a cached {@link FlutterEngine} instead of creating a new one, use * To use a cached {@link FlutterEngine} instead of creating a new one, use
*/ */
@NonNull @NonNull
public static NewFlutterFragment createDefault() { public static FlutterFragment createDefault() {
return new NewEngineFragmentBuilder().build(); return new NewEngineFragmentBuilder().build();
} }
...@@ -109,7 +107,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -109,7 +107,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
public static class NewEngineFragmentBuilder { public static class NewEngineFragmentBuilder {
private final Class<? extends NewFlutterFragment> fragmentClass; private final Class<? extends FlutterFragment> fragmentClass;
private FlutterShellArgs shellArgs = null; private FlutterShellArgs shellArgs = null;
private FlutterView.RenderMode renderMode = FlutterView.RenderMode.surface; private FlutterView.RenderMode renderMode = FlutterView.RenderMode.surface;
...@@ -117,24 +115,24 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -117,24 +115,24 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
private boolean shouldAttachEngineToActivity = true; private boolean shouldAttachEngineToActivity = true;
private String url = ""; private String url = "";
private Map params = new HashMap(); private Map params = new HashMap();
/** /**
* Constructs a {@code NewEngineFragmentBuilder} that is configured to construct an instance of * Constructs a {@code NewEngineFragmentBuilder} that is configured to construct an instance of
* {@code NewFlutterFragment}. * {@code NewFlutterFragment}.
*/ */
public NewEngineFragmentBuilder() { public NewEngineFragmentBuilder() {
fragmentClass = NewFlutterFragment.class; fragmentClass = FlutterFragment.class;
} }
/** /**
* Constructs a {@code NewEngineFragmentBuilder} that is configured to construct an instance of * Constructs a {@code NewEngineFragmentBuilder} that is configured to construct an instance of
* {@code subclass}, which extends {@code NewFlutterFragment}. * {@code subclass}, which extends {@code NewFlutterFragment}.
*/ */
public NewEngineFragmentBuilder(@NonNull Class<? extends NewFlutterFragment> subclass) { public NewEngineFragmentBuilder(@NonNull Class<? extends FlutterFragment> subclass) {
fragmentClass = subclass; fragmentClass = subclass;
} }
/** /**
* Any special configuration arguments for the Flutter engine * Any special configuration arguments for the Flutter engine
*/ */
...@@ -157,16 +155,18 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -157,16 +155,18 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
this.renderMode = renderMode; this.renderMode = renderMode;
return this; return this;
} }
public NewEngineFragmentBuilder url (@NonNull String url) {
public NewEngineFragmentBuilder url(@NonNull String url) {
this.url = url; this.url = url;
return this; return this;
} }
public NewEngineFragmentBuilder params (@NonNull Map params) { public NewEngineFragmentBuilder params(@NonNull Map params) {
this.params = params; this.params = params;
return this; return this;
} }
/** /**
* Support a {@link FlutterView.TransparencyMode#transparent} background within {@link FlutterView}, * Support a {@link FlutterView.TransparencyMode#transparent} background within {@link FlutterView},
* or force an {@link FlutterView.TransparencyMode#opaque} background. * or force an {@link FlutterView.TransparencyMode#opaque} background.
...@@ -180,7 +180,6 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -180,7 +180,6 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
} }
@NonNull @NonNull
protected Bundle createArgs() { protected Bundle createArgs() {
Bundle args = new Bundle(); Bundle args = new Bundle();
...@@ -190,7 +189,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -190,7 +189,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
args.putStringArray(ARG_FLUTTER_INITIALIZATION_ARGS, shellArgs.toArray()); args.putStringArray(ARG_FLUTTER_INITIALIZATION_ARGS, shellArgs.toArray());
} }
NewBoostFlutterActivity.SerializableMap serializableMap=new NewBoostFlutterActivity.SerializableMap(); BoostFlutterActivity.SerializableMap serializableMap = new BoostFlutterActivity.SerializableMap();
serializableMap.setMap(params); serializableMap.setMap(params);
args.putString(EXTRA_URL, url); args.putString(EXTRA_URL, url);
...@@ -208,7 +207,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -208,7 +207,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
* properties set on this {@code Builder}. * properties set on this {@code Builder}.
*/ */
@NonNull @NonNull
public <T extends NewFlutterFragment> T build() { public <T extends FlutterFragment> T build() {
try { try {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
T frag = (T) fragmentClass.getDeclaredConstructor().newInstance(); T frag = (T) fragmentClass.getDeclaredConstructor().newInstance();
...@@ -234,11 +233,11 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -234,11 +233,11 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
private FlutterActivityAndFragmentDelegate delegate; private FlutterActivityAndFragmentDelegate delegate;
protected XFlutterView getFlutterView(){ protected XFlutterView getFlutterView() {
return delegate.getFlutterView(); return delegate.getFlutterView();
} }
public NewFlutterFragment() { public FlutterFragment() {
// Ensure that we at least have an empty Bundle of arguments so that we don't // Ensure that we at least have an empty Bundle of arguments so that we don't
// need to continually check for null arguments before grabbing one. // need to continually check for null arguments before grabbing one.
setArguments(new Bundle()); setArguments(new Bundle());
...@@ -435,7 +434,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -435,7 +434,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
@Nullable @Nullable
public FlutterEngine provideFlutterEngine(@NonNull Context context) { public FlutterEngine provideFlutterEngine(@NonNull Context context) {
return NewFlutterBoost.instance().engineProvider(); return FlutterBoost.instance().engineProvider();
} }
/** /**
...@@ -494,8 +493,6 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -494,8 +493,6 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
} }
@Override @Override
public String getContainerUrl() { public String getContainerUrl() {
...@@ -507,7 +504,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr ...@@ -507,7 +504,7 @@ public class NewFlutterFragment extends Fragment implements FlutterActivityAndFr
@Override @Override
public Map getContainerUrlParams() { public Map getContainerUrlParams() {
NewBoostFlutterActivity.SerializableMap serializableMap= (NewBoostFlutterActivity.SerializableMap) getArguments().getSerializable(EXTRA_PARAMS); BoostFlutterActivity.SerializableMap serializableMap = (BoostFlutterActivity.SerializableMap) getArguments().getSerializable(EXTRA_PARAMS);
return serializableMap.getMap(); return serializableMap.getMap();
} }
......
...@@ -49,8 +49,6 @@ public class FlutterSplashView extends FrameLayout { ...@@ -49,8 +49,6 @@ public class FlutterSplashView extends FrameLayout {
@Override @Override
public void onFlutterEngineAttachedToFlutterView(@NonNull FlutterEngine engine) { public void onFlutterEngineAttachedToFlutterView(@NonNull FlutterEngine engine) {
flutterView.removeFlutterEngineAttachmentListener(this); flutterView.removeFlutterEngineAttachmentListener(this);
// displayFlutterViewWithSplash(flutterView, splashScreen);
// splashScreenTransitionNeededNow();
} }
@Override @Override
...@@ -60,15 +58,16 @@ public class FlutterSplashView extends FrameLayout { ...@@ -60,15 +58,16 @@ public class FlutterSplashView extends FrameLayout {
@NonNull @NonNull
private final OnFirstFrameRenderedListener onFirstFrameRenderedListener = new OnFirstFrameRenderedListener() { private final OnFirstFrameRenderedListener onFirstFrameRenderedListener = new OnFirstFrameRenderedListener() {
int i=0; int i = 0;
@Override @Override
public void onFirstFrameRendered() { public void onFirstFrameRendered() {
if(NewFlutterBoost.instance().platform().whenEngineStart()== NewFlutterBoost.ConfigBuilder.FLUTTER_ACTIVITY_CREATED){ if (FlutterBoost.instance().platform().whenEngineStart() == FlutterBoost.ConfigBuilder.FLUTTER_ACTIVITY_CREATED) {
long now=new Date().getTime(); long now = new Date().getTime();
long flutterPostFrameCallTime=NewFlutterBoost.instance().getFlutterPostFrameCallTime(); long flutterPostFrameCallTime = FlutterBoost.instance().getFlutterPostFrameCallTime();
if(flutterPostFrameCallTime!=0&& (now-flutterPostFrameCallTime)>800){ if (flutterPostFrameCallTime != 0 && (now - flutterPostFrameCallTime) > 800) {
if (splashScreen != null) { if (splashScreen != null) {
transitionToFlutter(); transitionToFlutter();
} }
...@@ -83,17 +82,13 @@ public class FlutterSplashView extends FrameLayout { ...@@ -83,17 +82,13 @@ public class FlutterSplashView extends FrameLayout {
}, 200); }, 200);
}else{ } else {
if (splashScreen != null) { if (splashScreen != null) {
transitionToFlutter(); transitionToFlutter();
} }
} }
} }
}; };
...@@ -119,7 +114,7 @@ public class FlutterSplashView extends FrameLayout { ...@@ -119,7 +114,7 @@ public class FlutterSplashView extends FrameLayout {
setSaveEnabled(true); setSaveEnabled(true);
if (mFlutterEngine == null) { if (mFlutterEngine == null) {
mFlutterEngine = NewFlutterBoost.instance().engineProvider(); mFlutterEngine = FlutterBoost.instance().engineProvider();
} }
} }
...@@ -155,80 +150,10 @@ public class FlutterSplashView extends FrameLayout { ...@@ -155,80 +150,10 @@ public class FlutterSplashView extends FrameLayout {
splashScreenView.setBackgroundColor(Color.WHITE); splashScreenView.setBackgroundColor(Color.WHITE);
addView(this.splashScreenView); addView(this.splashScreenView);
flutterView.addOnFirstFrameRenderedListener(onFirstFrameRenderedListener); flutterView.addOnFirstFrameRenderedListener(onFirstFrameRenderedListener);
// if (splashScreen != null) {
// if (this.isSplashScreenNeededNow()) {
// Log.v(TAG, "Showing splash screen UI.");
// this.splashScreenView = splashScreen.createSplashView(this.getContext(), this.splashScreenState);
// this.addView(this.splashScreenView);
// flutterView.addOnFirstFrameRenderedListener(this.onFirstFrameRenderedListener);
// } else if (this.isSplashScreenTransitionNeededNow()) {
// Log.v(TAG, "Showing an immediate splash transition to Flutter due to previously interrupted transition.");
// this.splashScreenView = splashScreen.createSplashView(this.getContext(), this.splashScreenState);
// this.addView(this.splashScreenView);
// this.transitionToFlutter();
// } else if (!flutterView.isAttachedToFlutterEngine()) {
// Log.v(TAG, "FlutterView is not yet attached to a FlutterEngine. Showing nothing until a FlutterEngine is attached.");
// flutterView.addFlutterEngineAttachmentListener(this.flutterEngineAttachmentListener);
// }
// }
} }
} }
/**
* Returns true if current conditions require a splash UI to be displayed.
* <p>
* This method does not evaluate whether a previously interrupted splash transition needs
* to resume. See {@link #isSplashScreenTransitionNeededNow()} to answer that question.
*/
private boolean isSplashScreenNeededNow() {
return flutterView != null
&& flutterView.isAttachedToFlutterEngine()
&& !flutterView.hasRenderedFirstFrame()
&& !hasSplashCompleted();
}
/**
* Returns true if a previous splash transition was interrupted by recreation, e.g., an
* orientation change, and that previous transition should be resumed.
* <p>
* Not all splash screens are capable of remembering their transition progress. In those
* cases, this method will return false even if a previous visual transition was
* interrupted.
*/
private boolean isSplashScreenTransitionNeededNow() {
return flutterView != null
&& flutterView.isAttachedToFlutterEngine()
&& splashScreen != null
&& splashScreen.doesSplashViewRememberItsTransition()
&& wasPreviousSplashTransitionInterrupted();
}
/**
* Returns true if a splash screen was transitioning to a Flutter experience and was then
* interrupted, e.g., by an Android configuration change. Returns false otherwise.
* <p>
* Invoking this method expects that a {@code flutterView} exists and it is attached to a
* {@code FlutterEngine}.
*/
private boolean wasPreviousSplashTransitionInterrupted() {
if (flutterView == null) {
throw new IllegalStateException("Cannot determine if previous splash transition was " +
"interrupted when no FlutterView is set.");
}
if (!flutterView.isAttachedToFlutterEngine()) {
throw new IllegalStateException("Cannot determine if previous splash transition was "
+ "interrupted when no FlutterEngine is attached to our FlutterView. This question "
+ "depends on an isolate ID to differentiate Flutter experiences.");
}
return flutterView.hasRenderedFirstFrame() && !hasSplashCompleted();
}
/** /**
* Returns true if a splash UI for a specific Flutter experience has already completed. * Returns true if a splash UI for a specific Flutter experience has already completed.
* <p> * <p>
...@@ -271,37 +196,6 @@ public class FlutterSplashView extends FrameLayout { ...@@ -271,37 +196,6 @@ public class FlutterSplashView extends FrameLayout {
splashScreen.transitionToFlutter(onTransitionComplete); splashScreen.transitionToFlutter(onTransitionComplete);
} }
public static class SavedState extends BaseSavedState {
public static Creator CREATOR = new Creator() {
public FlutterSplashView.SavedState createFromParcel(Parcel source) {
return new FlutterSplashView.SavedState(source);
}
public FlutterSplashView.SavedState[] newArray(int size) {
return new FlutterSplashView.SavedState[size];
}
};
private String previousCompletedSplashIsolate;
private Bundle splashScreenState;
SavedState(Parcelable superState) {
super(superState);
}
SavedState(Parcel source) {
super(source);
this.previousCompletedSplashIsolate = source.readString();
this.splashScreenState = source.readBundle(this.getClass().getClassLoader());
}
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeString(this.previousCompletedSplashIsolate);
out.writeBundle(this.splashScreenState);
}
}
@Override @Override
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
<activity <activity
android:name="com.idlefish.flutterboost.containers.NewBoostFlutterActivity" android:name="com.idlefish.flutterboost.containers.BoostFlutterActivity"
android:theme="@style/Theme.AppCompat" android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
......
...@@ -13,7 +13,7 @@ import android.view.View; ...@@ -13,7 +13,7 @@ import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.ImageView; import android.widget.ImageView;
import com.idlefish.flutterboost.containers.NewFlutterFragment; import com.idlefish.flutterboost.containers.FlutterFragment;
import io.flutter.embedding.android.DrawableSplashScreen; import io.flutter.embedding.android.DrawableSplashScreen;
import io.flutter.embedding.android.SplashScreen; import io.flutter.embedding.android.SplashScreen;
import io.flutter.embedding.android.SplashScreenProvider; import io.flutter.embedding.android.SplashScreenProvider;
...@@ -22,7 +22,7 @@ import io.flutter.plugin.platform.PlatformPlugin; ...@@ -22,7 +22,7 @@ import io.flutter.plugin.platform.PlatformPlugin;
public class FlutterFragmentPageActivity extends AppCompatActivity implements View.OnClickListener, SplashScreenProvider { public class FlutterFragmentPageActivity extends AppCompatActivity implements View.OnClickListener, SplashScreenProvider {
protected static final String SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable"; protected static final String SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable";
private NewFlutterFragment mFragment; private FlutterFragment mFragment;
private View mTab1; private View mTab1;
private View mTab2; private View mTab2;
...@@ -70,17 +70,17 @@ public class FlutterFragmentPageActivity extends AppCompatActivity implements Vi ...@@ -70,17 +70,17 @@ public class FlutterFragmentPageActivity extends AppCompatActivity implements Vi
if(mTab1 == v) { if(mTab1 == v) {
mTab1.setBackgroundColor(Color.YELLOW); mTab1.setBackgroundColor(Color.YELLOW);
mFragment= new NewFlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build(); mFragment= new FlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build();
}else if(mTab2 == v) { }else if(mTab2 == v) {
mTab2.setBackgroundColor(Color.YELLOW); mTab2.setBackgroundColor(Color.YELLOW);
mFragment= new NewFlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build(); mFragment= new FlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build();
}else if(mTab3 == v) { }else if(mTab3 == v) {
mTab3.setBackgroundColor(Color.YELLOW); mTab3.setBackgroundColor(Color.YELLOW);
mFragment= new NewFlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build(); mFragment= new FlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build();
}else{ }else{
mTab4.setBackgroundColor(Color.YELLOW); mTab4.setBackgroundColor(Color.YELLOW);
mFragment= new NewFlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build(); mFragment= new FlutterFragment.NewEngineFragmentBuilder().url("flutterFragment").build();
} }
getSupportFragmentManager() getSupportFragmentManager()
......
...@@ -11,6 +11,8 @@ import java.util.Map; ...@@ -11,6 +11,8 @@ import java.util.Map;
import com.idlefish.flutterboost.interfaces.INativeRouter; import com.idlefish.flutterboost.interfaces.INativeRouter;
import io.flutter.embedding.android.FlutterView; import io.flutter.embedding.android.FlutterView;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MyApplication extends Application { public class MyApplication extends Application {
...@@ -18,6 +20,7 @@ public class MyApplication extends Application { ...@@ -18,6 +20,7 @@ public class MyApplication extends Application {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
INativeRouter router =new INativeRouter() { INativeRouter router =new INativeRouter() {
@Override @Override
public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) { public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
...@@ -27,34 +30,24 @@ public class MyApplication extends Application { ...@@ -27,34 +30,24 @@ public class MyApplication extends Application {
}; };
NewFlutterBoost.BoostLifecycleListener lifecycleListener= new NewFlutterBoost.BoostLifecycleListener() { FlutterBoost.BoostPluginsRegister pluginsRegister= new FlutterBoost.BoostPluginsRegister(){
@Override
public void onEngineCreated() {
}
@Override
public void onPluginsRegistered() {
MethodChannel mMethodChannel = new MethodChannel( NewFlutterBoost.instance().engineProvider().getDartExecutor(), "methodChannel");
Log.e("MyApplication","MethodChannel create");
TextPlatformViewPlugin.register(NewFlutterBoost.instance().getPluginRegistry().registrarFor("TextPlatformViewPlugin"));
}
@Override @Override
public void onEngineDestroy() { public void registerPlugins(PluginRegistry mRegistry) {
GeneratedPluginRegistrant.registerWith(mRegistry);
TextPlatformViewPlugin.register(mRegistry.registrarFor("TextPlatformViewPlugin"));
} }
}; };
Platform platform= new NewFlutterBoost
Platform platform= new FlutterBoost
.ConfigBuilder(this,router) .ConfigBuilder(this,router)
.isDebug(true) .isDebug(true)
.whenEngineStart(NewFlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED) .whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
.renderMode(FlutterView.RenderMode.texture) .renderMode(FlutterView.RenderMode.texture)
.lifecycleListener(lifecycleListener) .pluginsRegister(pluginsRegister)
.build(); .build();
NewFlutterBoost.instance().init(platform); FlutterBoost.instance().init(platform);
......
package com.taobao.idlefish.flutterboostexample; package com.taobao.idlefish.flutterboostexample;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.idlefish.flutterboost.containers.NewBoostFlutterActivity; import com.idlefish.flutterboost.containers.BoostFlutterActivity;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -13,11 +13,9 @@ public class PageRouter { ...@@ -13,11 +13,9 @@ public class PageRouter {
public final static Map<String, String> pageName = new HashMap<String, String>() {{ public final static Map<String, String> pageName = new HashMap<String, String>() {{
put("first", "first"); put("first", "first");
put("second", "second"); put("second", "second");
put("tab", "tab"); put("tab", "tab");
put("sample://flutterPage", "flutterPage"); put("sample://flutterPage", "flutterPage");
}}; }};
...@@ -37,23 +35,27 @@ public class PageRouter { ...@@ -37,23 +35,27 @@ public class PageRouter {
try { try {
if (pageName.containsKey(path)) { if (pageName.containsKey(path)) {
Intent intent = NewBoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params) Intent intent = BoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params)
.backgroundMode(NewBoostFlutterActivity.BackgroundMode.opaque).build(context); .backgroundMode(BoostFlutterActivity.BackgroundMode.opaque).build(context);
if(context instanceof Activity){
context.startActivity(intent); Activity activity=(Activity)context;
activity.startActivityForResult(intent,requestCode);
}else{
context.startActivity(intent);
}
return true;
} else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) { } else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) {
context.startActivity(new Intent(context, FlutterFragmentPageActivity.class)); context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
return true; return true;
} else if (url.startsWith(NATIVE_PAGE_URL)) { } else if (url.startsWith(NATIVE_PAGE_URL)) {
context.startActivity(new Intent(context, NativePageActivity.class)); context.startActivity(new Intent(context, NativePageActivity.class));
return true; return true;
} else {
return false;
} }
return false;
} catch (Throwable t) { } catch (Throwable t) {
return false; return false;
} }
return false;
} }
} }
...@@ -56,8 +56,11 @@ ...@@ -56,8 +56,11 @@
if(!_existedID[vc.uniqueIDString]){ if(!_existedID[vc.uniqueIDString]){
[_idStk addObject:vc.uniqueIDString]; [_idStk addObject:vc.uniqueIDString];
} }
_existedID[vc.uniqueIDString] = vc.uniqueIDString; _existedID[vc.uniqueIDString] = vc.name;
} }
#if DEBUG
[self dump:@"ADD"];
#endif
} }
- (void)remove:(id<FLBFlutterContainer>)vc - (void)remove:(id<FLBFlutterContainer>)vc
...@@ -66,6 +69,9 @@ ...@@ -66,6 +69,9 @@
[_existedID removeObjectForKey:vc.uniqueIDString]; [_existedID removeObjectForKey:vc.uniqueIDString];
[_idStk removeObject:vc.uniqueIDString]; [_idStk removeObject:vc.uniqueIDString];
} }
#if DEBUG
[self dump:@"REMOVE"];
#endif
} }
- (NSString *)peak - (NSString *)peak
...@@ -73,4 +79,13 @@ ...@@ -73,4 +79,13 @@
return _idStk.lastObject; return _idStk.lastObject;
} }
#if DEBUG
- (void)dump:(NSString*)flag{
NSMutableString *log = [[NSMutableString alloc]initWithFormat:@"[DEBUG]--%@--PageStack uid/name", flag];
for(NSString *uid in _idStk){
[log appendFormat:@"-->%@/%@",uid, _existedID[uid]];
}
NSLog(@"%@\n", log);
}
#endif
@end @end
...@@ -111,26 +111,16 @@ ...@@ -111,26 +111,16 @@
return _instance; return _instance;
} }
- (id<FLBFlutterApplicationInterface>)application
{
return _application;
}
- (id<FLBAbstractFactory>)factory
{
return _factory;
}
- (void)startFlutterWithPlatform:(id<FLBPlatform>)platform - (void)startFlutterWithPlatform:(id<FLBPlatform>)platform
onStart:(void (^)(FlutterEngine *engine))callback; onStart:(void (^)(FlutterEngine *engine))callback;
{ {
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
__weak __typeof__(self) weakSelf = self;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
self->_factory = FLBFactory.new; __strong __typeof__(weakSelf) self = weakSelf;
self->_application = [self->_factory createApplication:platform]; self.factory = FLBFactory.new;
[self->_application startFlutterWithPlatform:platform self.application = [self->_factory createApplication:platform];
[self.application startFlutterWithPlatform:platform
onStart:callback]; onStart:callback];
}); });
} }
......
...@@ -26,14 +26,11 @@ ...@@ -26,14 +26,11 @@
#import "FLBFlutterApplicationInterface.h" #import "FLBFlutterApplicationInterface.h"
#import "FLBAbstractFactory.h" #import "FLBAbstractFactory.h"
#import "FlutterBoostPlugin.h" #import "FlutterBoostPlugin.h"
@interface FlutterBoostPlugin(){ @interface FlutterBoostPlugin()
id<FLBFlutterApplicationInterface> _application; @property (nonatomic,strong) id<FLBFlutterApplicationInterface> application;
id<FLBAbstractFactory> _factory; @property (nonatomic,strong) id<FLBAbstractFactory> factory;
}
@property (nonatomic,strong) FlutterMethodChannel *methodChannel; @property (nonatomic,strong) FlutterMethodChannel *methodChannel;
@property (nonatomic,copy) NSString *fPageId; @property (nonatomic,copy) NSString *fPageId;
@property (nonatomic,copy) NSString *fPagename; @property (nonatomic,copy) NSString *fPagename;
@property (nonatomic,strong) NSDictionary *fParams; @property (nonatomic,strong) NSDictionary *fParams;
- (id<FLBFlutterApplicationInterface>)application;
- (id<FLBAbstractFactory>)factory;
@end @end
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
- (id<FLBFlutterApplicationInterface>)createApplication:(id<FLBPlatform>)platform - (id<FLBFlutterApplicationInterface>)createApplication:(id<FLBPlatform>)platform
{ {
return [FLBFlutterApplication sharedApplication]; return [FLBFlutterApplication new];
} }
- (id<FLBFlutterContainer>)createFlutterContainer - (id<FLBFlutterContainer>)createFlutterContainer
......
...@@ -30,6 +30,5 @@ ...@@ -30,6 +30,5 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterApplication : NSObject<FLBFlutterApplicationInterface> @interface FLBFlutterApplication : NSObject<FLBFlutterApplicationInterface>
+ (FLBFlutterApplication *)sharedApplication;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -39,16 +39,6 @@ ...@@ -39,16 +39,6 @@
@implementation FLBFlutterApplication @implementation FLBFlutterApplication
@synthesize platform; @synthesize platform;
+ (FLBFlutterApplication *)sharedApplication
{
static FLBFlutterApplication *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [self new];
});
return instance;
}
- (BOOL)isRunning - (BOOL)isRunning
{ {
return _isRunning; return _isRunning;
......
...@@ -91,14 +91,14 @@ ...@@ -91,14 +91,14 @@
- (void)didEnterBackground - (void)didEnterBackground
{ {
[BoostMessageChannel sendEvent:@"background" [BoostMessageChannel sendEvent:@"lifecycle"
arguments:nil]; arguments:@{@"type":@"background"}];
} }
- (void)willEnterForeground - (void)willEnterForeground
{ {
[BoostMessageChannel sendEvent:@"foreground" [BoostMessageChannel sendEvent:@"lifecycle"
arguments:nil]; arguments:@{@"type":@"foreground"}];
} }
- (FlutterEngine *)engine - (FlutterEngine *)engine
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterViewContainer : FlutterViewController<FLBFlutterContainer> @interface FLBFlutterViewContainer : FlutterViewController<FLBFlutterContainer>
@property (nonatomic,copy,readwrite) NSString *name; @property (nonatomic,copy,readwrite) NSString *name;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (void)surfaceUpdated:(BOOL)appeared; - (void)surfaceUpdated:(BOOL)appeared;
- (void)setEnableForRunnersBatch:(BOOL)enable; - (void)setEnableForRunnersBatch:(BOOL)enable;
@end @end
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
@interface FLBFlutterViewContainer () @interface FLBFlutterViewContainer ()
@property (nonatomic,strong,readwrite) NSDictionary *params; @property (nonatomic,strong,readwrite) NSDictionary *params;
@property (nonatomic,assign) long long identifier; @property (nonatomic,assign) long long identifier;
@property (nonatomic, copy) NSString *flbNibName;
@property (nonatomic, strong) NSBundle *flbNibBundle;
@end @end
#pragma clang diagnostic push #pragma clang diagnostic push
...@@ -47,13 +49,15 @@ ...@@ -47,13 +49,15 @@
{ {
[FLUTTER_APP.flutterProvider prepareEngineIfNeeded]; [FLUTTER_APP.flutterProvider prepareEngineIfNeeded];
if(self = [super initWithEngine:FLUTTER_APP.flutterProvider.engine if(self = [super initWithEngine:FLUTTER_APP.flutterProvider.engine
nibName:nil nibName:_flbNibName
bundle:nil]){ bundle:_flbNibBundle]){
[self _setup]; [self _setup];
} }
return self; return self;
} }
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
- (instancetype)initWithCoder:(NSCoder *)aDecoder{ - (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder: aDecoder]) { if (self = [super initWithCoder: aDecoder]) {
NSAssert(NO, @"unsupported init method!"); NSAssert(NO, @"unsupported init method!");
...@@ -61,6 +65,13 @@ ...@@ -61,6 +65,13 @@
} }
return self; return self;
} }
#pragma pop
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
_flbNibName = nibNameOrNil;
_flbNibBundle = nibBundleOrNil;
return [self init];
}
- (void)setName:(NSString *)name params:(NSDictionary *)params - (void)setName:(NSString *)name params:(NSDictionary *)params
{ {
......
...@@ -39,7 +39,7 @@ class BoostPageRoute<T> extends MaterialPageRoute<T> { ...@@ -39,7 +39,7 @@ class BoostPageRoute<T> extends MaterialPageRoute<T> {
@override @override
Widget buildTransitions(BuildContext context, Animation<double> animation, Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) { Animation<double> secondaryAnimation, Widget child) {
return child; return super.buildTransitions(context, animation, secondaryAnimation, child);
} }
BoostPageRoute( BoostPageRoute(
......
...@@ -206,6 +206,18 @@ class ContainerCoordinator { ...@@ -206,6 +206,18 @@ class ContainerCoordinator {
?.pushContainer(_createContainerSettings(name, params, pageId)); ?.pushContainer(_createContainerSettings(name, params, pageId));
} }
//TODO, 需要验证android代码是否也可以移到这里
if (Platform.isIOS) {
try {
final SemanticsOwner owner =
WidgetsBinding.instance.pipelineOwner?.semanticsOwner;
final SemanticsNode root = owner?.rootSemanticsNode;
root?.detach();
root?.attach(owner);
} catch (e) {
assert(false, e.toString());
}
}
return true; return true;
} }
...@@ -254,9 +266,14 @@ class ContainerCoordinator { ...@@ -254,9 +266,14 @@ class ContainerCoordinator {
} }
bool _nativeContainerWillDealloc(String name, Map params, String pageId) { bool _nativeContainerWillDealloc(String name, Map params, String pageId) {
performContainerLifeCycle(_createContainerSettings(name, params, pageId), try{
ContainerLifeCycle.Destroy);
performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Destroy);
} catch (e){
Logger.log(
'nativeContainerWillDealloc error: ${e}' );
}
FlutterBoost.containerManager?.remove(pageId); FlutterBoost.containerManager?.remove(pageId);
Logger.log( Logger.log(
......
name: flutter_boost name: flutter_boost
description: A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts. description: A next-generation Flutter-Native hybrid solution. FlutterBoost is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.
version: 0.1.54 version: 0.1.61
author: Alibaba Xianyu author: Alibaba Xianyu
homepage: https://github.com/alibaba/flutter_boost homepage: https://github.com/alibaba/flutter_boost
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment