Commit 77ef993a authored by Jidong Chen's avatar Jidong Chen

init

parents
## 0.0.1
* TODO: Describe initial release.
The MIT License (MIT)
Copyright (c) 2019 Alibaba Group
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<p align="center">
<img src="flutter_boost.png">
<b></b><br>
<a href="README_CN.md">中文文档</a>
<br><br>
</p>
# 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 name="bf647454"></a>
# Prerequisites
You need to add Flutter to your project before moving on.
# Getting Started
## Add a dependency in you Flutter project.
Open you pubspec.yaml and add the following line to dependencies:
Before release 1.0
```java
flutter_boost: 0.0.34
```
After Release 1.0
```java
flutter_boost: ^0.0.39
```
## 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();
///register page widget builders,the key is pageName
FlutterBoost.singleton.registerPageBuilders({
'sample://firstPage': (pageName, params, _) => FirstRouteWidget(),
'sample://secondPage': (pageName, params, _) => SecondRouteWidget(),
});
///query current top page and load it
FlutterBoost.handleOnStartPage();
}
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Flutter Boost example',
builder: FlutterBoost.init(), ///init container manager
home: Container());
}
```
## Integration with iOS code.
Use FLBFlutterAppDelegate as the superclass of your AppDelegate
```objc
@interface AppDelegate : FLBFlutterAppDelegate <UIApplicationDelegate>
@end
```
Implement FLBPlatform protocol methods for your App.
```objc
@interface DemoRouter : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
+ (DemoRouter *)sharedRouter;
@end
@implementation DemoRouter
- (void)openPage:(NSString *)name
params:(NSDictionary *)params
animated:(BOOL)animated
completion:(void (^)(BOOL))completion
{
if([params[@"present"] boolValue]){
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
}else{
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
}
}
- (void)closePage:(NSString *)uid animated:(BOOL)animated params:(NSDictionary *)params completion:(void (^)(BOOL))completion
{
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.
```objc
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterViewController *fvc) {
}];
```
## Integration with Android code.
Init FlutterBoost in Application.onCreate() 
```java
public class MyApplication extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
FlutterBoostPlugin.init(new IPlatform() {
@Override
public Application getApplication() {
return MyApplication.this;
}
/**
* get the main activity, this activity should always at the bottom of task stack.
*/
@Override
public Activity getMainActivity() {
return MainActivity.sRef.get();
}
@Override
public boolean isDebug() {
return false;
}
/**
* start a new activity from flutter page, you may need a activity router.
*/
@Override
public boolean startActivity(Context context, String url, int requestCode) {
return PageRouter.openPageByUrl(context,url,requestCode);
}
@Override
public Map getSettings() {
return null;
}
});
}
```
# 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
```objc
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
```
Android
```java
public class FlutterPageActivity extends BoostFlutterActivity {
@Override
public void onRegisterPlugins(PluginRegistry registry) {
//register flutter plugins
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
//specify the page name register in FlutterBoost
return "sample://firstPage";
}
@Override
public Map getContainerParams() {
//params of the page
Map<String,String> params = new HashMap<>();
params.put("key","value");
return params;
}
}
```
or
```java
public class FlutterFragment extends BoostFlutterFragment {
@Override
public void onRegisterPlugins(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
return "sample://firstPage";
}
@Override
public Map getContainerParams() {
Map<String,String> params = new HashMap<>();
params.put("key","value");
return params;
}
}
```
## Use Flutter Boost to open a page in dart code.
Dart
```objc
FlutterBoost.singleton.openPage("pagename", {}, true);
```
## Use Flutter Boost to close a page in dart code.
```objc
FlutterBoost.singleton.closePageForContext(context);
```
# Running the Demo
Please see the example for details.
# License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details
# Acknowledgments
* Flutter
<p align="center">
<img src="flutter_boost.png">
</p>
# FlutterBoost
新一代Flutter-Native混合解决方案。 FlutterBoost是一个Flutter插件,它可以轻松地为现有原生应用程序提供Flutter混合集成方案。FlutterBoost的理念是将Flutter像Webview那样来使用。在现有应用程序中同时管理Native页面和Flutter页面并非易事。 FlutterBoost帮你处理页面的映射和跳转,你只需关心页面的名字和参数即可(通常可以是URL)。
# 前置条件
在继续之前,您需要将Flutter集成到你现有的项目中。
# 安装
## 在Flutter项目中添加依赖项。
打开pubspec.yaml并将以下行添加到依赖项:
Release 1.0 之前的版本
```JSON
flutter_boost:0.0.34
```
1.0之后版本
```
flutter_boost:^ 0.0.39
```
## 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();
///register page widget builders,the key is pageName
FlutterBoost.singleton.registerPageBuilders({
'sample://firstPage': (pageName, params, _) => FirstRouteWidget(),
'sample://secondPage': (pageName, params, _) => SecondRouteWidget(),
});
///query current top page and load it
FlutterBoost.handleOnStartPage();
}
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Flutter Boost example',
builder: FlutterBoost.init(), ///init container manager
home: Container());
}
```
## iOS代码集成。
使用FLBFlutterAppDelegate作为AppDelegate的超类
```objectivec
@interface AppDelegate : FLBFlutterAppDelegate <UIApplicationDelegate>
@end
```
为您的应用程序实现FLBPlatform协议方法。
```objectivec
@interface DemoRouter : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
+ (DemoRouter *)sharedRouter;
@end
@implementation DemoRouter
- (void)openPage:(NSString *)name
params:(NSDictionary *)params
animated:(BOOL)animated
completion:(void (^)(BOOL))completion
{
if([params[@"present"] boolValue]){
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
}else{
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
}
}
- (void)closePage:(NSString *)uid animated:(BOOL)animated params:(NSDictionary *)params completion:(void (^)(BOOL))completion
{
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。
```的ObjectiveC
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterViewController * fvc){
}];
```
## Android代码集成。
在Application.onCreate()中初始化FlutterBoost
```java
public class MyApplication extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
FlutterBoostPlugin.init(new IPlatform() {
@Override
public Application getApplication() {
return MyApplication.this;
}
/**
* get the main activity, this activity should always at the bottom of task stack.
*/
@Override
public Activity getMainActivity() {
return MainActivity.sRef.get();
}
@Override
public boolean isDebug() {
return false;
}
/**
* start a new activity from flutter page, you may need a activity router.
*/
@Override
public boolean startActivity(Context context, String url, int requestCode) {
return PageRouter.openPageByUrl(context,url,requestCode);
}
@Override
public Map getSettings() {
return null;
}
});
}
```
# 基本用法
## 概念
所有页面路由请求都将发送到Native路由器。Native路由器与Native Container Manager通信,Native Container Manager负责构建和销毁Native Containers。
## 使用Flutter Boost Native Container用Native代码打开Flutter页面。
```objc
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
```
Android
```java
public class FlutterPageActivity extends BoostFlutterActivity {
@Override
public void onRegisterPlugins(PluginRegistry registry) {
//register flutter plugins
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
//specify the page name register in FlutterBoost
return "sample://firstPage";
}
@Override
public Map getContainerParams() {
//params of the page
Map<String,String> params = new HashMap<>();
params.put("key","value");
return params;
}
}
```
或者用Fragment
```java
public class FlutterFragment extends BoostFlutterFragment {
@Override
public void onRegisterPlugins(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
return "sample://firstPage";
}
@Override
public Map getContainerParams() {
Map<String,String> params = new HashMap<>();
params.put("key","value");
return params;
}
}
```
## 使用Flutter Boost在dart代码打开页面。
Dart
```java
FlutterBoost.singleton.openPage("pagename", {}, true);
```
## 使用Flutter Boost在dart代码关闭页面。
```java
FlutterBoost.singleton.closePageForContext(context);
```
# Examples
更详细的使用例子请参考Demo
# 作者
阿里巴巴闲鱼终端团队
# 许可证
该项目根据MIT许可证授权 - 有关详细信息,请参阅[LICENSE.md](LICENSE.md)文件
<a name="Acknowledgments"> </a>
# 致谢
- Flutter
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.idea
.DS_Store
/build
/captures
GitCommitRecord.txt
group 'com.taobao.idlefish.flutterboost'
version '1.0-SNAPSHOT'
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
minSdkVersion 16
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
lintOptions {
disable 'InvalidPackage'
}
}
dependencies {
implementation 'com.alibaba:fastjson:1.2.41'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:appcompat-v7:26.1.0'
provided rootProject.findProject(":xservice_kit")
}
ext {
groupId = 'com.taobao.fleamarket'
artifactId = "FlutterBoost"
}
org.gradle.jvmargs=-Xmx1536M
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
rootProject.name = 'flutter_boost'
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.taobao.idlefish.flutterboost">
<application
android:allowBackup="false">
<activity
android:name="com.taobao.idlefish.flutterboost.BoostFlutterActivity"
android:launchMode="standard"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"/>
</application>
</manifest>
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import android.content.Context;
import io.flutter.view.FlutterNativeView;
public class BoostFlutterNativeView extends FlutterNativeView {
public BoostFlutterNativeView(Context context) {
super(context);
}
@Override
public void detach() {
//do nothing...
}
@Override
public void destroy() {
//do nothing...
}
public void boostDestroy() {
super.destroy();
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.View;
import com.taobao.idlefish.flutterboost.NavigationService.NavigationService;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import io.flutter.view.FlutterNativeView;
import io.flutter.view.FlutterView;
public class BoostFlutterView extends FlutterView {
private boolean mFirstFrameCalled = false;
private boolean mResumed = false;
private BoostCallback mBoostCallback;
public BoostFlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
super(context, attrs, nativeView);
super.addFirstFrameListener(new FirstFrameListener() {
@Override
public void onFirstFrame() {
mFirstFrameCalled = true;
}
});
try {
Field field = FlutterView.class.getDeclaredField("mSurfaceCallback");
field.setAccessible(true);
SurfaceHolder.Callback cb = (SurfaceHolder.Callback)field.get(this);
getHolder().removeCallback(cb);
mBoostCallback = new BoostCallback(cb);
getHolder().addCallback(mBoostCallback);
}catch (Throwable t){
Debuger.exception(t);
}
}
@Override
public void onStart() {
//do nothing...
}
@Override
public void onPostResume() {
//do nothing...
}
@Override
public void onPause() {
//do nothing...
}
@Override
public void onStop() {
//do nothing...
}
@Override
public FlutterNativeView detach() {
//do nothing...
return getFlutterNativeView();
}
@Override
public void destroy() {
//do nothing...
}
@Override
public Bitmap getBitmap() {
if(getFlutterNativeView() == null || !getFlutterNativeView().isAttached()) {
Debuger.exception("FlutterView not attached!");
return null;
}
return super.getBitmap();
}
public boolean firstFrameCalled() {
return mFirstFrameCalled;
}
public void boostResume() {
if (!mResumed) {
mResumed = true;
super.onPostResume();
Debuger.log("resume flutter view");
}
}
public void boostStop() {
if (mResumed) {
super.onStop();
Debuger.log("stop flutter view");
mResumed = false;
}
}
public boolean isResumed() {
return mResumed;
}
public void boostDestroy() {
super.destroy();
}
public void scheduleFrame(){
if (mResumed) {
Map<String,String> map = new HashMap<>();
map.put("type","scheduleFrame");
NavigationService.getService().emitEvent(map);
}
}
class BoostCallback implements SurfaceHolder.Callback {
final SurfaceHolder.Callback mCallback;
BoostCallback(SurfaceHolder.Callback cb){
this.mCallback = cb;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//Debuger.log("flutterView surfaceCreated");
try {
mCallback.surfaceCreated(holder);
}catch (Throwable t){
Debuger.exception(t);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//Debuger.log("flutterView surfaceChanged");
try {
mCallback.surfaceChanged(holder,format,width,height);
scheduleFrame();
}catch (Throwable t){
Debuger.exception(t);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//Debuger.log("flutterView surfaceDestroyed");
try {
mCallback.surfaceDestroyed(holder);
}catch (Throwable t){
Debuger.exception(t);
}
}
}
@Override
protected void onAttachedToWindow() {
//Debuger.log("flutterView onAttachedToWindow");
super.onAttachedToWindow();
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import com.taobao.idlefish.flutterboost.NavigationService.NavigationService;
import com.taobao.idlefish.flutterboost.interfaces.IContainerManager;
import com.taobao.idlefish.flutterboost.interfaces.IContainerRecord;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import java.util.Map;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
public class ContainerRecord implements IContainerRecord {
private final IContainerManager mManager;
private final IFlutterViewContainer mContainer;
private final String mUniqueId;
private int mState = STATE_UNKNOW;
private MethodChannelProxy mProxy = new MethodChannelProxy();
public ContainerRecord(IContainerManager manager, IFlutterViewContainer container) {
mUniqueId = System.currentTimeMillis() + "-" + hashCode();
mManager = manager;
mContainer = container;
}
@Override
public String uniqueId() {
return mUniqueId;
}
@Override
public IFlutterViewContainer getContainer() {
return mContainer;
}
@Override
public int getState() {
return mState;
}
@Override
public void onCreate() {
mState = STATE_CREATED;
mContainer.getBoostFlutterView().boostResume();
mProxy.create();
}
@Override
public void onAppear() {
mState = STATE_APPEAR;
mContainer.getBoostFlutterView().boostResume();
mProxy.appear();
}
@Override
public void onDisappear() {
mProxy.disappear();
mState = STATE_DISAPPEAR;
}
@Override
public void onDestroy() {
mProxy.destroy();
mState = STATE_DESTROYED;
}
@Override
public void onResult(Map Result) {
NavigationService.onNativePageResult(
genResult("onNativePageResult"),
mUniqueId,
mUniqueId,
Result,
mContainer.getContainerParams()
);
}
private class MethodChannelProxy {
private int mState = STATE_UNKNOW;
private void create() {
if (mState == STATE_UNKNOW) {
NavigationService.didInitPageContainer(
genResult("didInitPageContainer"),
mContainer.getContainerName(),
mContainer.getContainerParams(),
mUniqueId
);
//Debuger.log("didInitPageContainer");
mState = STATE_CREATED;
}
}
private void appear() {
NavigationService.didShowPageContainer(
genResult("didShowPageContainer"),
mContainer.getContainerName(),
mContainer.getContainerParams(),
mUniqueId
);
//Debuger.log("didShowPageContainer");
mState = STATE_APPEAR;
}
private void disappear() {
if (mState < STATE_DISAPPEAR) {
NavigationService.didDisappearPageContainer(
genResult("didDisappearPageContainer"),
mContainer.getContainerName(),
mContainer.getContainerParams(),
mUniqueId
);
//Debuger.log("didDisappearPageContainer");
mState = STATE_DISAPPEAR;
}
}
private void destroy() {
if (mState < STATE_DESTROYED) {
NavigationService.willDeallocPageContainer(
genResult("willDeallocPageContainer"),
mContainer.getContainerName(),
mContainer.getContainerParams(),
mUniqueId
);
//Debuger.log("willDeallocPageContainer");
mState = STATE_DESTROYED;
}
}
}
private MessageResult<Boolean> genResult(final String name) {
return new MessageResult<Boolean>() {
@Override
public void success(Boolean var1) {
//Debuger.log(name + " call success");
}
@Override
public void error(String var1, String var2, Object var3) {
Debuger.log(name + " call error");
}
@Override
public void notImplemented() {
Debuger.log(name + " call not Impelemented");
}
};
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import android.util.Log;
public class Debuger {
private static final String TAG = "FlutterBoost#";
private static final Debuger DEBUG = new Debuger();
private Debuger(){ }
private void print(String info) {
if(isDebug()) {
Log.e(TAG, info);
}
}
public static void log(String info) {
DEBUG.print(info);
}
public static void exception(String message) {
if(isDebug()) {
throw new RuntimeException(message);
}else{
Log.e(TAG,"exception",new RuntimeException(message));
}
}
public static void exception(Throwable t) {
if(isDebug()) {
throw new RuntimeException(t);
}else{
Log.e(TAG,"exception",t);
}
}
public static boolean isDebug(){
try {
return FlutterBoostPlugin.platform().isDebug();
}catch (Throwable t){
return false;
}
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import com.alibaba.fastjson.JSON;
import com.taobao.idlefish.flutterboost.NavigationService.NavigationService;
import com.taobao.idlefish.flutterboost.interfaces.IContainerRecord;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import com.taobao.idlefish.flutterboost.loader.ServiceLoader;
import com.taobao.idlefish.flutterboost.interfaces.IContainerManager;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewProvider;
import com.taobao.idlefish.flutterboost.interfaces.IPlatform;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
public class FlutterBoostPlugin implements MethodChannel.MethodCallHandler, Application.ActivityLifecycleCallbacks {
private static FlutterBoostPlugin sInstance = null;
public static synchronized void init(IPlatform platform) {
if (sInstance == null) {
sInstance = new FlutterBoostPlugin(platform);
platform.getApplication().registerActivityLifecycleCallbacks(sInstance);
ServiceLoader.load();
}
}
public static void registerWith(PluginRegistry.Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_boost");
channel.setMethodCallHandler(sInstance);
}
public static IFlutterViewProvider viewProvider() {
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet");
}
return sInstance.mViewProvider;
}
public static IContainerManager containerManager() {
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet");
}
return sInstance.mManager;
}
public static IPlatform platform() {
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet");
}
return sInstance.mPlatform;
}
public static Activity currentActivity() {
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet");
}
return sInstance.mCurrentActiveActivity;
}
private final IPlatform mPlatform;
private final IContainerManager mManager;
private final IFlutterViewProvider mViewProvider;
private final PageResultMediator mMediator;
private Activity mCurrentActiveActivity;
private FlutterBoostPlugin(IPlatform platform) {
mPlatform = platform;
mViewProvider = new FlutterViewProvider(platform);
mManager = new FlutterViewContainerManager();
mMediator = new PageResultMediator();
}
public IFlutterViewContainer findContainerById(String id){
return mManager.findContainerById(id);
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}
public static void openPage(Context context, String url, final Map params, int requestCode) {
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet!");
}
Context ctx = context;
if (ctx == null) {
ctx = currentActivity();
}
if (ctx == null) {
ctx = sInstance.mPlatform.getMainActivity();
}
if (ctx == null) {
ctx = sInstance.mPlatform.getApplication();
}
//Handling page result.
if (sInstance.needResult(params)){
sInstance.mMediator.setHandler(url, new PageResultHandler() {
@Override
public void onResult(String key, Map resultData) {
NavigationService.onNativePageResult(new MessageResult<Boolean>() {
@Override
public void success(Boolean var1) {
//Doing nothing now.
}
@Override
public void error(String var1, String var2, Object var3) {
//Doing nothing now.
}
@Override
public void notImplemented() {
//Doing nothing now.
}
},"no use",key,resultData,params);
}
});
}
sInstance.mPlatform.startActivity(ctx, concatUrl(url, params), requestCode);
}
private Boolean needResult(Map params){
if(params == null) return false;
final String key = "needResult";
if(params.containsKey(key)){
if(params.get(key) instanceof Boolean){
return (Boolean) params.get(key);
}
}
return false;
}
public static void onPageResult(String key , Map resultData){
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet!");
}
sInstance.mMediator.onPageResult(key,resultData);
}
public static void setHandler(String key, PageResultHandler handler){
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet!");
}
sInstance.mMediator.setHandler(key,handler);
}
public static void removeHandler(String key){
if (sInstance == null) {
throw new RuntimeException("FlutterBoostPlugin not init yet!");
}
sInstance.mMediator.removeHandler(key);
}
private static String concatUrl(String url, Map params) {
if (params == null || params.isEmpty()) return url;
Uri uri = Uri.parse(url);
Uri.Builder builder = uri.buildUpon();
for (Object key : params.keySet()) {
Object value = params.get(key);
if (value != null) {
String str;
if (value instanceof Map || value instanceof List) {
try {
str = URLEncoder.encode(JSON.toJSONString(value), "utf-8");
} catch (UnsupportedEncodingException e) {
str = value.toString();
}
} else {
str = value.toString();
}
builder.appendQueryParameter(String.valueOf(key), str);
}
}
return builder.build().toString();
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
if (mCurrentActiveActivity == null) {
Debuger.log("Application entry foreground");
Map<String, String> map = new HashMap<>();
map.put("type", "foreground");
NavigationService.getService().emitEvent(map);
}
mCurrentActiveActivity = activity;
}
@Override
public void onActivityResumed(Activity activity) {
mCurrentActiveActivity = activity;
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
if (mCurrentActiveActivity == activity) {
Debuger.log("Application entry background");
Map<String, String> map = new HashMap<>();
map.put("type", "background");
NavigationService.getService().emitEvent(map);
mCurrentActiveActivity = null;
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
if (mCurrentActiveActivity == activity) {
Debuger.log("Application entry background");
Map<String, String> map = new HashMap<>();
map.put("type", "background");
NavigationService.getService().emitEvent(map);
mCurrentActiveActivity = null;
}
}
public static void setBoostResult(Activity activity, HashMap result){
Intent intent = new Intent();
if(result != null) {
intent.putExtra(IFlutterViewContainer.RESULT_KEY, result);
}
activity.setResult(Activity.RESULT_OK,intent);
}
public static void onBoostResult(IFlutterViewContainer container, int requestCode,int resultCode,Intent intent){
Map map = new HashMap();
if(intent != null) {
map.put("result",intent.getSerializableExtra(IFlutterViewContainer.RESULT_KEY));
}
map.put("requestCode",requestCode);
map.put("responseCode",resultCode);
containerManager().onContainerResult(container,map);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import android.app.Activity;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import com.taobao.idlefish.flutterboost.NavigationService.NavigationService;
import com.taobao.idlefish.flutterboost.interfaces.IContainerManager;
import com.taobao.idlefish.flutterboost.interfaces.IContainerRecord;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterRunArguments;
public class FlutterViewContainerManager implements IContainerManager {
private final Map<IFlutterViewContainer, IContainerRecord> mRecords = new LinkedHashMap<>();
private final Instrument mInstrument;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Set<ContainerRef> mRefs = new HashSet<>();
private IContainerRecord mCurrentTopRecord;
FlutterViewContainerManager() {
mInstrument = new Instrument(this);
}
@Override
public PluginRegistry onContainerCreate(IFlutterViewContainer container) {
assertCallOnMainThread();
ContainerRecord record = new ContainerRecord(this, container);
if (mRecords.put(container, record) != null) {
Debuger.exception("container:" + container.getContainerName() + " already exists!");
return new PluginRegistryImpl(container.getActivity(), container.getBoostFlutterView());
}
mRefs.add(new ContainerRef(record.uniqueId(),container));
FlutterMain.ensureInitializationComplete(container.getActivity().getApplicationContext(), null);
BoostFlutterView flutterView = FlutterBoostPlugin.viewProvider().createFlutterView(container);
if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
String appBundlePath = FlutterMain.findAppBundlePath(container.getActivity().getApplicationContext());
if (appBundlePath != null) {
FlutterRunArguments arguments = new FlutterRunArguments();
arguments.bundlePath = appBundlePath;
arguments.entrypoint = "main";
flutterView.runFromBundle(arguments);
}
}
mInstrument.performCreate(record);
return new PluginRegistryImpl(container.getActivity(), container.getBoostFlutterView());
}
@Override
public void onContainerAppear(IFlutterViewContainer container) {
assertCallOnMainThread();
final IContainerRecord record = mRecords.get(container);
if (record == null) {
Debuger.exception("container:" + container.getContainerName() + " not exists yet!");
return;
}
mInstrument.performAppear(record);
mCurrentTopRecord = record;
}
@Override
public void onContainerDisappear(IFlutterViewContainer container) {
assertCallOnMainThread();
final IContainerRecord record = mRecords.get(container);
if (record == null) {
Debuger.exception("container:" + container.getContainerName() + " not exists yet!");
return;
}
mInstrument.performDisappear(record);
if (!container.isFinishing()) {
checkIfFlutterViewNeedStopLater();
}
}
@Override
public void onContainerDestroy(IFlutterViewContainer container) {
assertCallOnMainThread();
if (mCurrentTopRecord != null
&& mCurrentTopRecord.getContainer() == container) {
mCurrentTopRecord = null;
}
final IContainerRecord record = mRecords.remove(container);
if (record == null) {
Debuger.exception("container:" + container.getContainerName() + " not exists yet!");
return;
}
mInstrument.performDestroy(record);
checkIfFlutterViewNeedStopLater();
}
private void checkIfFlutterViewNeedStopLater() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (!hasContainerAppear()) {
FlutterBoostPlugin.viewProvider().stopFlutterView();
}
}
}, 250);
}
@Override
public void onBackPressed(IFlutterViewContainer container) {
assertCallOnMainThread();
final IContainerRecord record = mRecords.get(container);
if (record == null) {
Debuger.exception("container:" + container.getContainerName() + " not exists yet!");
return;
}
Map<String, String> map = new HashMap<>();
map.put("type", "backPressedCallback");
map.put("name", container.getContainerName());
map.put("uniqueId", record.uniqueId());
NavigationService.getService().emitEvent(map);
}
@Override
public void destroyContainerRecord(String name, String uniqueId) {
assertCallOnMainThread();
boolean done = false;
for (Map.Entry<IFlutterViewContainer, IContainerRecord> entry : mRecords.entrySet()) {
if (TextUtils.equals(uniqueId, entry.getValue().uniqueId())) {
entry.getKey().destroyContainer();
done = true;
break;
}
}
if (!done) {
Debuger.exception("destroyContainerRecord can not find name:" + name + " uniqueId:" + uniqueId);
}
}
@Override
public void onContainerResult(IFlutterViewContainer container, Map result) {
final IContainerRecord record = mRecords.get(container);
if (record == null) {
Debuger.exception("container:" + container.getContainerName() + " not exists yet!");
return;
}
record.onResult(result);
}
@Override
public void setContainerResult(String uniqueId, Map result) {
if (result == null) {
Debuger.exception("setContainerResult result is null");
return;
}
if (!(result instanceof HashMap)) {
result = new HashMap();
result.putAll(result);
}
boolean done = false;
for (Map.Entry<IFlutterViewContainer, IContainerRecord> entry : mRecords.entrySet()) {
if (TextUtils.equals(uniqueId, entry.getValue().uniqueId())) {
entry.getKey().setBoostResult((HashMap) result);
done = true;
break;
}
}
if (!done) {
Debuger.exception("setContainerResult can not find uniqueId:" + uniqueId);
}
}
@Override
public IContainerRecord getCurrentTopRecord() {
return mCurrentTopRecord;
}
@Override
public IContainerRecord getLastRecord() {
final Collection<IContainerRecord> values = mRecords.values();
if(!values.isEmpty()) {
final ArrayList<IContainerRecord> array = new ArrayList<>(values);
return array.get(array.size()-1);
}
return null;
}
@Override
public IFlutterViewContainer findContainerById(String uniqueId) {
IFlutterViewContainer target = null;
for (Map.Entry<IFlutterViewContainer, IContainerRecord> entry : mRecords.entrySet()) {
if (TextUtils.equals(uniqueId, entry.getValue().uniqueId())) {
target = entry.getKey();
break;
}
}
if(target == null) {
for(ContainerRef ref:mRefs){
if(TextUtils.equals(uniqueId,ref.uniqueId)) {
return ref.container.get();
}
}
}
return target;
}
@Override
public void onShownContainerChanged(String old, String now) {
assertCallOnMainThread();
IFlutterViewContainer oldContainer = null;
IFlutterViewContainer nowContainer = null;
for (Map.Entry<IFlutterViewContainer, IContainerRecord> entry : mRecords.entrySet()) {
if (TextUtils.equals(old, entry.getValue().uniqueId())) {
oldContainer = entry.getKey();
}
if (TextUtils.equals(now, entry.getValue().uniqueId())) {
nowContainer = entry.getKey();
}
if (oldContainer != null && nowContainer != null) {
break;
}
}
if (nowContainer != null) {
nowContainer.onContainerShown();
}
if (oldContainer != null) {
oldContainer.onContainerHidden();
}
}
@Override
public boolean hasContainerAppear() {
assertCallOnMainThread();
for (Map.Entry<IFlutterViewContainer, IContainerRecord> entry : mRecords.entrySet()) {
if (entry.getValue().getState() == IContainerRecord.STATE_APPEAR) {
return true;
}
}
return false;
}
@Override
public void reset() {
}
private void assertCallOnMainThread() {
if (Looper.myLooper() != Looper.getMainLooper()) {
Debuger.exception("must call method on main thread");
}
}
public static class ContainerRef {
public final String uniqueId;
public final WeakReference<IFlutterViewContainer> container;
ContainerRef(String id, IFlutterViewContainer container) {
this.uniqueId = id;
this.container = new WeakReference<>(container);
}
}
public static class PluginRegistryImpl implements PluginRegistry {
final BoostFlutterView mBoostFlutterView;
PluginRegistryImpl(Activity activity, BoostFlutterView flutterView) {
mBoostFlutterView = flutterView;
}
@Override
public Registrar registrarFor(String pluginKey) {
return mBoostFlutterView.getPluginRegistry().registrarFor(pluginKey);
}
@Override
public boolean hasPlugin(String key) {
return mBoostFlutterView.getPluginRegistry().hasPlugin(key);
}
@Override
public <T> T valuePublishedByPlugin(String pluginKey) {
return mBoostFlutterView.getPluginRegistry().valuePublishedByPlugin(pluginKey);
}
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import android.app.Activity;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewProvider;
import com.taobao.idlefish.flutterboost.interfaces.IPlatform;
public class FlutterViewProvider implements IFlutterViewProvider {
private final IPlatform mPlatform;
private BoostFlutterNativeView mFlutterNativeView = null;
private BoostFlutterView mFlutterView = null;
FlutterViewProvider(IPlatform platform){
mPlatform = platform;
}
@Override
public BoostFlutterView createFlutterView(IFlutterViewContainer container) {
Activity activity = mPlatform.getMainActivity();
if(activity == null) {
Debuger.log("create Flutter View not with MainActivity");
activity = container.getActivity();
}
if (mFlutterView == null) {
mFlutterView = new BoostFlutterView(activity, null, createFlutterNativeView(container));
}
return mFlutterView;
}
@Override
public BoostFlutterNativeView createFlutterNativeView(IFlutterViewContainer container) {
if (mFlutterNativeView == null) {
mFlutterNativeView = new BoostFlutterNativeView(container.getActivity().getApplicationContext());
}
return mFlutterNativeView;
}
@Override
public BoostFlutterView tryGetFlutterView() {
return mFlutterView;
}
@Override
public void stopFlutterView() {
final BoostFlutterView view = mFlutterView;
if(view != null) {
view.boostStop();
}
}
@Override
public void reset() {
if(mFlutterNativeView != null) {
mFlutterNativeView.boostDestroy();
mFlutterNativeView = null;
}
if(mFlutterView != null) {
mFlutterView.boostDestroy();
mFlutterView = null;
}
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import com.taobao.idlefish.flutterboost.interfaces.IContainerRecord;
import com.taobao.idlefish.flutterboost.interfaces.IContainerManager;
public class Instrument {
private final IContainerManager mManager;
Instrument(IContainerManager manager) {
mManager = manager;
}
public void performCreate(IContainerRecord record) {
final int currentState = record.getState();
if (currentState != IContainerRecord.STATE_UNKNOW) {
Debuger.exception("performCreate state error, current state:" + currentState);
return;
}
record.onCreate();
}
public void performAppear(IContainerRecord record) {
final int currentState = record.getState();
if (currentState != IContainerRecord.STATE_CREATED
&& currentState != IContainerRecord.STATE_DISAPPEAR) {
Debuger.exception("performAppear state error, current state:" + currentState);
return;
}
record.onAppear();
}
public void performDisappear(IContainerRecord record) {
final int currentState = record.getState();
if (currentState != IContainerRecord.STATE_APPEAR) {
Debuger.exception("performDisappear state error , current state:" + currentState);
return;
}
record.onDisappear();
}
public void performDestroy(IContainerRecord record) {
final int currentState = record.getState();
if (currentState != IContainerRecord.STATE_DISAPPEAR) {
Debuger.exception("performDestroy state error, current state:" + currentState);
}
record.onDestroy();
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.NavigationService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import fleamarket.taobao.com.xservicekit.handler.MessageHandler;
import fleamarket.taobao.com.xservicekit.service.ServiceTemplate;
import fleamarket.taobao.com.xservicekit.service.ServiceGateway;
import io.flutter.plugin.common.MethodChannel;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
public class NavigationService {
private static final ServiceTemplate mService = new ServiceTemplate("NavigationService");
public static ServiceTemplate getService(){
return mService;
}
public static void register(){
ServiceGateway.sharedInstance().addService(mService);
}
public static void onNativePageResult(final MessageResult<Boolean> result ,String uniqueId,String key,Map resultData,Map params){
Map<String,Object> args = new HashMap<>();
args.put("uniqueId",uniqueId);
args.put("key",key);
args.put("resultData",resultData);
args.put("params",params);
mService.invoke("onNativePageResult", args, mService.methodChannelName(), new MethodChannel.Result() {
@Override
public void success(Object o) {
if (o instanceof Boolean){
result.success((Boolean)o);
}else{
result.error("return type error code dart code","","");
}
}
@Override
public void error(String s, String s1, Object o) {
if (result != null){
result.error(s,s1,o);
}
}
@Override
public void notImplemented() {
if (result != null){
result.notImplemented();
}
}
});
}
public static void didShowPageContainer(final MessageResult<Boolean> result ,String pageName,Map params,String uniqueId){
Map<String,Object> args = new HashMap<>();
args.put("pageName",pageName);
args.put("params",params);
args.put("uniqueId",uniqueId);
mService.invoke("didShowPageContainer", args, mService.methodChannelName(), new MethodChannel.Result() {
@Override
public void success(Object o) {
if (o instanceof Boolean){
result.success((Boolean)o);
}else{
result.error("return type error code dart code","","");
}
}
@Override
public void error(String s, String s1, Object o) {
if (result != null){
result.error(s,s1,o);
}
}
@Override
public void notImplemented() {
if (result != null){
result.notImplemented();
}
}
});
}
public static void willShowPageContainer(final MessageResult<Boolean> result ,String pageName,Map params,String uniqueId){
Map<String,Object> args = new HashMap<>();
args.put("pageName",pageName);
args.put("params",params);
args.put("uniqueId",uniqueId);
mService.invoke("willShowPageContainer", args, mService.methodChannelName(), new MethodChannel.Result() {
@Override
public void success(Object o) {
if (o instanceof Boolean){
result.success((Boolean)o);
}else{
result.error("return type error code dart code","","");
}
}
@Override
public void error(String s, String s1, Object o) {
if (result != null){
result.error(s,s1,o);
}
}
@Override
public void notImplemented() {
if (result != null){
result.notImplemented();
}
}
});
}
public static void willDisappearPageContainer(final MessageResult<Boolean> result ,String pageName,Map params,String uniqueId){
Map<String,Object> args = new HashMap<>();
args.put("pageName",pageName);
args.put("params",params);
args.put("uniqueId",uniqueId);
mService.invoke("willDisappearPageContainer", args, mService.methodChannelName(), new MethodChannel.Result() {
@Override
public void success(Object o) {
if (o instanceof Boolean){
result.success((Boolean)o);
}else{
result.error("return type error code dart code","","");
}
}
@Override
public void error(String s, String s1, Object o) {
if (result != null){
result.error(s,s1,o);
}
}
@Override
public void notImplemented() {
if (result != null){
result.notImplemented();
}
}
});
}
public static void didDisappearPageContainer(final MessageResult<Boolean> result ,String pageName,Map params,String uniqueId){
Map<String,Object> args = new HashMap<>();
args.put("pageName",pageName);
args.put("params",params);
args.put("uniqueId",uniqueId);
mService.invoke("didDisappearPageContainer", args, mService.methodChannelName(), new MethodChannel.Result() {
@Override
public void success(Object o) {
if (o instanceof Boolean){
result.success((Boolean)o);
}else{
result.error("return type error code dart code","","");
}
}
@Override
public void error(String s, String s1, Object o) {
if (result != null){
result.error(s,s1,o);
}
}
@Override
public void notImplemented() {
if (result != null){
result.notImplemented();
}
}
});
}
public static void didInitPageContainer(final MessageResult<Boolean> result ,String pageName,Map params,String uniqueId){
Map<String,Object> args = new HashMap<>();
args.put("pageName",pageName);
args.put("params",params);
args.put("uniqueId",uniqueId);
mService.invoke("didInitPageContainer", args, mService.methodChannelName(), new MethodChannel.Result() {
@Override
public void success(Object o) {
if (o instanceof Boolean){
result.success((Boolean)o);
}else{
result.error("return type error code dart code","","");
}
}
@Override
public void error(String s, String s1, Object o) {
if (result != null){
result.error(s,s1,o);
}
}
@Override
public void notImplemented() {
if (result != null){
result.notImplemented();
}
}
});
}
public static void willDeallocPageContainer(final MessageResult<Boolean> result ,String pageName,Map params,String uniqueId){
Map<String,Object> args = new HashMap<>();
args.put("pageName",pageName);
args.put("params",params);
args.put("uniqueId",uniqueId);
mService.invoke("willDeallocPageContainer", args, mService.methodChannelName(), new MethodChannel.Result() {
@Override
public void success(Object o) {
if (o instanceof Boolean){
result.success((Boolean)o);
}else{
result.error("return type error code dart code","","");
}
}
@Override
public void error(String s, String s1, Object o) {
if (result != null){
result.error(s,s1,o);
}
}
@Override
public void notImplemented() {
if (result != null){
result.notImplemented();
}
}
});
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.NavigationService;
public class NavigationServiceRegister {
public static void register(){
NavigationService.register();
NavigationService_onShownContainerChanged.register();
NavigationService_onFlutterPageResult.register();
NavigationService_pageOnStart.register();
NavigationService_openPage.register();
NavigationService_closePage.register();
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.NavigationService;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import com.taobao.idlefish.flutterboost.FlutterViewContainerManager;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import fleamarket.taobao.com.xservicekit.handler.MessageHandler;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
import fleamarket.taobao.com.xservicekit.service.ServiceGateway;
public class NavigationService_closePage implements MessageHandler<Boolean>{
private Object mContext = null;
private boolean onCall(MessageResult<Boolean> result,String uniqueId,String pageName,Map params,Boolean animated){
FlutterBoostPlugin.containerManager().destroyContainerRecord(pageName,uniqueId);
result.success(true);
return true;
}
//==================Do not edit code blow!==============
@Override
public boolean onMethodCall(String name, Map args, MessageResult<Boolean> result) {
this.onCall(result,(String)args.get("uniqueId"),(String)args.get("pageName"),(Map)args.get("params"),(Boolean)args.get("animated"));
return true;
}
@Override
public List<String> handleMessageNames() {
List<String> h = new ArrayList<>();
h.add("closePage");
return h;
}
@Override
public Object getContext() {
return mContext;
}
@Override
public void setContext(Object obj) {
mContext = obj;
}
@Override
public String service() {
return "NavigationService";
}
public static void register(){
ServiceGateway.sharedInstance().registerHandler(new NavigationService_closePage());
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.NavigationService;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import fleamarket.taobao.com.xservicekit.handler.MessageHandler;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
import fleamarket.taobao.com.xservicekit.service.ServiceGateway;
public class NavigationService_onFlutterPageResult implements MessageHandler<Boolean>{
private Object mContext = null;
private boolean onCall(MessageResult<Boolean> result,String uniqueId,String key,Map resultData,Map params){
FlutterBoostPlugin.containerManager().setContainerResult(uniqueId,resultData);
result.success(true);
return true;
}
//==================Do not edit code blow!==============
@Override
public boolean onMethodCall(String name, Map args, MessageResult<Boolean> result) {
this.onCall(result,(String)args.get("uniqueId"),(String)args.get("key"),(Map)args.get("resultData"),(Map)args.get("params"));
return true;
}
@Override
public List<String> handleMessageNames() {
List<String> h = new ArrayList<>();
h.add("onFlutterPageResult");
return h;
}
@Override
public Object getContext() {
return mContext;
}
@Override
public void setContext(Object obj) {
mContext = obj;
}
@Override
public String service() {
return "NavigationService";
}
public static void register(){
ServiceGateway.sharedInstance().registerHandler(new NavigationService_onFlutterPageResult());
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.NavigationService;
import com.taobao.idlefish.flutterboost.Debuger;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import fleamarket.taobao.com.xservicekit.handler.MessageHandler;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
import fleamarket.taobao.com.xservicekit.service.ServiceGateway;
public class NavigationService_onShownContainerChanged implements MessageHandler<Boolean>{
private Object mContext = null;
private boolean onCall(MessageResult<Boolean> result,String now,String old,Map params){
//Add your handler code here.
FlutterBoostPlugin.containerManager().onShownContainerChanged(old,now);
return true;
}
//==================Do not edit code blow!==============
@Override
public boolean onMethodCall(String name, Map args, MessageResult<Boolean> result) {
this.onCall(result,(String)args.get("newName"),(String)args.get("oldName"),(Map)args.get("params"));
return true;
}
@Override
public List<String> handleMessageNames() {
List<String> h = new ArrayList<>();
h.add("onShownContainerChanged");
return h;
}
@Override
public Object getContext() {
return mContext;
}
@Override
public void setContext(Object obj) {
mContext = obj;
}
@Override
public String service() {
return "NavigationService";
}
public static void register(){
ServiceGateway.sharedInstance().registerHandler(new NavigationService_onShownContainerChanged());
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.NavigationService;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import fleamarket.taobao.com.xservicekit.handler.MessageHandler;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
import fleamarket.taobao.com.xservicekit.service.ServiceGateway;
public class NavigationService_openPage implements MessageHandler<Boolean>{
private Object mContext = null;
private boolean onCall(MessageResult<Boolean> result,String pageName,Map params,Boolean animated){
Map pageParams = null;
int requestCode = 0;
if(params != null && params.get("query") != null) {
pageParams = (Map)params.get("query");
}
if(params != null && params.get("requestCode") != null) {
requestCode = (int)params.get("requestCode");
}
FlutterBoostPlugin.openPage(null,pageName,pageParams,requestCode);
result.success(true);
return true;
}
//==================Do not edit code blow!==============
@Override
public boolean onMethodCall(String name, Map args, MessageResult<Boolean> result) {
this.onCall(result,(String)args.get("pageName"),(Map)args.get("params"),(Boolean)args.get("animated"));
return true;
}
@Override
public List<String> handleMessageNames() {
List<String> h = new ArrayList<>();
h.add("openPage");
return h;
}
@Override
public Object getContext() {
return mContext;
}
@Override
public void setContext(Object obj) {
mContext = obj;
}
@Override
public String service() {
return "NavigationService";
}
public static void register(){
ServiceGateway.sharedInstance().registerHandler(new NavigationService_openPage());
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.NavigationService;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import com.taobao.idlefish.flutterboost.FlutterViewContainerManager;
import com.taobao.idlefish.flutterboost.interfaces.IContainerRecord;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import fleamarket.taobao.com.xservicekit.handler.MessageHandler;
import fleamarket.taobao.com.xservicekit.handler.MessageResult;
import fleamarket.taobao.com.xservicekit.service.ServiceGateway;
public class NavigationService_pageOnStart implements MessageHandler<Map>{
private Object mContext = null;
private boolean onCall(MessageResult<Map> result,Map params){
Map<String,Object> pageInfo = new HashMap<>();
try {
IContainerRecord record = FlutterBoostPlugin
.containerManager().getCurrentTopRecord();
if(record == null) {
record = FlutterBoostPlugin.containerManager().getLastRecord();
}
pageInfo.put("name",record.getContainer().getContainerName());
pageInfo.put("params",record.getContainer().getContainerParams());
pageInfo.put("uniqueId",record.uniqueId());
result.success(pageInfo);
}catch (Throwable t){
result.success(pageInfo);
}
return true;
}
//==================Do not edit code blow!==============
@Override
public boolean onMethodCall(String name, Map args, MessageResult<Map> result) {
this.onCall(result,(Map)args.get("params"));
return true;
}
@Override
public List<String> handleMessageNames() {
List<String> h = new ArrayList<>();
h.add("pageOnStart");
return h;
}
@Override
public Object getContext() {
return mContext;
}
@Override
public void setContext(Object obj) {
mContext = obj;
}
@Override
public String service() {
return "NavigationService";
}
public static void register(){
ServiceGateway.sharedInstance().registerHandler(new NavigationService_pageOnStart());
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import java.util.Map;
public interface PageResultHandler {
void onResult(String key , Map resultData);
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import java.util.HashMap;
import java.util.Map;
class PageResultMediator {
private Map<String,PageResultHandler> _handlers = new HashMap<>();
void onPageResult(String key , Map resultData){
if(key == null) return;
if(_handlers.containsKey(key)){
_handlers.get(key).onResult(key,resultData);
_handlers.remove(key);
}
}
void setHandler(String key, PageResultHandler handler){
if(key == null || handler == null) return;
_handlers.put(key,handler);
}
void removeHandler(String key){
if(key == null) return;;
_handlers.remove(key);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost;
import android.graphics.Bitmap;
import android.graphics.Color;
public class Utils {
public static boolean checkImageValid(final Bitmap bitmap) {
if (null == bitmap) {
return false;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
int [] checkPixels = new int[18];
for (int i=0; i<5; i++) {
int colCount = 4 - i%2;
for (int j=0; j<colCount; j++) {
checkPixels[i*3 + j + (i+1)/2] = pixels[(i + 1)*(height/6)*width + (j + 1)*(width/(colCount + 1))];
}
}
float[][] checkHSV = new float[checkPixels.length][3];
for (int i=0; i<checkPixels.length; i++) {
int clr = checkPixels[i];
int red = (clr & 0x00ff0000) >> 16; // 取高两位
int green = (clr & 0x0000ff00) >> 8; // 取中两位
int blue = clr & 0x000000ff;
Color.RGBToHSV(red, green, blue, checkHSV[i]);
}
int diffCount = 0;
for (int i=0; i<checkPixels.length; i++) {
for (int j=i+1; j<checkPixels.length; j++) {
double d = Math.sqrt(Math.pow(checkHSV[i][0] - checkHSV[j][0], 2.0)
+ Math.pow(checkHSV[i][1] - checkHSV[j][1], 2.0)
+ Math.pow(checkHSV[i][2] - checkHSV[j][2], 2.0));
if (d >= 1) {
diffCount++;
}
}
}
if (diffCount <= 10) {
return false;
} else {
return true;
}
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.containers;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.taobao.idlefish.flutterboost.BoostFlutterView;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import java.util.HashMap;
import java.util.Map;
import io.flutter.app.FlutterActivity;
import io.flutter.view.FlutterNativeView;
import io.flutter.view.FlutterView;
abstract public class BoostFlutterActivity extends FlutterActivity implements IFlutterViewContainer {
private FlutterContent mFlutterContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
mFlutterContent = new FlutterContent(this);
setContentView(mFlutterContent);
FlutterBoostPlugin.containerManager().onContainerCreate(this);
onRegisterPlugins(this);
}
@Override
protected void onPostResume() {
super.onPostResume();
FlutterBoostPlugin.containerManager().onContainerAppear(BoostFlutterActivity.this);
mFlutterContent.attachFlutterView(getBoostFlutterView());
}
@Override
protected void onPause() {
mFlutterContent.detachFlutterView();
FlutterBoostPlugin.containerManager().onContainerDisappear(this);
super.onPause();
}
@Override
protected void onDestroy() {
FlutterBoostPlugin.containerManager().onContainerDestroy(this);
mFlutterContent.destroy();
super.onDestroy();
}
public FlutterView createFlutterView(Context context) {
return FlutterBoostPlugin.viewProvider().createFlutterView(this);
}
@Override
public FlutterNativeView createFlutterNativeView() {
return FlutterBoostPlugin.viewProvider().createFlutterNativeView(this);
}
@Override
public boolean retainFlutterNativeView() {
return true;
}
protected View createSplashScreenView() {
FrameLayout frameLayout = new FrameLayout(this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
frameLayout.addView(new ProgressBar(this), params);
return frameLayout;
}
protected View createFlutterInitCoverView() {
View initCover = new View(this);
initCover.setBackgroundColor(Color.WHITE);
return initCover;
}
@Override
public void onContainerShown() {
mFlutterContent.onContainerShown();
}
@Override
public void onContainerHidden() {
mFlutterContent.onContainerHidden();
}
@Override
public void onBackPressed() {
FlutterBoostPlugin.containerManager().onBackPressed(this);
}
@Override
public Activity getActivity() {
return this;
}
@Override
public BoostFlutterView getBoostFlutterView() {
return (BoostFlutterView) getFlutterView();
}
@Override
public void destroyContainer() {
finish();
}
@Override
public abstract String getContainerName();
@Override
public abstract Map getContainerParams();
@Override
public void setBoostResult(HashMap result) {
FlutterBoostPlugin.setBoostResult(this, result);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
FlutterBoostPlugin.onBoostResult(this,requestCode,resultCode,data);
}
class FlutterContent extends FlutterViewStub {
public FlutterContent(Context context) {
super(context);
}
@Override
public View createFlutterInitCoverView() {
return BoostFlutterActivity.this.createFlutterInitCoverView();
}
@Override
public BoostFlutterView getBoostFlutterView() {
return BoostFlutterActivity.this.getBoostFlutterView();
}
@Override
public View createSplashScreenView() {
return BoostFlutterActivity.this.createSplashScreenView();
}
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.containers;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.taobao.idlefish.flutterboost.BoostFlutterView;
import com.taobao.idlefish.flutterboost.Debuger;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import com.taobao.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import java.util.HashMap;
import io.flutter.plugin.common.PluginRegistry;
abstract public class BoostFlutterFragment extends Fragment implements IFlutterViewContainer {
FlutterContent mContent;
PluginRegistry mRegistry;
boolean resumed = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRegistry = FlutterBoostPlugin.containerManager().onContainerCreate(this);
onRegisterPlugins(mRegistry);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
mContent = new FlutterContent(getActivity());
return mContent;
}
@Override
public void onResume() {
super.onResume();
if (!resumed) {
resumed = true;
FlutterBoostPlugin.containerManager().onContainerAppear(this);
mContent.attachFlutterView(getBoostFlutterView());
Log.e("FlutterBoost", "FlutterMenuFragment resume");
}
}
@Override
public void onPause() {
super.onPause();
if (resumed) {
resumed = false;
mContent.snapshot();
FlutterBoostPlugin.containerManager().onContainerDisappear(this);
Log.e("FlutterBoost", "FlutterMenuFragment stop");
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mContent != null) {
mContent.destroy();
}
FlutterBoostPlugin.containerManager().onContainerDestroy(this);
}
@Override
public void onContainerShown() {
mContent.onContainerShown();
}
@Override
public void onContainerHidden() {
mContent.onContainerHidden();
}
@Override
public BoostFlutterView getBoostFlutterView() {
return FlutterBoostPlugin.viewProvider().createFlutterView(this);
}
@Override
public boolean isFinishing() {
return getActivity().isFinishing();
}
protected View createSplashScreenView() {
FrameLayout layout = new FrameLayout(getContext());
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
layout.addView(new ProgressBar(getContext()),params);
return layout;
}
protected View createFlutterInitCoverView() {
View initCover = new View(getActivity());
initCover.setBackgroundColor(Color.WHITE);
return initCover;
}
@Override
public void setBoostResult(HashMap result) {
}
class FlutterContent extends FlutterViewStub {
public FlutterContent(Context context) {
super(context);
}
@Override
public View createFlutterInitCoverView() {
return BoostFlutterFragment.this.createFlutterInitCoverView();
}
@Override
public BoostFlutterView getBoostFlutterView() {
return BoostFlutterFragment.this.getBoostFlutterView();
}
@Override
public View createSplashScreenView() {
return BoostFlutterFragment.this.createSplashScreenView();
}
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.containers;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import com.taobao.idlefish.flutterboost.BoostFlutterView;
import com.taobao.idlefish.flutterboost.Debuger;
abstract public class FlutterViewStub extends FrameLayout {
public static final Handler sHandler = new ProcessHandler(Looper.getMainLooper());
protected Bitmap mBitmap;
protected ImageView mSnapshot;
protected FrameLayout mStub;
protected View mCover;
protected View mSplashScreenView;
public FlutterViewStub(Context context) {
super(context);
mStub = new FrameLayout(context);
mStub.setBackgroundColor(Color.WHITE);
addView(mStub, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mSnapshot = new ImageView(context);
mSnapshot.setScaleType(ImageView.ScaleType.FIT_CENTER);
mSnapshot.setLayoutParams(new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mCover = createFlutterInitCoverView();
addView(mCover, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
final BoostFlutterView flutterView = getBoostFlutterView();
if (!flutterView.firstFrameCalled()) {
mSplashScreenView = createSplashScreenView();
addView(mSplashScreenView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
}
public void onContainerShown() {
Debuger.log("onContainerShown");
sHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (mSplashScreenView != null) {
FlutterViewStub.this.removeView(mSplashScreenView);
mSplashScreenView = null;
}
if (mCover != null) {
FlutterViewStub.this.removeView(mCover);
}
if (mSnapshot.getParent() == FlutterViewStub.this) {
FlutterViewStub.this.removeView(mSnapshot);
mSnapshot.setImageBitmap(null);
if (mBitmap != null && !mBitmap.isRecycled()) {
mBitmap.recycle();
mBitmap = null;
}
}
getBoostFlutterView().scheduleFrame();
getBoostFlutterView().requestFocus();
getBoostFlutterView().invalidate();
}
}, 167);
}
public void onContainerHidden() {
//Debuger.log("onContainerHidden");
}
public void snapshot() {
if (mStub.getChildCount() <= 0) return;
if (mSnapshot.getParent() != null) return;
BoostFlutterView flutterView = (BoostFlutterView) mStub.getChildAt(0);
mBitmap = flutterView.getBitmap();
if (mBitmap != null && !mBitmap.isRecycled()) {
mSnapshot.setImageBitmap(mBitmap);
addView(mSnapshot);
}
}
public void attachFlutterView(final BoostFlutterView flutterView) {
if (flutterView.getParent() != mStub) {
sHandler.removeMessages(ProcessHandler.MSG_DETACH);
Debuger.log("attachFlutterView");
if (flutterView.getParent() != null) {
((ViewGroup) flutterView.getParent()).removeView(flutterView);
}
mStub.addView(flutterView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
}
public void detachFlutterView() {
if (mStub.getChildCount() <= 0) return;
final BoostFlutterView flutterView = (BoostFlutterView) mStub.getChildAt(0);
if (flutterView == null) return;
Debuger.log("detachFlutterView");
if (mSnapshot.getParent() == null) {
mBitmap = flutterView.getBitmap();
if (mBitmap != null && !mBitmap.isRecycled()) {
mSnapshot.setImageBitmap(mBitmap);
addView(mSnapshot);
}
}
Message msg = new Message();
msg.what = ProcessHandler.MSG_DETACH;
msg.obj = new Runnable() {
@Override
public void run() {
if (flutterView.getParent() != null && flutterView.getParent() == mStub) {
mStub.removeView(flutterView);
}
}
};
sHandler.sendMessage(msg);
}
public void destroy() {
removeAllViews();
mSnapshot.setImageBitmap(null);
if (mBitmap != null && !mBitmap.isRecycled()) {
mBitmap.recycle();
mBitmap = null;
}
}
protected View createFlutterInitCoverView() {
View initCover = new View(getContext());
initCover.setBackgroundColor(Color.WHITE);
return initCover;
}
protected View createSplashScreenView() {
FrameLayout layout = new FrameLayout(getContext());
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER;
layout.addView(new ProgressBar(getContext()),params);
return layout;
}
abstract protected BoostFlutterView getBoostFlutterView();
public static class ProcessHandler extends Handler {
static final int MSG_DETACH = 175101;
ProcessHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.obj instanceof Runnable) {
Runnable run = (Runnable) msg.obj;
run.run();
}
}
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.interfaces;
import android.app.Activity;
import java.util.Map;
import io.flutter.plugin.common.PluginRegistry;
public interface IContainerManager {
/**
* call by native side when container create
* @param container
* @return
*/
PluginRegistry onContainerCreate(IFlutterViewContainer container);
/**
* call by native side when container appear
* @param container
* @return
*/
void onContainerAppear(IFlutterViewContainer container);
/**
* call by native side when container disappear
* @param container
* @return
*/
void onContainerDisappear(IFlutterViewContainer container);
/**
* call by native side when container destroy
* @param container
* @return
*/
void onContainerDestroy(IFlutterViewContainer container);
/**
* call by native side when back key pressed
* @param container
* @return
*/
void onBackPressed(IFlutterViewContainer container);
/**
* call by flutter side when need destroy container
* @param name
* @param uq
*/
void destroyContainerRecord(String name,String uq);
/**
* call by native side when container handle a result (onActivityResult)
* @param container
* @param result
*/
void onContainerResult(IFlutterViewContainer container,Map result);
/**
* call by flutter side when flutter want set a result for request (setResult)
* @param uniqueId
* @param result
*/
void setContainerResult(String uniqueId,Map result);
/**
* get current interactive container
* @return
*/
IContainerRecord getCurrentTopRecord();
/**
* get last created container
* @return
*/
IContainerRecord getLastRecord();
/**
* find a container
* @param uniqueId
* @return
*/
IFlutterViewContainer findContainerById(String uniqueId);
/**
* call by flutter side when a container shown or hidden
* @param old
* @param now
*/
void onShownContainerChanged(String old,String now);
/**
* is any container appear now
* @return
*/
boolean hasContainerAppear();
/**
* no use
*/
void reset();
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.interfaces;
import java.util.Map;
/**
* a container record, which use map a flutter page
*/
public interface IContainerRecord {
int STATE_UNKNOW = 0;
int STATE_CREATED = 1;
int STATE_APPEAR = 2;
int STATE_DISAPPEAR = 3;
int STATE_DESTROYED = 4;
String uniqueId();
IFlutterViewContainer getContainer();
int getState();
void onCreate();
void onAppear();
void onDisappear();
void onDestroy();
void onResult(Map Result);
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.interfaces;
import android.app.Activity;
import com.taobao.idlefish.flutterboost.BoostFlutterView;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.PluginRegistry;
/**
* a container which contains the flutter view
*/
public interface IFlutterViewContainer {
String RESULT_KEY = "_flutter_result_";
Activity getActivity();
/**
* provide a flutter view
* @return
*/
BoostFlutterView getBoostFlutterView();
/**
* call to destroy the container
*/
void destroyContainer();
/**
* container name
* @return
*/
String getContainerName();
/**
* container params
* @return
*/
Map getContainerParams();
/**
* callback when container shown
*/
void onContainerShown();
/**
* callback when container hidden
*/
void onContainerHidden();
/**
* is container finishing
* @return
*/
boolean isFinishing();
/**
* call by flutter side to set result
* @param result
*/
void setBoostResult(HashMap result);
/**
* register flutter plugins
* @param registry
*/
void onRegisterPlugins(PluginRegistry registry);
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.interfaces;
import com.taobao.idlefish.flutterboost.BoostFlutterNativeView;
import com.taobao.idlefish.flutterboost.BoostFlutterView;
/**
* a flutter view provider
*/
public interface IFlutterViewProvider {
/**
* create flutter view, we just hold a single instance now
* @param container
* @return
*/
BoostFlutterView createFlutterView(IFlutterViewContainer container);
/**
* single instance also
* @param container
* @return
*/
BoostFlutterNativeView createFlutterNativeView(IFlutterViewContainer container);
/**
* may return null
* @return
*/
BoostFlutterView tryGetFlutterView();
/**
* release flutter view
*/
void stopFlutterView();
/**
* reset all refrence
*/
void reset();
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.interfaces;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import java.util.Map;
/**
* APIs that platform(Android App) must provide
*/
public interface IPlatform {
/**
* get current application
* @return
*/
Application getApplication();
/**
* get main activity, which must always exist at the bottom of task stack.
* @return
*/
Activity getMainActivity();
/**
* debug or not
* @return
*/
boolean isDebug();
/**
* start a new activity from flutter page, you may need a page router with url
* @param context
* @param url
* @param requestCode
* @return
*/
boolean startActivity(Context context,String url,int requestCode);
/**
* settings, no use
* @return
*/
Map getSettings();
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.taobao.idlefish.flutterboost.loader;
public class ServiceLoader {
public static void load(){
com.taobao.idlefish.flutterboost.NavigationService.NavigationServiceRegister.register();
}
}
\ No newline at end of file
.DS_Store
.dart_tool/
.packages
.pub/
.idea
build/
.flutter-plugins
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 2a5023ac70c4566dd56d7d00b1b7bd47a0e3cf80
channel: xy_beta_v0.8.2
# flutter_boost_example
Demonstrates how to use the flutter_boost plugin.
## Getting Started
For help getting started with Flutter, view our online
[documentation](https://flutter.io/).
*.iml
*.class
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
GeneratedPluginRegistrant.java
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 27
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.taobao.idlefish.flutterboostexample"
minSdkVersion 16
targetSdkVersion 27
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.taobao.idlefish.flutterboostexample">
<!-- The INTERNET permission is required for development. Specifically,
flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name=".MyApplication"
android:label="flutter_boost_example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".FlutterPageActivity"
android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"/>
<activity
android:name=".FlutterFragmentPageActivity"
android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"/>
<activity
android:name=".NativePageActivity"
android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:windowSoftInputMode="adjustResize"/>
</application>
</manifest>
package com.taobao.idlefish.flutterboostexample;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.taobao.idlefish.flutterboost.containers.BoostFlutterFragment;
import java.util.HashMap;
import java.util.Map;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class FlutterFragment extends BoostFlutterFragment {
@Override
public void setArguments(@Nullable Bundle args) {
if(args == null) {
args = new Bundle();
args.putString("tag","");
}
super.setArguments(args);
}
public void setTabTag(String tag) {
Bundle args = new Bundle();
args.putString("tag",tag);
super.setArguments(args);
}
@Override
public void onRegisterPlugins(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
return "flutterFragment";
}
@Override
public Map getContainerParams() {
Map<String,String> params = new HashMap<>();
params.put("tag",getArguments().getString("tag"));
return params;
}
@Override
public void destroyContainer() {
}
public static FlutterFragment instance(String tag){
FlutterFragment fragment = new FlutterFragment();
fragment.setTabTag(tag);
return fragment;
}
}
package com.taobao.idlefish.flutterboostexample;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import android.view.WindowManager;
import io.flutter.plugin.platform.PlatformPlugin;
public class FlutterFragmentPageActivity extends AppCompatActivity {
private FlutterFragment mFragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(0x40000000);
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
}
super.onCreate(savedInstanceState);
final ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
actionBar.hide();
}
setContentView(R.layout.flutter_fragment_page);
mFragment = FlutterFragment.instance("hello");
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_stub,mFragment)
.commit();
}
}
package com.taobao.idlefish.flutterboostexample;
import com.taobao.idlefish.flutterboost.containers.BoostFlutterActivity;
import java.util.Map;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class FlutterPageActivity extends BoostFlutterActivity {
@Override
public void onRegisterPlugins(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
return "flutterPage";
}
@Override
public Map getContainerParams() {
return null;
}
}
package com.taobao.idlefish.flutterboostexample;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static WeakReference<MainActivity> sRef;
private TextView mOpenNative;
private TextView mOpenFlutter;
private TextView mOpenFlutterFragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sRef = new WeakReference<>(this);
setContentView(R.layout.native_page);
mOpenNative = findViewById(R.id.open_native);
mOpenFlutter = findViewById(R.id.open_flutter);
mOpenFlutterFragment = findViewById(R.id.open_flutter_fragment);
mOpenNative.setOnClickListener(this);
mOpenFlutter.setOnClickListener(this);
mOpenFlutterFragment.setOnClickListener(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
sRef.clear();
sRef = null;
}
@Override
public void onClick(View v) {
if (v == mOpenNative) {
PageRouter.openPageByUrl(this, PageRouter.NATIVE_PAGE_URL);
} else if (v == mOpenFlutter) {
PageRouter.openPageByUrl(this, PageRouter.FLUTTER_PAGE_URL);
} else if (v == mOpenFlutterFragment) {
PageRouter.openPageByUrl(this, PageRouter.FLUTTER_FRAGMENT_PAGE_URL);
}
}
}
package com.taobao.idlefish.flutterboostexample;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import com.taobao.idlefish.flutterboost.FlutterBoostPlugin;
import com.taobao.idlefish.flutterboost.interfaces.IPlatform;
import java.util.Map;
import io.flutter.app.FlutterApplication;
public class MyApplication extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
FlutterBoostPlugin.init(new IPlatform() {
@Override
public Application getApplication() {
return MyApplication.this;
}
/**
* 获取应用入口的Activity,这个Activity在应用交互期间应该是一直在栈底的
* @return
*/
@Override
public Activity getMainActivity() {
return MainActivity.sRef.get();
}
@Override
public boolean isDebug() {
return true;
}
@Override
public boolean startActivity(Context context, String url, int requestCode) {
return PageRouter.openPageByUrl(context,url,requestCode);
}
@Override
public Map getSettings() {
return null;
}
});
}
}
package com.taobao.idlefish.flutterboostexample;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
public class NativePageActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mOpenNative;
private TextView mOpenFlutter;
private TextView mOpenFlutterFragment;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.native_page);
mOpenNative = findViewById(R.id.open_native);
mOpenFlutter = findViewById(R.id.open_flutter);
mOpenFlutterFragment = findViewById(R.id.open_flutter_fragment);
mOpenNative.setOnClickListener(this);
mOpenFlutter.setOnClickListener(this);
mOpenFlutterFragment.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v == mOpenNative) {
PageRouter.openPageByUrl(this, PageRouter.NATIVE_PAGE_URL);
} else if (v == mOpenFlutter) {
PageRouter.openPageByUrl(this, PageRouter.FLUTTER_PAGE_URL);
} else if (v == mOpenFlutterFragment) {
PageRouter.openPageByUrl(this, PageRouter.FLUTTER_FRAGMENT_PAGE_URL);
}
}
}
\ No newline at end of file
package com.taobao.idlefish.flutterboostexample;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
public class PageRouter {
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) {
return openPageByUrl(context, url, 0);
}
public static boolean openPageByUrl(Context context, String url, int requestCode) {
try {
if (TextUtils.equals(url, FLUTTER_PAGE_URL)) {
context.startActivity(new Intent(context, FlutterPageActivity.class));
return true;
} else if (TextUtils.equals(url, FLUTTER_FRAGMENT_PAGE_URL)) {
context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
return true;
} else if (TextUtils.equals(url, NATIVE_PAGE_URL)) {
context.startActivity(new Intent(context, NativePageActivity.class));
return true;
} else {
return false;
}
} catch (Throwable t) {
return false;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/white">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/fragment_stub"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="left"
android:background="@android:color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:id="@+id/info"
android:text="@string/native_info"
android:textColor="@android:color/holo_blue_dark"
android:textSize="28sp"
android:layout_gravity="center_horizontal"/>
<View android:layout_width="1dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:background="@android:color/holo_orange_dark"
android:layout_margin="8.0dp"
android:padding="8.0dp"
android:textColor="@android:color/black"
android:id="@+id/open_native"
android:textAllCaps="false"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/open_native" />
<TextView
android:background="@android:color/holo_orange_dark"
android:layout_margin="8.0dp"
android:padding="8.0dp"
android:textColor="@android:color/black"
android:id="@+id/open_flutter"
android:textAllCaps="false"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/open_flutter" />
<TextView
android:background="@android:color/holo_orange_dark"
android:layout_marginLeft="8.0dp"
android:layout_marginTop="8.0dp"
android:layout_marginRight="8.0dp"
android:layout_marginBottom="80.0dp"
android:padding="8.0dp"
android:textColor="@android:color/black"
android:id="@+id/open_flutter_fragment"
android:textAllCaps="false"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/open_flutter_fragment" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="open_native">open native page</string>
<string name="open_flutter">open flutter page</string>
<string name="open_flutter_fragment">open flutter fragment page</string>
<string name="native_info">This is a native activity</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
\ No newline at end of file
org.gradle.jvmargs=-Xmx1536M
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/ios/.symlinks/plugins/xservice_kit/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/ios/.symlinks/plugins/xservice_kit/.pub" />
<excludeFolder url="file://$MODULE_DIR$/ios/.symlinks/plugins/xservice_kit/build" />
<excludeFolder url="file://$MODULE_DIR$/ios/.symlinks/plugins/xservice_kit/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/ios/.symlinks/plugins/xservice_kit/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/ios/.symlinks/plugins/xservice_kit/example/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="GEN_FOLDER_RELATIVE_PATH_APT" value="/android/gen" />
<option name="GEN_FOLDER_RELATIVE_PATH_AIDL" value="/android/gen" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/android/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/android/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/android/assets" />
<option name="LIBS_FOLDER_RELATIVE_PATH" value="/android/libs" />
<option name="PROGUARD_LOGS_FOLDER_RELATIVE_PATH" value="/android/proguard_logs" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/android">
<sourceFolder url="file://$MODULE_DIR$/android/app/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/android/gen" isTestSource="false" generated="true" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Flutter for Android" level="project" />
</component>
</module>
/Users/jidong/Documents/FlutterBoost
\ No newline at end of file
/Users/jidong/.pub-cache/hosted/pub.dartlang.org/xservice_kit-0.0.26
\ No newline at end of file
App.framework
Flutter.framework
flutter_assets
Generated.xcconfig
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
pods_ary = []
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
end
target 'Runner' do
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
# Flutter Pods
generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
if generated_xcode_build_settings.empty?
puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
end
generated_xcode_build_settings.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join('.symlinks', 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
end
}
# pod 'flutter_boost', :path => '../../ios'
# pod 'xservice_kit', :path => '.symlinks/plugins/xservice_kit/ios'
# Plugin Pods
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join('.symlinks', 'plugins', p[:name])
File.symlink(p[:path], symlink)
pod p[:name], :path => File.join(p[:path], 'ios')
}
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
PODS:
- Flutter (1.0.0)
- flutter_boost (0.0.1):
- Flutter
- xservice_kit
- xservice_kit (0.0.1):
- Flutter
DEPENDENCIES:
- flutter_boost (from `/Users/jidong/Documents/FlutterBoost/ios`)
- xservice_kit (from `/Users/jidong/.pub-cache/hosted/pub.dartlang.org/xservice_kit-0.0.26/ios`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- Flutter
EXTERNAL SOURCES:
flutter_boost:
:path: "/Users/jidong/Documents/FlutterBoost/ios"
xservice_kit:
:path: "/Users/jidong/.pub-cache/hosted/pub.dartlang.org/xservice_kit-0.0.26/ios"
SPEC CHECKSUMS:
Flutter: fa617360ba1995d522016bfa59d68df27ac12e02
flutter_boost: 24249d12d924d858cf445a84949484bc08bca000
xservice_kit: a86c64372b3e41e7d8e9b1a0b9139866680f525c
PODFILE CHECKSUM: 2a757a7bdc03b37a2814666652fdff1cf694243f
COCOAPODS: 1.5.3
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
921CEEAB9796F8104B126880 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C0C20F7D503C2CDF597A19CB /* libPods-Runner.a */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
DF544AA62177253600931378 /* UIViewControllerDemo.m in Sources */ = {isa = PBXBuildFile; fileRef = DF544AA42177253600931378 /* UIViewControllerDemo.m */; };
DF544AA72177253600931378 /* UIViewControllerDemo.xib in Resources */ = {isa = PBXBuildFile; fileRef = DF544AA52177253600931378 /* UIViewControllerDemo.xib */; };
DF544AD4217838EF00931378 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DF544AD3217838EF00931378 /* libc++.tbd */; };
DFD80BFA217DF95400E3F036 /* DemoRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = DFD80BF9217DF95400E3F036 /* DemoRouter.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C0C20F7D503C2CDF597A19CB /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DF544AA32177253600931378 /* UIViewControllerDemo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIViewControllerDemo.h; sourceTree = "<group>"; };
DF544AA42177253600931378 /* UIViewControllerDemo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIViewControllerDemo.m; sourceTree = "<group>"; };
DF544AA52177253600931378 /* UIViewControllerDemo.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIViewControllerDemo.xib; sourceTree = "<group>"; };
DF544ACF217836F600931378 /* libstdc++.6.0.9.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.6.0.9.tbd"; path = "usr/lib/libstdc++.6.0.9.tbd"; sourceTree = SDKROOT; };
DF544AD3217838EF00931378 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
DFD80BF8217DF95400E3F036 /* DemoRouter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoRouter.h; sourceTree = "<group>"; };
DFD80BF9217DF95400E3F036 /* DemoRouter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoRouter.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DF544AD4217838EF00931378 /* libc++.tbd in Frameworks */,
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
921CEEAB9796F8104B126880 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
248EAAEEAB727BFBF388239B /* Frameworks */ = {
isa = PBXGroup;
children = (
DF544AD3217838EF00931378 /* libc++.tbd */,
DF544ACF217836F600931378 /* libstdc++.6.0.9.tbd */,
C0C20F7D503C2CDF597A19CB /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
7BDD959A65220A7D194700AF /* Pods */ = {
isa = PBXGroup;
children = (
);
name = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
7BDD959A65220A7D194700AF /* Pods */,
248EAAEEAB727BFBF388239B /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
DF544AA32177253600931378 /* UIViewControllerDemo.h */,
DF544AA42177253600931378 /* UIViewControllerDemo.m */,
DF544AA52177253600931378 /* UIViewControllerDemo.xib */,
DFD80BF8217DF95400E3F036 /* DemoRouter.h */,
DFD80BF9217DF95400E3F036 /* DemoRouter.m */,
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
);
path = Runner;
sourceTree = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
97C146F21CF9000F007C117D /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
BCB6935FD3A46669EE413581 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
3FC74F80EA9D039C70D1F681 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0910;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = E83K84RE26;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DF544AA72177253600931378 /* UIViewControllerDemo.xib in Resources */,
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
};
3FC74F80EA9D039C70D1F681 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/Flutter/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
};
BCB6935FD3A46669EE413581 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DFD80BFA217DF95400E3F036 /* DemoRouter.m in Sources */,
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
97C146F31CF9000F007C117D /* main.m in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
DF544AA62177253600931378 /* UIViewControllerDemo.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = E83K84RE26;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = fleamarket.taobao.com.flutterBoostExample;
PRODUCT_NAME = "$(TARGET_NAME)";
REEXPORTED_LIBRARY_PATHS = "";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = E83K84RE26;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = fleamarket.taobao.com.flutterBoostExample;
PRODUCT_NAME = "$(TARGET_NAME)";
REEXPORTED_LIBRARY_PATHS = "";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Original</string>
</dict>
</plist>
//
// AppDelegate.h
// sdfsdf
//
// Created by Jidong Chen on 2018/10/18.
// Copyright © 2018年 Jidong Chen. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <flutter_boost/FlutterBoost.h>
@interface AppDelegate : FLBFlutterAppDelegate <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
//
// AppDelegate.m
// sdfsdf
//
// Created by Jidong Chen on 2018/10/18.
// Copyright © 2018年 Jidong Chen. All rights reserved.
//
#import "AppDelegate.h"
#import "UIViewControllerDemo.h"
#import "DemoRouter.h"
#import <flutter_boost/FlutterBoost.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
UIViewControllerDemo *vc = [[UIViewControllerDemo alloc] initWithNibName:@"UIViewControllerDemo" bundle:[NSBundle mainBundle]];
vc.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"hybrid" image:nil tag:0];
FLBFlutterViewContainer *fvc = FLBFlutterViewContainer.new;
[fvc setName:@"tab" params:@{}];
fvc.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"flutter_tab" image:nil tag:1];
UITabBarController *tabVC = [[UITabBarController alloc] init];
UINavigationController *rvc = [[UINavigationController alloc] initWithRootViewController:tabVC];
DemoRouter *router = [DemoRouter sharedRouter];
router.navigationController = rvc;
tabVC.viewControllers = @[vc,fvc];
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterViewController *fvc) {
}];
self.window.rootViewController = rvc;
UIButton *nativeButton = [UIButton buttonWithType:UIButtonTypeCustom];
nativeButton.frame = CGRectMake(self.window.frame.size.width * 0.5 - 50, 200, 100, 45);
nativeButton.backgroundColor = [UIColor redColor];
[nativeButton setTitle:@"push native" forState:UIControlStateNormal];
[nativeButton addTarget:self action:@selector(pushNative) forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:nativeButton];
return YES;
}
- (void)pushNative
{
UINavigationController *nvc = (id)self.window.rootViewController;
UIViewControllerDemo *vc = [[UIViewControllerDemo alloc] initWithNibName:@"UIViewControllerDemo" bundle:[NSBundle mainBundle]];
[nvc pushViewController:vc animated:YES];
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
//
// DemoRouter.h
// Runner
//
// Created by Jidong Chen on 2018/10/22.
// Copyright © 2018年 The Chromium Authors. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <flutter_boost/FLBPlatform.h>
NS_ASSUME_NONNULL_BEGIN
@interface DemoRouter : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
+ (DemoRouter *)sharedRouter;
@end
NS_ASSUME_NONNULL_END
//
// DemoRouter.m
// Runner
//
// Created by Jidong Chen on 2018/10/22.
// Copyright © 2018年 The Chromium Authors. All rights reserved.
//
#import "DemoRouter.h"
#import <flutter_boost/FlutterBoost.h>
@implementation DemoRouter
+ (DemoRouter *)sharedRouter
{
static id instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
- (void)openPage:(NSString *)name
params:(NSDictionary *)params
animated:(BOOL)animated
completion:(void (^)(BOOL))completion
{
if([params[@"present"] boolValue]){
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
}else{
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
}
}
- (void)closePage:(NSString *)uid animated:(BOOL)animated params:(NSDictionary *)params completion:(void (^)(BOOL))completion
{
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
//
// Generated file. Do not edit.
//
#ifndef GeneratedPluginRegistrant_h
#define GeneratedPluginRegistrant_h
#import <Flutter/Flutter.h>
@interface GeneratedPluginRegistrant : NSObject
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
@end
#endif /* GeneratedPluginRegistrant_h */
//
// Generated file. Do not edit.
//
#import "GeneratedPluginRegistrant.h"
#import <flutter_boost/FlutterBoostPlugin.h>
#import <xservice_kit/XserviceKitPlugin.h>
@implementation GeneratedPluginRegistrant
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
[FlutterBoostPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterBoostPlugin"]];
[XserviceKitPlugin registerWithRegistrar:[registry registrarForPlugin:@"XserviceKitPlugin"]];
}
@end
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_boost_example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>
//
// UIViewControllerDemo.h
// Runner
//
// Created by Jidong Chen on 2018/10/17.
// Copyright © 2018年 The Chromium Authors. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIViewControllerDemo : UIViewController
@end
NS_ASSUME_NONNULL_END
//
// UIViewControllerDemo.m
// Runner
//
// Created by Jidong Chen on 2018/10/17.
// Copyright © 2018年 The Chromium Authors. All rights reserved.
//
#import "UIViewControllerDemo.h"
#import <Flutter/Flutter.h>
#import "DemoRouter.h"
@interface UIViewControllerDemo ()
@end
@implementation UIViewControllerDemo
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (IBAction)pushFlutterPage:(id)sender {
[DemoRouter.sharedRouter openPage:@"first" params:@{} animated:YES completion:^(BOOL f){}];
}
- (IBAction)present:(id)sender {
[DemoRouter.sharedRouter openPage:@"second" params:@{@"present":@(YES)} animated:YES completion:^(BOOL f){}];
// [self dismissViewControllerAnimated:YES completion:completion];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIViewControllerDemo">
<connections>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Nzh-7M-COj">
<rect key="frame" x="127" y="313.5" width="121" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="WtG-3o-XWQ"/>
<constraint firstAttribute="width" constant="121" id="c57-Gz-XRM"/>
</constraints>
<state key="normal" title="Push Flutter Page"/>
<connections>
<action selector="pushFlutterPage:" destination="-1" eventType="touchUpInside" id="NCF-bc-bsK"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DT7-uk-4YM">
<rect key="frame" x="117.5" y="361" width="140" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="NXI-Pz-Jlx"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="140" id="QqC-Lf-gkn"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="cQZ-3Y-0HG"/>
</constraints>
<state key="normal" title="Present Flutter Page"/>
<connections>
<action selector="present:" destination="-1" eventType="touchUpInside" id="2xc-IT-njo"/>
</connections>
</button>
<textField opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="This a native page" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="bCg-og-n1K">
<rect key="frame" x="121" y="120" width="133" height="17"/>
<color key="textColor" red="1" green="0.034776387922296426" blue="0.45555885506455018" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="Nzh-7M-COj" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="9DT-7L-3xa"/>
<constraint firstItem="bCg-og-n1K" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="9T9-4m-GgT"/>
<constraint firstItem="Nzh-7M-COj" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="D6k-vF-b5G"/>
<constraint firstItem="bCg-og-n1K" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="120" id="G4r-vQ-M9g"/>
<constraint firstItem="DT7-uk-4YM" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="a5O-rA-Z3g"/>
<constraint firstItem="DT7-uk-4YM" firstAttribute="top" secondItem="Nzh-7M-COj" secondAttribute="bottom" constant="7.5" id="rhd-e4-oVP"/>
<constraint firstItem="bCg-og-n1K" firstAttribute="width" secondItem="i5M-Pr-FkT" secondAttribute="height" multiplier="0.2" id="zgc-4g-vU3"/>
</constraints>
<point key="canvasLocation" x="-759.20000000000005" y="143.47826086956522"/>
</view>
</objects>
</document>
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char* argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
{"services":[]}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'simple_page_widgets.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(),
'flutterPage': (pageName, params, _) => FlutterRouteWidget(),
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params),
});
FlutterBoost.handleOnStartPage();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Boost example',
builder: FlutterBoost.init(),
home: Container());
}
}
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
class FirstRouteWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: RaisedButton(
child: Text('Open second route'),
onPressed: () {
FlutterBoost.singleton.openPage("second", {}, animated: true);
},
),
),
);
}
}
class SecondRouteWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
// Navigate back to first route when tapped.
FlutterBoost.singleton.closePageForContext(context);
},
child: Text('Go back!'),
),
),
);
}
}
class TabRouteWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Tab Route"),
),
body: Center(
child: RaisedButton(
onPressed: () {
FlutterBoost.singleton.openPage("second", {}, animated: true);
},
child: Text('Open second route'),
),
),
);
}
}
class FlutterRouteWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutter_boost_example'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 80.0),
child: Text(
"This is a flutter activity",
style: TextStyle(fontSize: 28.0, color: Colors.blue),
),
alignment: AlignmentDirectional.center,
),
Expanded(child: Container()),
InkWell(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
color: Colors.yellow,
child: Text(
'open native page',
style: TextStyle(fontSize: 22.0, color: Colors.black),
)),
onTap: () =>
FlutterBoost.singleton.openPage("sample://nativePage", {}),
),
InkWell(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
color: Colors.yellow,
child: Text(
'open flutter page',
style: TextStyle(fontSize: 22.0, color: Colors.black),
)),
onTap: () =>
FlutterBoost.singleton.openPage("sample://flutterPage", {}),
),
InkWell(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 80.0),
color: Colors.yellow,
child: Text(
'open flutter fragment page',
style: TextStyle(fontSize: 22.0, color: Colors.black),
)),
onTap: () => FlutterBoost.singleton
.openPage("sample://flutterFragmentPage", {}),
)
],
),
);
}
}
class FragmentRouteWidget extends StatelessWidget {
final Map params;
FragmentRouteWidget(this.params);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutter_boost_example'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 80.0),
child: Text(
"This is a flutter fragment",
style: TextStyle(fontSize: 28.0, color: Colors.blue),
),
alignment: AlignmentDirectional.center,
),
Container(
margin: const EdgeInsets.only(top: 32.0),
child: Text(
params['tag'] ?? '',
style: TextStyle(fontSize: 28.0, color: Colors.red),
),
alignment: AlignmentDirectional.center,
),
Expanded(child: Container()),
InkWell(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
color: Colors.yellow,
child: Text(
'open native page',
style: TextStyle(fontSize: 22.0, color: Colors.black),
)),
onTap: () =>
FlutterBoost.singleton.openPage("sample://nativePage", {}),
),
InkWell(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
color: Colors.yellow,
child: Text(
'open flutter page',
style: TextStyle(fontSize: 22.0, color: Colors.black),
)),
onTap: () =>
FlutterBoost.singleton.openPage("sample://flutterPage", {}),
),
InkWell(
child: Container(
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 80.0),
color: Colors.yellow,
child: Text(
'open flutter fragment page',
style: TextStyle(fontSize: 22.0, color: Colors.black),
)),
onTap: () => FlutterBoost.singleton
.openPage("sample://flutterFragmentPage", {}),
)
],
),
);
}
}
name: flutter_boost_example
description: Demonstrates how to use the flutter_boost plugin.
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# Read more about versioning at semver.org.
version: 1.0.0+1
environment:
sdk: ">=2.0.0-dev.68.0 <3.0.0"
dependencies:
xservice_kit: ^0.0.18
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_boost:
path: ../
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.io/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.io/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.io/custom-fonts/#from-packages
// This is a basic Flutter widget test.
// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter
// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to
// find child widgets in the widget tree, read text, and verify that the values of widget properties
// are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../lib/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(new MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) =>
widget is Text && widget.data.startsWith('Running on:'),
),
findsOneWidget);
});
}
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/build" />
<excludeFolder url="file://$MODULE_DIR$/example/ios/Flutter/flutter_assets/packages" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="GEN_FOLDER_RELATIVE_PATH_APT" value="/android/gen" />
<option name="GEN_FOLDER_RELATIVE_PATH_AIDL" value="/android/gen" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/android/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/android/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/android/assets" />
<option name="LIBS_FOLDER_RELATIVE_PATH" value="/android/libs" />
<option name="PROGUARD_LOGS_FOLDER_RELATIVE_PATH" value="/android/proguard_logs" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$/android">
<sourceFolder url="file://$MODULE_DIR$/android/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/android/gen" isTestSource="false" generated="true" />
</content>
<content url="file://$MODULE_DIR$/example/android">
<sourceFolder url="file://$MODULE_DIR$/example/android/app/src/main/java" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Flutter for Android" level="project" />
</component>
</module>
\ No newline at end of file
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "FLBFlutterViewProvider.h"
NS_ASSUME_NONNULL_BEGIN
#if RELEASE_1_0
@interface FLBFlutterEngine : NSObject<FLBFlutterViewProvider>
@end
#endif
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBFlutterEngine.h"
#import <Flutter/Flutter.h>
#import "FLBFlutterViewControllerAdaptor.h"
#if RELEASE_1_0
@interface FLBFlutterEngine()
@property (nonatomic,strong) FLBFlutterViewControllerAdaptor *viewController;
@property (nonatomic,strong) FlutterEngine *engine;
@end
@implementation FLBFlutterEngine
- (instancetype)init
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
if (self = [super init]) {
_engine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:nil];
[_engine runWithEntrypoint:nil];
_viewController = [[FLBFlutterViewControllerAdaptor alloc] initWithEngine:_engine
nibName:nil
bundle:nil];
[_viewController view];
Class clazz = NSClassFromString(@"GeneratedPluginRegistrant");
if (clazz) {
if ([clazz respondsToSelector:NSSelectorFromString(@"registerWithRegistry:")]) {
[clazz performSelector:NSSelectorFromString(@"registerWithRegistry:")
withObject:_viewController];
}
}
}
return self;
#pragma clang diagnostic pop
}
- (FlutterViewController *)viewController
{
return _viewController;
}
- (void)pause
{
//TODO: [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.paused"];
[self.viewController boost_viewWillDisappear:NO];
[self.viewController boost_viewDidDisappear:NO];
}
- (void)resume
{
//TODO: [[_engine.get() lifecycleChannel] sendMessage:@"AppLifecycleState.resumed"];
[self.viewController boost_viewWillAppear:NO];
[self.viewController boost_viewDidAppear:NO];
}
- (void)inactive
{
[[_engine lifecycleChannel] sendMessage:@"AppLifecycleState.inactive"];
}
@end
#endif
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "FLBFlutterViewProvider.h"
NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterEngineOld : NSObject<FLBFlutterViewProvider>
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBFlutterEngineOld.h"
#import "FLBFlutterViewControllerAdaptor.h"
@interface FLBFlutterEngineOld()
@property (nonatomic,strong) FLBFlutterViewControllerAdaptor *viewController;
@end
@implementation FLBFlutterEngineOld
- (instancetype)init
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
if (self = [super init]) {
_viewController = [FLBFlutterViewControllerAdaptor new];
[_viewController view];
Class clazz = NSClassFromString(@"GeneratedPluginRegistrant");
if (clazz) {
if ([clazz respondsToSelector:NSSelectorFromString(@"registerWithRegistry:")]) {
[clazz performSelector:NSSelectorFromString(@"registerWithRegistry:")
withObject:_viewController];
}
}
}
return self;
#pragma clang diagnostic pop
}
- (FlutterViewController *)viewController
{
return _viewController;
}
- (void)pause
{
[self.viewController boost_viewWillDisappear:NO];
[self.viewController boost_viewDidDisappear:NO];
}
- (void)resume
{
[self.viewController boost_viewWillAppear:NO];
[self.viewController boost_viewDidAppear:NO];
}
- (void)inactive
{
NSString *channel = @"flutter/lifecycle";
NSString *message = @"AppLifecycleState.inactive";
NSData *data = [[FlutterStringCodec sharedInstance] encode:message];
[self.viewController sendOnChannel:channel message:data];
}
- (void)resumeFlutterOnly
{
NSString *channel = @"flutter/lifecycle";
NSString *message = @"AppLifecycleState.resumed";
NSData *data = [[FlutterStringCodec sharedInstance] encode:message];
[self.viewController sendOnChannel:channel message:data];
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterViewControllerAdaptor : FlutterViewController
- (void)boost_viewWillAppear:(BOOL)animated;
- (void)boost_viewDidAppear:(BOOL)animated;
- (void)boost_viewWillDisappear:(BOOL)animated;
- (void)boost_viewDidDisappear:(BOOL)animated;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBFlutterViewControllerAdaptor.h"
@interface FLBFlutterViewControllerAdaptor ()
@end
@implementation FLBFlutterViewControllerAdaptor
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// Do any additional setup after loading the view.
}
- (void)viewWillAppear:(BOOL)animated
{
//Left blank intentionally.
}
- (void)viewDidAppear:(BOOL)animated
{
//Left blank intentionally.
}
- (void)viewWillDisappear:(BOOL)animated
{
[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
//miss super call intentionally.
}
- (void)viewDidDisappear:(BOOL)animated
{
//Miss super call intentionally.
[[[UIApplication sharedApplication] keyWindow] endEditing:YES];
}
- (void)boost_viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)boost_viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)boost_viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)boost_viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (UIEdgeInsets)paddingEdgeInsets{
UIEdgeInsets edgeInsets = UIEdgeInsetsZero;
if (@available(iOS 11, *)) {
edgeInsets = UIEdgeInsetsMake(0, self.view.safeAreaInsets.left, self.view.safeAreaInsets.bottom, self.view.safeAreaInsets.right);
} else {
edgeInsets = UIEdgeInsetsZero;
}
return edgeInsets;
}
- (void)installSplashScreenViewIfNecessary {
//Override this to avoid unnecessary splash Screen.
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
@class FlutterViewController;
NS_ASSUME_NONNULL_BEGIN
#define RELEASE_1_0 0
@protocol FLBFlutterViewProvider <NSObject>
@required
- (FlutterViewController *)viewController;
- (void)pause;
- (void)resume;
- (void)inactive;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "FLBFlutterViewProvider.h"
NS_ASSUME_NONNULL_BEGIN
@interface FLBViewProviderFactory : NSObject
- (id<FLBFlutterViewProvider>)createViewProvider;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBViewProviderFactory.h"
#import "FLBFlutterEngine.h"
#import "FLBFlutterEngineOld.h"
@implementation FLBViewProviderFactory
- (id<FLBFlutterViewProvider>)createViewProvider
{
#if RELEASE_1_0
return [FLBFlutterEngine new];
#else
return [FLBFlutterEngineOld new];
#endif
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterAppDelegate : FlutterAppDelegate
// Returns the key window's rootViewController, if it's a FlutterViewController.
// Otherwise, returns nil.
- (FlutterViewController*)rootFlutterViewController;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBFlutterAppDelegate.h"
#import "FLBFlutterApplication.h"
@implementation FLBFlutterAppDelegate
// Returns the key window's rootViewController, if it's a FlutterViewController.
// Otherwise, returns nil.
- (FlutterViewController*)rootFlutterViewController {
return FLBFlutterApplication.sharedApplication.flutterViewController;
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
#import "FLBPlatform.h"
#import "FlutterBoost.h"
NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterApplication : NSObject
@property (nonatomic,strong) id<FLBPlatform> platform;
#pragma mark - Getters
+ (FLBFlutterApplication *)sharedApplication;
- (void)startFlutterWithPlatform:(id<FLBPlatform>)platform
onStart:(void (^)(FlutterViewController *))callback;
- (FlutterViewController *)flutterViewController;
#pragma mark - Container Management
- (BOOL)contains:(FLBFlutterViewContainer *)vc;
- (void)addUniqueViewController:(FLBFlutterViewContainer *)vc;
- (void)removeViewController:(FLBFlutterViewContainer *)vc;
- (BOOL)isTop:(NSString *)pageId;
#pragma mark - App Control
- (void)pause;
- (void)resume;
- (void)inactive;
- (BOOL)isRunning;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBFlutterApplication.h"
#import "FlutterBoost.h"
#import "FLBFlutterViewContainerManager.h"
#import "FLBViewProviderFactory.h"
@interface FLBFlutterApplication()
@property (nonatomic,strong) FLBFlutterViewContainerManager *manager;
@property (nonatomic,strong) id<FLBFlutterViewProvider> viewProvider;
@property (nonatomic,strong) NSMutableDictionary *pageBuilders;
@property (nonatomic,copy) FLBPageBuilder defaultPageBuilder;
@property (nonatomic,assign) BOOL isRendering;
@property (nonatomic,assign) BOOL isRunning;
@end
@implementation FLBFlutterApplication
+ (FLBFlutterApplication *)sharedApplication
{
static FLBFlutterApplication *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [self new];
});
return instance;
}
- (BOOL)isRunning
{
return _isRunning;
}
- (void)startFlutterWithPlatform:(id<FLBPlatform>)platform
onStart:(void (^)(FlutterViewController * _Nonnull))callback
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
self.platform = platform;
self.viewProvider = [[FLBViewProviderFactory new] createViewProvider];
[self.viewProvider resume];
self.isRendering = YES;
self.isRunning = YES;
if(callback) callback(self.viewProvider.viewController);
});
}
- (instancetype)init
{
if (self = [super init]) {
_manager = [FLBFlutterViewContainerManager new];
_pageBuilders = [NSMutableDictionary new];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (UIView *)flutterView
{
return [self flutterViewController].view;
}
- (FlutterViewController *)flutterViewController
{
return self.viewProvider.viewController;
}
- (BOOL)contains:(FLBFlutterViewContainer *)vc
{
return [_manager contains:vc];
}
- (void)addUniqueViewController:(FLBFlutterViewContainer *)vc
{
return [_manager addUnique:vc];
}
- (void)removeViewController:(FLBFlutterViewContainer *)vc
{
return [_manager remove:vc];
}
- (BOOL)isTop:(NSString *)pageId
{
return [_manager.peak isEqual:pageId];
}
- (void)pause
{
if(!_isRendering) return;
[self.viewProvider pause];
_isRendering = NO;
}
- (void)resume
{
if(_isRendering) return;
[self.viewProvider resume];
_isRendering = YES;
}
- (void)inactive
{
[self.viewProvider inactive];
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol FLBPlatform <NSObject>
@required
- (void)openPage:(NSString *)name
params:(NSDictionary *)params
animated:(BOOL)animated
completion:(void (^)(BOOL finished))completion;
- (void)closePage:(NSString *)uid
animated:(BOOL)animated
params:(NSDictionary *)params
completion:(void (^)(BOOL finished))completion;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^FLBPageResultHandler)(NSString *, NSDictionary *);
@interface FLBResultMediator : NSObject
- (void)onResultForKey:(NSString *)vcId resultData:(NSDictionary *)resultData;
- (void)setResultHandler:(FLBPageResultHandler)handler forKey:(NSString *)vcid;
- (void)removeHandlerForKey:(NSString *)vcid;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBResultMediator.h"
@interface FLBResultMediator()
@property (nonatomic,strong) NSMutableDictionary *handlers;
@end
@implementation FLBResultMediator
- (instancetype)init
{
if (self = [super init]) {
_handlers = [NSMutableDictionary new];
}
return self;
}
- (void)onResultForKey:(NSString *)vcId
resultData:(NSDictionary *)resultData
{
if(!vcId) return;
NSString *key = vcId;
if(_handlers[key]){
FLBPageResultHandler handler = _handlers[key];
handler(key,resultData);
[_handlers removeObjectForKey: key];
}
}
- (void)setResultHandler:(FLBPageResultHandler)handler
forKey:(NSString *)vcid
{
if(!handler || !vcid) return;
_handlers[vcid] = handler;
}
- (void)removeHandlerForKey:(NSString *)vcid
{
if(!vcid) return;
[_handlers removeObjectForKey:vcid];
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FlutterBoost_h
#define FlutterBoost_h
#import "FlutterBoostPlugin.h"
#import "FLBFlutterViewContainer.h"
#import "FLBPlatform.h"
#import "FLBFlutterAppDelegate.h"
#endif /* FlutterBoost_h */
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
NS_ASSUME_NONNULL_BEGIN
@interface FlutterBoostConfig : NSObject
#pragma mark - Store first open page
//There are some cases first page messages could be lost.
//So we store the first page info for later usage.
+ (instancetype)sharedInstance;
@property (nonatomic,copy) NSString *fPagename;
@property (nonatomic,copy) NSString *fPageId;
@property (nonatomic,strong) NSDictionary *fParams;
- (BOOL)firstView;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FlutterBoostConfig.h"
@interface FlutterBoostConfig()
@property (nonatomic,assign) BOOL firstView;
@end
@implementation FlutterBoostConfig
+ (instancetype)sharedInstance
{
static FlutterBoostConfig *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [self new];
instance.firstView = YES;
});
return instance;
}
- (void)setFPageId:(NSString *)fPageId
{
_fPageId = fPageId;
_firstView = NO;
}
- (BOOL)firstView
{
return _firstView;
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Flutter/Flutter.h>
#import "FLBFlutterViewContainer.h"
#import "FLBPlatform.h"
typedef FLBFlutterViewContainer * (^FLBPageBuilder)(NSString *name,NSDictionary *params);
@interface FlutterBoostPlugin : NSObject<FlutterPlugin>
#pragma mark - Initializer
+ (instancetype)sharedInstance;
- (void)startFlutterWithPlatform:(id<FLBPlatform>)platform onStart:(void (^)(FlutterViewController *))callback;
#pragma mark - Some properties.
- (BOOL)isRunning;
- (FlutterViewController *)currentViewController;
#pragma mark - handing vc result.
- (void)onResultForKey:(NSString *)vcId resultData:(NSDictionary *)resultData;
- (void)setResultHandler:(void (^)(NSString *, NSDictionary *))handler forKey:(NSString *)vcid;
- (void)removeHandlerForKey:(NSString *)vcid;
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FlutterBoostPlugin.h"
#import "FLBFlutterApplication.h"
#import "FLBResultMediator.h"
@interface FlutterBoostPlugin()
@property (nonatomic,strong) FLBResultMediator *resultMediator;
@end
@implementation FlutterBoostPlugin
+ (instancetype)sharedInstance
{
static id _instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [self.class new];
});
return _instance;
}
- (instancetype)init
{
if (self = [super init]) {
_resultMediator = [FLBResultMediator new];
}
return self;
}
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:@"flutter_boost"
binaryMessenger:[registrar messenger]];
FlutterBoostPlugin* instance = [self.class sharedInstance];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"getPlatformVersion" isEqualToString:call.method]) {
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
} else {
result(FlutterMethodNotImplemented);
}
}
- (void)startFlutterWithPlatform:(id<FLBPlatform>)platform
onStart:(void (^)(FlutterViewController *))callback;
{
[FLBFlutterApplication.sharedApplication startFlutterWithPlatform:platform
onStart:callback];
}
- (BOOL)isRunning
{
return [FLBFlutterApplication.sharedApplication isRunning];
}
- (FlutterViewController *)currentViewController
{
return [[FLBFlutterApplication sharedApplication] flutterViewController];
}
- (void)onResultForKey:(NSString *)vcId resultData:(NSDictionary *)resultData
{
[_resultMediator onResultForKey:vcId resultData:resultData];
}
- (void)setResultHandler:(void (^)(NSString *, NSDictionary *))handler forKey:(NSString *)vcid
{
[_resultMediator setResultHandler:handler forKey:vcid];
}
- (void)removeHandlerForKey:(NSString *)vcid
{
[_resultMediator removeHandlerForKey:vcid];
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <UIKit/UIKit.h>
#import "FLBViewControllerResultHandler.h"
NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterViewContainer : UIViewController<FLBViewControllerResultHandler>
@property (nonatomic,copy,readonly) NSString *name;
@property (nonatomic,strong,readonly) NSDictionary *params;
@property (nonatomic,copy,readonly) NSString *uniqueIDString;
/*
You must call this one time to set flutter page name
and params.
*/
- (void)setName:(NSString *)name params:(NSDictionary *)params;
- (void)flutterViewDidAppear:(NSDictionary *)params;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBFlutterViewContainer.h"
#import "FLBFlutterApplication.h"
#import "FLBStackCache.h"
#import "FLBStackCacheObjectImg.h"
#import "FLBMemoryInspector.h"
#import "Service_NavigationService.h"
#import "FlutterBoostConfig.h"
#define FLUTTER_VIEW [FLBFlutterApplication sharedApplication].flutterViewController.view
#define FLUTTER_VC [FLBFlutterApplication sharedApplication].flutterViewController
#define FLUTTER_APP [FLBFlutterApplication sharedApplication]
@interface FLBFlutterViewContainer ()
@property (nonatomic,copy,readwrite) NSString *name;
@property (nonatomic,strong,readwrite) NSDictionary *params;
@property (nonatomic,strong) UIImageView *screenShotView;
@property (nonatomic,assign) long long identifier;
@end
@implementation FLBFlutterViewContainer
- (void)setName:(NSString *)name params:(NSDictionary *)params
{
if(!_name && name){
_name = name;
_params = params;
[Service_NavigationService didInitPageContainer:^(NSNumber *r) {}
pageName:name
params:params
uniqueId:[self uniqueIDString]];
}
}
static NSUInteger kInstanceCounter = 0;
+ (NSUInteger)instanceCounter
{
return kInstanceCounter;
}
+ (void)instanceCounterIncrease
{
kInstanceCounter++;
if(kInstanceCounter == 1){
[FLUTTER_APP resume];
}
}
+ (void)instanceCounterDecrease
{
kInstanceCounter--;
if([self.class instanceCounter] == 0){
[[FLBStackCache sharedInstance] clear];
[[FLBFlutterApplication sharedApplication] pause];
}
}
- (NSString *)uniqueIDString
{
return @(_identifier).stringValue;
}
- (instancetype)init
{
if(self = [super init]){
static long long sCounter = 0;
_identifier = sCounter++;
[self.class instanceCounterIncrease];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(flutterViewDidShow:) name:@"flutter_boost_container_showed"
object:nil];
}
return self;
}
- (void)flutterViewDidAppear:(NSDictionary *)params
{
//Notify flutter view appeared.
}
- (void)flutterViewDidShow:(NSNotification *)notification
{
__weak typeof(self) weakSelf = self;
if([notification.object isEqual: self.uniqueIDString]){
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf showFlutterView];
});
}
}
- (void)dealloc
{
[self notifyWillDealloc];
[NSNotificationCenter.defaultCenter removeObserver:self];
}
- (void)notifyWillDealloc
{
[Service_NavigationService willDeallocPageContainer:^(NSNumber *r) {}
pageName:_name params:_params
uniqueId:[self uniqueIDString]];
[[FLBStackCache sharedInstance] remove:self.uniqueIDString];
[[FLBFlutterApplication sharedApplication] removeViewController:self];
[self.class instanceCounterDecrease];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
self.screenShotView = [[UIImageView alloc] initWithFrame:self.view.bounds];
self.screenShotView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.screenShotView];
}
#pragma mark - ScreenShots
- (UIImage *)takeScreenShot
{
CGFloat scale = 1;
switch ([FLBMemoryInspector.sharedInstance currentCondition]) {
case FLBMemoryConditionNormal:
scale = 2;
break;
case FLBMemoryConditionLowMemory:
scale = 1;
break;
case FLBMemoryConditionExtremelyLow:
scale = 0.75;
break;
case FLBMemoryConditionAboutToDie:
return [UIImage new];
break;
case FLBMemoryConditionUnknown:
if([[FLBMemoryInspector sharedInstance] smallMemoryDevice]){
scale = 1;
}else{
scale = 2;
}
break;
}
self.screenShotView.opaque = YES;
CGRect flutterBounds = self.view.bounds;
CGSize snapshotSize = CGSizeMake(flutterBounds.size.width ,
flutterBounds.size.height);
UIGraphicsBeginImageContextWithOptions(snapshotSize, NO, scale);
[self.view drawViewHierarchyInRect:flutterBounds
afterScreenUpdates:NO];
UIImage *snapImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapImage;
}
- (void)saveScreenShot
{
UIImage *snapImage = [self takeScreenShot];
if(snapImage){
FLBStackCacheObjectImg *cImg = [[FLBStackCacheObjectImg alloc] initWithImage:snapImage];
[[FLBStackCache sharedInstance] pushObject:cImg key:self.uniqueIDString];
}
}
- (void)clearCurrentScreenShotImage
{
self.screenShotView.image = nil;
}
- (UIImage *)getSavedScreenShot
{
FLBStackCacheObjectImg *cImg = [[FLBStackCache sharedInstance] objectForKey:self.uniqueIDString];
return [cImg image];
}
- (BOOL)isFlutterViewAttatched
{
return FLUTTER_VIEW.superview == self.view;
}
- (void)attatchFlutterView
{
if([self isFlutterViewAttatched]) return;
[FLUTTER_VC willMoveToParentViewController:nil];
[FLUTTER_VC removeFromParentViewController];
[FLUTTER_VC didMoveToParentViewController:nil];
[FLUTTER_VC willMoveToParentViewController:self];
FLUTTER_VIEW.frame = self.view.bounds;
if(!self.screenShotView.image){
[self.view addSubview: FLUTTER_VIEW];
}else{
[self.view insertSubview:FLUTTER_VIEW belowSubview:self.screenShotView];
}
[self addChildViewController:FLUTTER_VC];
[FLUTTER_VC didMoveToParentViewController:self];
}
- (BOOL)showSnapShotVew
{
self.screenShotView.image = [self getSavedScreenShot];
if([self isFlutterViewAttatched]){
NSUInteger fIdx = [self.view.subviews indexOfObject:FLUTTER_VIEW];
NSUInteger sIdx = [self.view.subviews indexOfObject:self.screenShotView];
if(fIdx > sIdx){
[self.view insertSubview:FLUTTER_VIEW
atIndex:0];
}
}
return self.screenShotView.image != nil;
}
- (void)showFlutterView
{
if(FLUTTER_VIEW.superview != self.view) return;
if([self isFlutterViewAttatched] ){
NSUInteger fIdx = [self.view.subviews indexOfObject:FLUTTER_VIEW];
NSUInteger sIdx = [self.view.subviews indexOfObject:self.screenShotView];
self.screenShotView.backgroundColor = UIColor.clearColor;
if(sIdx > fIdx){
[self.view insertSubview:self.screenShotView belowSubview:FLUTTER_VIEW];
[self flutterViewDidAppear:@{@"uid":self.uniqueIDString?:@""}];
}
}
[self clearCurrentScreenShotImage];
}
#pragma mark - Life circle methods
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[[FLBFlutterApplication sharedApplication] resume];
}
- (void)viewWillAppear:(BOOL)animated
{
[[FLBFlutterApplication sharedApplication] resume];
//For new page we should attach flutter view in view will appear
//for better performance.
if(![[FLBFlutterApplication sharedApplication] contains:self]){
[self attatchFlutterView];
}
[self showSnapShotVew];
[Service_NavigationService willShowPageContainer:^(NSNumber *result) {}
pageName:_name
params:_params
uniqueId:self.uniqueIDString];
//Save some first time page info.
if(![FlutterBoostConfig sharedInstance].fPagename){
[FlutterBoostConfig sharedInstance].fPagename = _name;
[FlutterBoostConfig sharedInstance].fPageId = self.uniqueIDString;
[FlutterBoostConfig sharedInstance].fParams = _params;
}
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[[FLBFlutterApplication sharedApplication] resume];
//Ensure flutter view is attached.
[self attatchFlutterView];
[Service_NavigationService didShowPageContainer:^(NSNumber *result) {}
pageName:_name
params:_params
uniqueId:self.uniqueIDString];
[[FLBFlutterApplication sharedApplication] addUniqueViewController:self];
[super viewDidAppear:animated];
__weak typeof(self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(2 * NSEC_PER_SEC)),
dispatch_get_main_queue(),^{
[weakSelf showFlutterView];
});
}
- (void)viewWillDisappear:(BOOL)animated
{
//is top.
if([FLUTTER_APP isTop:self.uniqueIDString]
&& self.navigationController.interactivePopGestureRecognizer.state != UIGestureRecognizerStateBegan){
[self saveScreenShot];
}
self.screenShotView.image = [self getSavedScreenShot];
if(self.screenShotView.image){
[self.view bringSubviewToFront:self.screenShotView];
}
[Service_NavigationService willDisappearPageContainer:^(NSNumber *result) {}
pageName:_name
params:_params
uniqueId:self.uniqueIDString];
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[Service_NavigationService didDisappearPageContainer:^(NSNumber *result) {}
pageName:_name
params:_params
uniqueId:self.uniqueIDString];
[self clearCurrentScreenShotImage];
[super viewDidDisappear:animated];
[FLUTTER_APP inactive];
}
#pragma mark - FLBViewControllerResultHandler
- (void)onRecievedResult:(NSDictionary *)resultData forKey:(NSString *)key
{
[Service_NavigationService onNativePageResult:^(NSNumber *finished) {}
uniqueId:self.uniqueIDString
key:key
resultData:resultData
params:@{}];
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "FLBFlutterViewContainer.h"
NS_ASSUME_NONNULL_BEGIN
@interface FLBFlutterViewContainerManager : NSObject
- (NSString *)peak;
- (void)addUnique:(FLBFlutterViewContainer *)vc;
- (void)remove:(FLBFlutterViewContainer *)vc;
- (BOOL)contains:(FLBFlutterViewContainer *)vc;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBFlutterViewContainerManager.h"
@interface FLBFlutterViewContainerManager()
@property (nonatomic,strong) NSMutableArray *idStk;
@property (nonatomic,strong) NSMutableDictionary *existedID;
@end
@implementation FLBFlutterViewContainerManager
- (instancetype)init
{
if (self = [super init]) {
_idStk= [NSMutableArray new];
_existedID = [NSMutableDictionary dictionary];
}
return self;
}
- (BOOL)contains:(FLBFlutterViewContainer *)vc
{
if (vc) {
return _existedID[vc.uniqueIDString]?YES:NO;
}
return NO;
}
- (void)addUnique:(FLBFlutterViewContainer *)vc
{
if (vc) {
if(!_existedID[vc.uniqueIDString]){
[_idStk addObject:vc.uniqueIDString];
}
_existedID[vc.uniqueIDString] = vc.uniqueIDString;
}
}
- (void)remove:(FLBFlutterViewContainer *)vc
{
if (vc) {
[_existedID removeObjectForKey:vc.uniqueIDString];
[_idStk removeObject:vc.uniqueIDString];
}
}
- (NSString *)peak
{
return _idStk.lastObject;
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol FLBViewControllerResultHandler <NSObject>
@required
- (void)onRecievedResult:(NSDictionary *)resultData forKey:(NSString *)key;
@end
NS_ASSUME_NONNULL_END
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Generated by AIOCodeGen do not edit!
#import "FlutterServiceCallHandler.h"
@interface NavigationService_closePage : FlutterServiceCallHandler
@end
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
//Generated by AIOCodeGen.
#import "ServiceGateway.h"
#import "NavigationService_closePage.h"
#import "FLBFlutterApplication.h"
@implementation NavigationService_closePage
- (void)onCall:(void (^)(BOOL))result
uniqueId:(NSString *)uniqueId
pageName:(NSString *)pageName
params:(NSDictionary *)params
animated:(NSNumber *)animated
{
//Add your handler code here!
[[FLBFlutterApplication sharedApplication].platform closePage:uniqueId
animated:animated.boolValue
params:params
completion:^(BOOL finished) {
if(result) result(finished);
}];
}
#pragma mark - Do not edit these method.
- (void)__flutter_p_handler_closePage:(NSDictionary *)args result:(void (^)(BOOL))result {
[self onCall:result uniqueId:args[@"uniqueId"] pageName:args[@"pageName"] params:args[@"params"] animated:args[@"animated"]];
}
+ (void)load{
[[ServiceGateway sharedInstance] registerHandler:[NavigationService_closePage new]];
}
- (NSString *)returnType
{
return @"BOOL";
}
- (NSString *)service
{
return @"NavigationService";
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Generated by AIOCodeGen do not edit!
#import "FlutterServiceCallHandler.h"
@interface NavigationService_onFlutterPageResult : FlutterServiceCallHandler
@end
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
//Generated by AIOCodeGen.
#import "ServiceGateway.h"
#import "NavigationService_onFlutterPageResult.h"
#import "FlutterBoost.h"
@implementation NavigationService_onFlutterPageResult
- (void)onCall:(void (^)(BOOL))result uniqueId:(NSString *)uniqueId key:(NSString *)key resultData:(NSDictionary *)resultData params:(NSDictionary *)params
{
//Add your handler code here!
[FlutterBoostPlugin.sharedInstance onResultForKey:key
resultData:resultData];
}
#pragma mark - Do not edit these method.
- (void)__flutter_p_handler_onFlutterPageResult:(NSDictionary *)args result:(void (^)(BOOL))result {
[self onCall:result uniqueId:args[@"uniqueId"] key:args[@"key"] resultData:args[@"resultData"] params:args[@"params"]];
}
+ (void)load{
[[ServiceGateway sharedInstance] registerHandler:[NavigationService_onFlutterPageResult new]];
}
- (NSString *)returnType
{
return @"BOOL";
}
- (NSString *)service
{
return @"NavigationService";
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Generated by AIOCodeGen do not edit!
#import "FlutterServiceCallHandler.h"
@interface NavigationService_onShownContainerChanged : FlutterServiceCallHandler
@end
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
//Generated by AIOCodeGen.
#import "ServiceGateway.h"
#import "NavigationService_onShownContainerChanged.h"
@implementation NavigationService_onShownContainerChanged
- (void)onCall:(void (^)(BOOL))result newName:(NSString *)newName oldName:(NSString *)oldName params:(NSDictionary *)params
{
if(newName){
[NSNotificationCenter.defaultCenter postNotificationName:@"flutter_boost_container_showed"
object:newName];
}
}
#pragma mark - Do not edit these method.
- (void)__flutter_p_handler_onShownContainerChanged:(NSDictionary *)args result:(void (^)(BOOL))result {
[self onCall:result newName:args[@"newName"] oldName:args[@"oldName"] params:args[@"params"]];
}
+ (void)load{
[[ServiceGateway sharedInstance] registerHandler:[NavigationService_onShownContainerChanged new]];
}
- (NSString *)returnType
{
return @"BOOL";
}
- (NSString *)service
{
return @"NavigationService";
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Generated by AIOCodeGen do not edit!
#import "FlutterServiceCallHandler.h"
@interface NavigationService_openPage : FlutterServiceCallHandler
@end
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
//Generated by AIOCodeGen.
#import "ServiceGateway.h"
#import "NavigationService_openPage.h"
#import "FLBFlutterApplication.h"
#import "FlutterBoost.h"
#import "Service_NavigationService.h"
@implementation NavigationService_openPage
- (void)onCall:(void (^)(BOOL))result pageName:(NSString *)pageName params:(NSDictionary *)params animated:(NSNumber *)animated
{
NSString *url = pageName;
if(pageName == nil){
pageName = params[@"url"];
}
if([self needResult:params]){
[FlutterBoostPlugin.sharedInstance setResultHandler:^(NSString *key , NSDictionary *resultData) {
[Service_NavigationService onNativePageResult:^(NSNumber *) {}
uniqueId:@"no use"
key:url
resultData:resultData
params:@{}];
} forKey:url];
}
[[FLBFlutterApplication sharedApplication].platform openPage:pageName
params:params
animated:animated.boolValue
completion:^(BOOL finished) {
if(result)result(YES);
}];
}
- (BOOL)needResult:(NSDictionary *)params
{
NSString *const key = @"needResult";
NSNumber *val = params[key];
if (val && [val isKindOfClass:NSNumber.class]) {
return val.boolValue;
}
return NO;
}
#pragma mark - Do not edit these method.
- (void)__flutter_p_handler_openPage:(NSDictionary *)args result:(void (^)(BOOL))result {
[self onCall:result pageName:args[@"pageName"] params:args[@"params"] animated:args[@"animated"]];
}
+ (void)load{
[[ServiceGateway sharedInstance] registerHandler:[NavigationService_openPage new]];
}
- (NSString *)returnType
{
return @"BOOL";
}
- (NSString *)service
{
return @"NavigationService";
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// Generated by AIOCodeGen do not edit!
#import "FlutterServiceCallHandler.h"
@interface NavigationService_pageOnStart : FlutterServiceCallHandler
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
//Generated by AIOCodeGen.
#import "ServiceGateway.h"
#import "NavigationService_pageOnStart.h"
#import "FLBFlutterApplication.h"
#import "FlutterBoostConfig.h"
@implementation NavigationService_pageOnStart
- (void)onCall:(void (^)(NSDictionary *))result params:(NSDictionary *)params
{
NSMutableDictionary *pageInfo = [NSMutableDictionary new];
pageInfo[@"name"] =[FlutterBoostConfig sharedInstance].fPagename;
pageInfo[@"params"] = [FlutterBoostConfig sharedInstance].fParams;
pageInfo[@"uniqueId"] = [FlutterBoostConfig sharedInstance].fPageId;
if(result) result(pageInfo);
}
#pragma mark - Do not edit these method.
- (void)__flutter_p_handler_pageOnStart:(NSDictionary *)args result:(void (^)(NSDictionary *))result {
[self onCall:result params:args[@"params"]];
}
+ (void)load{
[[ServiceGateway sharedInstance] registerHandler:[NavigationService_pageOnStart new]];
}
- (NSString *)returnType
{
return @"NSDictionary *";
}
- (NSString *)service
{
return @"NavigationService";
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
//Generated by AIOCodeGen do not edit!
#import "FlutterServiceTemplate.h"
@interface Service_NavigationService : NSObject
+ (FlutterServiceTemplate *)service;
+ (void)onNativePageResult:(void (^)(NSNumber *))result uniqueId:(NSString *)uniqueId key:(NSString *)key resultData:(NSDictionary *)resultData params:(NSDictionary *)params;
+ (void)didShowPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId;
+ (void)willShowPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId;
+ (void)willDisappearPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId;
+ (void)didDisappearPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId;
+ (void)didInitPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId;
+ (void)willDeallocPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId;
@end
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
//Generated by AIOCodeGen. Do not edit!
#import "Service_NavigationService.h"
#import "ServiceGateway.h"
#import "FlutterServiceTemplate.h"
@implementation Service_NavigationService
+ (FlutterServiceTemplate *)service
{
static id _instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[FlutterServiceTemplate alloc] initWithName:@"NavigationService"];
});
return _instance;
}
+ (void)load{
[[ServiceGateway sharedInstance] addService:[self service]];
}
+ (void)onNativePageResult:(void (^)(NSNumber *))result uniqueId:(NSString *)uniqueId key:(NSString *)key resultData:(NSDictionary *)resultData params:(NSDictionary *)params
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
if(uniqueId) tmp[@"uniqueId"] = uniqueId;
if(key) tmp[@"key"] = key;
if(resultData) tmp[@"resultData"] = resultData;
if(params) tmp[@"params"] = params;
[self.service invoke:@"onNativePageResult" args:tmp result:^(id tTesult) {
if (result) {
result(tTesult);
}
}];
}
+ (void)didShowPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
if(pageName) tmp[@"pageName"] = pageName;
if(params) tmp[@"params"] = params;
if(uniqueId) tmp[@"uniqueId"] = uniqueId;
[self.service invoke:@"didShowPageContainer" args:tmp result:^(id tTesult) {
if (result) {
result(tTesult);
}
}];
}
+ (void)willShowPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
if(pageName) tmp[@"pageName"] = pageName;
if(params) tmp[@"params"] = params;
if(uniqueId) tmp[@"uniqueId"] = uniqueId;
[self.service invoke:@"willShowPageContainer" args:tmp result:^(id tTesult) {
if (result) {
result(tTesult);
}
}];
}
+ (void)willDisappearPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
if(pageName) tmp[@"pageName"] = pageName;
if(params) tmp[@"params"] = params;
if(uniqueId) tmp[@"uniqueId"] = uniqueId;
[self.service invoke:@"willDisappearPageContainer" args:tmp result:^(id tTesult) {
if (result) {
result(tTesult);
}
}];
}
+ (void)didDisappearPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
if(pageName) tmp[@"pageName"] = pageName;
if(params) tmp[@"params"] = params;
if(uniqueId) tmp[@"uniqueId"] = uniqueId;
[self.service invoke:@"didDisappearPageContainer" args:tmp result:^(id tTesult) {
if (result) {
result(tTesult);
}
}];
}
+ (void)didInitPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
if(pageName) tmp[@"pageName"] = pageName;
if(params) tmp[@"params"] = params;
if(uniqueId) tmp[@"uniqueId"] = uniqueId;
[self.service invoke:@"didInitPageContainer" args:tmp result:^(id tTesult) {
if (result) {
result(tTesult);
}
}];
}
+ (void)willDeallocPageContainer:(void (^)(NSNumber *))result pageName:(NSString *)pageName params:(NSDictionary *)params uniqueId:(NSString *)uniqueId
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
if(pageName) tmp[@"pageName"] = pageName;
if(params) tmp[@"params"] = params;
if(uniqueId) tmp[@"uniqueId"] = uniqueId;
[self.service invoke:@"willDeallocPageContainer" args:tmp result:^(id tTesult) {
if (result) {
result(tTesult);
}
}];
}
@end
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
@class FLBStackCache;
@protocol FLBStackCacheObject<NSObject>
@required
@property (nonatomic,copy) NSString *key;
- (BOOL)writeToFileWithKey:(NSString *)key
queue:(dispatch_queue_t)queue
cache:(FLBStackCache *)cache
completion:(void (^)(NSError *err,NSString *path))completion;
+ (BOOL)loadFromFileWithKey:(NSString *)key
queue:(dispatch_queue_t)queue
cache:(FLBStackCache *)cache
completion:(void (^)(NSError *err ,id<FLBStackCacheObject>))completion;
@end
@interface FLBStackCache : NSObject
+ (instancetype)sharedInstance;
/**
* Num of objects allowed in memory.
* Default value is set to 2.
*/
@property (nonatomic,assign) NSUInteger inMemoryCount;
#pragma mark - basic operations.
- (void)pushObject:(id<FLBStackCacheObject>)obj key:(NSString *)key;
- (id<FLBStackCacheObject>)remove:(NSString *)key;
- (BOOL)empty;
- (void)clear;
- (id<FLBStackCacheObject>)objectForKey:(NSString *)key;
#pragma mark - Disk thing.
- (NSString *)cacheDir;
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBStackCache.h"
@interface FLBStackCache()
@property (nonatomic,strong) NSMutableArray *keyStack;
@property (nonatomic,strong) NSMutableDictionary *typesMap;
@property (nonatomic,strong) NSMutableDictionary *inMemoryObjectsMap;
@property (nonatomic,strong) NSMutableDictionary *loadinMap;
@property (nonatomic,strong) dispatch_queue_t queueIO;
@end
@implementation FLBStackCache
+ (instancetype)sharedInstance
{
static id sInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sInstance = [self.class new];
});
return sInstance;
}
- (BOOL)empty
{
return _keyStack.count<=0;
}
- (void)clear
{
[self.keyStack removeAllObjects];
[self.inMemoryObjectsMap removeAllObjects];
[self.typesMap removeAllObjects];
NSError *err = nil;
[[NSFileManager defaultManager] removeItemAtPath:self.cacheDir error:&err];
if (err) {
NSLog(@"fail to remove cache dir %@",err);
}
}
- (instancetype)init
{
if (self = [super init]) {
_keyStack = [NSMutableArray new];
_inMemoryObjectsMap = [NSMutableDictionary new];
_loadinMap = [NSMutableDictionary new];
_typesMap = [NSMutableDictionary new];
_queueIO = dispatch_queue_create("Stack cache working queue", NULL);
}
_inMemoryCount = 2;
return self;
}
- (void)pushObject:(id<FLBStackCacheObject>)obj
key:(NSString *)key
{
if (!obj || key.length <= 0) {
return;
}
if(!_inMemoryObjectsMap[key]){
[_keyStack addObject:key];
}else{
//return;
}
obj.key = key;
_typesMap[key] = obj.class;
_inMemoryObjectsMap[key] = obj;
for(NSUInteger i = _keyStack.count - _inMemoryObjectsMap.count ;
i < _keyStack.count && _inMemoryObjectsMap.count > _inMemoryCount;
i++){
NSString *keyToSave = _keyStack[i];
if(_inMemoryObjectsMap[keyToSave]){
id<FLBStackCacheObject> ob = _inMemoryObjectsMap[keyToSave];
[_inMemoryObjectsMap removeObjectForKey:keyToSave];
[ob writeToFileWithKey:keyToSave
queue:_queueIO
cache:self
completion:^(NSError *err, NSString *path) {
if (err) {
NSLog(@"Caching object to file failed!");
}
}];
}
}
}
- (id<FLBStackCacheObject>)objectForKey:(NSString *)key
{
return _inMemoryObjectsMap[key];
}
- (id<FLBStackCacheObject>)remove:(NSString *)key
{
if([self empty]) return nil;
if(![_keyStack containsObject:key]) return nil;
id ob = _inMemoryObjectsMap[key];
[_keyStack removeObject:key];
[_inMemoryObjectsMap removeObjectForKey:key];
[_typesMap removeObjectForKey:key];
[self preloadIfNeeded];
return ob;
}
- (void)preloadIfNeeded
{
for(NSString *key in self.keyStack.reverseObjectEnumerator){
Class typeClass = _typesMap[key];
id cache = _inMemoryObjectsMap[key];
if(typeClass && !cache && [typeClass conformsToProtocol: @protocol(FLBStackCacheObject)]){
_loadinMap[key] = @(YES);
[typeClass loadFromFileWithKey:key
queue:_queueIO
cache:self
completion:^(NSError *err ,id<FLBStackCacheObject> ob){
[self.loadinMap removeObjectForKey:key];
if (ob && !err) {
if(self.typesMap[key]){
self.inMemoryObjectsMap[key] = ob;
}
}else{
NSLog(@"preload object from file failed!");
}
}];
}
if(_inMemoryObjectsMap.count + _loadinMap.count >= _inMemoryCount){
break;
}
}
}
- (NSString *)cacheDir
{
static NSString *cachePath = nil;
if (!cachePath) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
cachePath = [cacheDirectory stringByAppendingPathComponent:@"FlutterScreenshots"];
}
BOOL dir = NO;
if(![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&dir]){
NSError *eror = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:cachePath
withIntermediateDirectories:YES
attributes:nil
error:&eror];
if (eror) {
NSLog(@"%@",eror);
}
}
return cachePath;
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "FLBStackCache.h"
@interface FLBStackCacheObjectImg : NSObject<FLBStackCacheObject>
@property (nonatomic,copy) NSString *key;
- (instancetype)initWithImage:(UIImage *)image;
- (UIImage *)image;
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBStackCacheObjectImg.h"
@interface FLBStackCacheObjectImg()
@property (nonatomic,strong) UIImage *image;
@end
@implementation FLBStackCacheObjectImg
- (instancetype)initWithImage:(UIImage *)image
{
if (self = [super init]) {
_image = image;
}
return self;
}
+ (BOOL)loadFromFileWithKey:(NSString *)key
queue:(dispatch_queue_t)queue
cache:(FLBStackCache *)cache
completion:(void (^)(NSError *, id<FLBStackCacheObject>))completion
{
dispatch_async(queue, ^{
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[self filePathByKey:key dirPath:cache.cacheDir]];
if (completion) {
if (image) {
FLBStackCacheObjectImg *ob = [[FLBStackCacheObjectImg alloc] initWithImage:image];
ob.key = key;
completion(nil,ob);
}else{
completion([NSError new],nil);
}
}
});
return YES;
}
+ (NSString *)filePathByKey:(NSString *)key dirPath:(NSString *)cacheDir
{
key = [key stringByReplacingOccurrencesOfString:@"/" withString:@""];
key = [key stringByReplacingOccurrencesOfString:@":" withString:@""];
NSString *path = [cacheDir stringByAppendingPathComponent:key];
return path;
}
- (BOOL)writeToFileWithKey:(NSString *)key
queue:(dispatch_queue_t)queue
cache:(FLBStackCache *)cache
completion:(void (^)(NSError *, NSString *))completion
{
if(!_image){
return NO;
}
dispatch_async(queue, ^{
NSData *imgData = UIImagePNGRepresentation(self.image);
NSString *filePath = [FLBStackCacheObjectImg filePathByKey:key dirPath:cache.cacheDir];
[imgData writeToFile:filePath atomically:YES];
if (completion) {
completion(nil,key);
}
});
return YES;
}
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#define kFLBMemoryInspectorChangedNotification @"__FlutterMemoryInspectorChangedNotification__"
#define kFLBMemoryInspectorKeyCondition @"condition"
typedef NS_ENUM(NSUInteger,FLBMemoryCondition) {
FLBMemoryConditionUnknown,
FLBMemoryConditionNormal,
FLBMemoryConditionLowMemory,
FLBMemoryConditionExtremelyLow,
FLBMemoryConditionAboutToDie
};
@interface FLBMemoryInspector : NSObject
+ (instancetype)sharedInstance;
- (FLBMemoryCondition)currentCondition;
- (int64_t)currentFootPrint;
- (int64_t)deviceMemory;
- (BOOL)smallMemoryDevice;
@end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#import "FLBMemoryInspector.h"
#include <mach/mach.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#define MB(_v_) (_v_*1024*1024)
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
@interface FLBMemoryInspector()
@property(nonatomic,assign) FLBMemoryCondition condition;
@end
@implementation FLBMemoryInspector
+ (instancetype)sharedInstance
{
static id sInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sInstance = [[self.class alloc] init];
});
return sInstance;
}
static bool isHighterThanIos9(){
bool ret = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0.0");
return ret;
}
static int64_t memoryFootprint()
{
task_vm_info_data_t vmInfo;
mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
kern_return_t result = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
if (result != KERN_SUCCESS)
return -1;
return vmInfo.phys_footprint;
}
static int64_t _memoryWarningLimit()
{
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine =(char *) malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithUTF8String:machine];
free(machine);
if ([platform isEqualToString:@"iPhone5,1"]) return MB(600);
if ([platform isEqualToString:@"iPhone5,2"]) return MB(600);
if ([platform isEqualToString:@"iPhone5,3"]) return MB(600);
if ([platform isEqualToString:@"iPhone5,4"]) return MB(600);
if ([platform isEqualToString:@"iPhone6,1"]) return MB(600);
if ([platform isEqualToString:@"iPhone6,2"]) return MB(600);
if ([platform isEqualToString:@"iPhone7,1"]) return MB(600);
if ([platform isEqualToString:@"iPhone7,2"]) return MB(600);
if ([platform isEqualToString:@"iPhone8,1"]) return MB(1280);
if ([platform isEqualToString:@"iPhone8,2"]) return MB(1280);
if ([platform isEqualToString:@"iPhone8,4"]) return MB(1280);
if ([platform isEqualToString:@"iPhone9,1"]) return MB(1280);
if ([platform isEqualToString:@"iPhone9,2"]) return MB(1950);
if ([platform isEqualToString:@"iPhone9,3"]) return MB(1280);
if ([platform isEqualToString:@"iPhone9,4"]) return MB(1950);
if ([platform isEqualToString:@"iPhone10,1"]) return MB(1280);
if ([platform isEqualToString:@"iPhone10,2"]) return MB(1950);
if ([platform isEqualToString:@"iPhone10,3"]) return MB(1950);
if ([platform isEqualToString:@"iPhone10,4"]) return MB(1280);
if ([platform isEqualToString:@"iPhone10,5"]) return MB(1950);
if ([platform isEqualToString:@"iPhone10,6"]) return MB(1950);
return 0;
}
static int64_t getLimit(){
const static size_t l = _memoryWarningLimit();
return l;
}
- (int64_t)deviceMemory
{
int64_t size = [NSProcessInfo processInfo].physicalMemory;
return size;
}
- (BOOL)smallMemoryDevice
{
if([self deviceMemory] <= MB(1024)){
return YES;
}else{
return NO;
}
}
- (FLBMemoryCondition)currentCondition
{
FLBMemoryCondition newCondition = FLBMemoryConditionUnknown;
if(!isHighterThanIos9() || getLimit() <= 0){
newCondition = FLBMemoryConditionUnknown;
}else if(memoryFootprint() < getLimit() * 0.40){
newCondition = FLBMemoryConditionNormal;
}else if(memoryFootprint() < getLimit() * 0.60){
newCondition = FLBMemoryConditionLowMemory;
}else if(memoryFootprint() < getLimit() * 0.80){
newCondition = FLBMemoryConditionExtremelyLow;
}else{
newCondition = FLBMemoryConditionAboutToDie;
}
if (newCondition != self.condition) {
[[NSNotificationCenter defaultCenter] postNotificationName:kFLBMemoryInspectorChangedNotification
object:@{kFLBMemoryInspectorKeyCondition:@(newCondition)}];
}
self.condition = newCondition;
return newCondition;
}
- (int64_t)currentFootPrint
{
return memoryFootprint();
}
@end
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'flutter_boost'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin make flutter better to use!'
s.description = <<-DESC
A new Flutter plugin make flutter better to use!
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Alibaba Xianyu' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*.{h,m,mm}'
s.public_header_files =
'Classes/Boost/FlutterBoost.h',
'Classes/Boost/FlutterBoostPlugin.h',
'Classes/Boost/FLBPlatform.h',
'Classes/Boost/FLBFlutterAppDelegate.h',
'Classes/Container/FLBFlutterViewContainer.h',
'Classes/Container/FLBViewControllerResultHandler.h'
s.dependency 'Flutter'
s.dependency 'xservice_kit'
s.ios.deployment_target = '8.0'
end
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:xservice_kit/ServiceCallHandler.dart';
import 'package:xservice_kit/ServiceGateway.dart';
class NavigationService_didDisappearPageContainer extends ServiceCallHandler {
static void regsiter() {
ServiceGateway.sharedInstance()
.registerHandler(new NavigationService_didDisappearPageContainer());
}
@override
String name() {
return "didDisappearPageContainer";
}
@override
String service() {
return "NavigationService";
}
@override
Future<bool> onMethodCall(MethodCall call) {
return onCall(call.arguments["pageName"], call.arguments["params"],
call.arguments["uniqueId"]);
}
//==============================================Do not edit code above!
Future<bool> onCall(String pageName, Map params, String uniqueId) async {
return ContainerCoordinator.singleton
.nativeContainerDidDisappear(pageName, params, uniqueId);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:xservice_kit/ServiceCallHandler.dart';
import 'package:xservice_kit/ServiceGateway.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
class NavigationService_didInitPageContainer extends ServiceCallHandler {
static void regsiter() {
ServiceGateway.sharedInstance()
.registerHandler(new NavigationService_didInitPageContainer());
}
@override
String name() {
return "didInitPageContainer";
}
@override
String service() {
return "NavigationService";
}
@override
Future<bool> onMethodCall(MethodCall call) {
return onCall(call.arguments["pageName"], call.arguments["params"],
call.arguments["uniqueId"]);
}
//==============================================Do not edit code above!
Future<bool> onCall(String pageName, Map params, String uniqueId) async {
return ContainerCoordinator.singleton
.nativeContainerDidInit(pageName, params, uniqueId);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:xservice_kit/ServiceCallHandler.dart';
import 'package:xservice_kit/ServiceGateway.dart';
class NavigationService_didShowPageContainer extends ServiceCallHandler {
static void regsiter() {
ServiceGateway.sharedInstance()
.registerHandler(new NavigationService_didShowPageContainer());
}
@override
String name() {
return "didShowPageContainer";
}
@override
String service() {
return "NavigationService";
}
@override
Future<bool> onMethodCall(MethodCall call) {
return onCall(call.arguments["pageName"], call.arguments["params"],
call.arguments["uniqueId"]);
}
//==============================================Do not edit code above!
Future<bool> onCall(String pageName, Map params, String uniqueId) async {
return ContainerCoordinator.singleton
.nativeContainerDidShow(pageName, params, uniqueId);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:xservice_kit/ServiceCallHandler.dart';
import 'package:xservice_kit/ServiceGateway.dart';
import 'package:flutter_boost/flutter_boost.dart';
class NavigationService_onNativePageResult extends ServiceCallHandler {
static void regsiter() {
ServiceGateway.sharedInstance().registerHandler(new NavigationService_onNativePageResult());
}
@override
String name() {
return "onNativePageResult";
}
@override
String service() {
return "NavigationService";
}
@override
Future<bool> onMethodCall(MethodCall call) {
return onCall(call.arguments["uniqueId"],call.arguments["key"],call.arguments["resultData"],call.arguments["params"]);
}
//==============================================Do not edit code above!
Future<bool> onCall(String uniqueId,String key,Map resultData,Map params) async{
return FlutterBoost.singleton.onPageResult(key, resultData);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:xservice_kit/ServiceCallHandler.dart';
import 'package:xservice_kit/ServiceGateway.dart';
class NavigationService_willDeallocPageContainer extends ServiceCallHandler {
static void regsiter() {
ServiceGateway.sharedInstance()
.registerHandler(new NavigationService_willDeallocPageContainer());
}
@override
String name() {
return "willDeallocPageContainer";
}
@override
String service() {
return "NavigationService";
}
@override
Future<bool> onMethodCall(MethodCall call) {
return onCall(call.arguments["pageName"], call.arguments["params"],
call.arguments["uniqueId"]);
}
//==============================================Do not edit code above!
Future<bool> onCall(String pageName, Map params, String uniqueId) async {
return ContainerCoordinator.singleton
.nativeContainerWillDealloc(pageName, params, uniqueId);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:xservice_kit/ServiceCallHandler.dart';
import 'package:xservice_kit/ServiceGateway.dart';
class NavigationService_willDisappearPageContainer extends ServiceCallHandler {
static void regsiter() {
ServiceGateway.sharedInstance()
.registerHandler(new NavigationService_willDisappearPageContainer());
}
@override
String name() {
return "willDisappearPageContainer";
}
@override
String service() {
return "NavigationService";
}
@override
Future<bool> onMethodCall(MethodCall call) {
return onCall(call.arguments["pageName"], call.arguments["params"],
call.arguments["uniqueId"]);
}
//==============================================Do not edit code above!
Future<bool> onCall(String pageName, Map params, String uniqueId) async {
return ContainerCoordinator.singleton
.nativeContainerWillDisappear(pageName, params, uniqueId);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:xservice_kit/ServiceCallHandler.dart';
import 'package:xservice_kit/ServiceGateway.dart';
class NavigationService_willShowPageContainer extends ServiceCallHandler {
static void regsiter() {
ServiceGateway.sharedInstance()
.registerHandler(new NavigationService_willShowPageContainer());
}
@override
String name() {
return "willShowPageContainer";
}
@override
String service() {
return "NavigationService";
}
@override
Future<bool> onMethodCall(MethodCall call) {
return onCall(call.arguments["pageName"], call.arguments["params"],
call.arguments["uniqueId"]);
}
//==============================================Do not edit code above!
Future<bool> onCall(String pageName, Map params, String uniqueId) async {
return ContainerCoordinator.singleton
.nativeContainerWillShow(pageName, params, uniqueId);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:xservice_kit/foundation_ext/foundation_ext.dart';
import 'package:xservice_kit/ServiceTemplate.dart';
import 'package:xservice_kit/ServiceGateway.dart';
class NavigationService {
static final ServiceTemplate _service =
new ServiceTemplate("NavigationService");
static void regsiter() {
ServiceGateway.sharedInstance().registerService(_service);
}
//List event from event channel.
static int listenEvent(void onData(dynamic event)) {
return _service.listenEvent(onData);
}
//Cancel event for subscription with ID.
static void cancelEventForSubscription(int subID) {
_service.cancelEventForSubscription(subID);
}
static Future<bool> onShownContainerChanged(String newName,String oldName,Map params) {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["newName"]=newName;
properties["oldName"]=oldName;
properties["params"]=params;
return _service.methodChannel().invokeMethod('onShownContainerChanged',properties).then<bool>((value){
return BOOL(value);
});
}
static Future<bool> onFlutterPageResult(String uniqueId,String key,Map resultData,Map params) {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["uniqueId"]=uniqueId;
properties["key"]=key;
properties["resultData"]=resultData;
properties["params"]=params;
return _service.methodChannel().invokeMethod('onFlutterPageResult',properties).then<bool>((value){
return BOOL(value);
});
}
static Future<Map> pageOnStart(Map params) async {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["params"]=params;
try {
return await _service.methodChannel().invokeMethod('pageOnStart',properties).then<Map>((value){
return value as Map;
});
} catch (e) {
print('Page on start exception');
return Future<Map>.value({});
}
}
static Future<bool> openPage(String pageName,Map params,bool animated) {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["pageName"]=pageName;
properties["params"]=params;
properties["animated"]=animated;
return _service.methodChannel().invokeMethod('openPage',properties).then<bool>((value){
return BOOL(value);
});
}
static Future<bool> closePage(String uniqueId,String pageName,Map params,bool animated) {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["uniqueId"]=uniqueId;
properties["pageName"]=pageName;
properties["params"]=params;
properties["animated"]=animated;
return _service.methodChannel().invokeMethod('closePage',properties).then<bool>((value){
return BOOL(value);
});
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'NavigationService.dart';
import '../handlers/NavigationService_onNativePageResult.dart';
import '../handlers/NavigationService_didShowPageContainer.dart';
import '../handlers/NavigationService_willShowPageContainer.dart';
import '../handlers/NavigationService_willDisappearPageContainer.dart';
import '../handlers/NavigationService_didDisappearPageContainer.dart';
import '../handlers/NavigationService_didInitPageContainer.dart';
import '../handlers/NavigationService_willDeallocPageContainer.dart';
class NavigationServiceRegister{
static register(){
NavigationService.regsiter();
NavigationService_onNativePageResult.regsiter();
NavigationService_didShowPageContainer.regsiter();
NavigationService_willShowPageContainer.regsiter();
NavigationService_willDisappearPageContainer.regsiter();
NavigationService_didDisappearPageContainer.regsiter();
NavigationService_didInitPageContainer.regsiter();
NavigationService_willDeallocPageContainer.regsiter();
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import '../NavigationService/service/NavigationServiceRegister.dart';
class ServiceLoader{
static load(){
NavigationServiceRegister.register();
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'package:flutter/material.dart';
import 'package:flutter_boost/container/container_manager.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/router/boost_page_route.dart';
import 'package:flutter_boost/support/logger.dart';
enum ContainerLifeCycle {
Init,
Appear,
Disappear,
Destroy,
Background,
Foreground
}
typedef void BoostContainerLifeCycleObserver(
ContainerLifeCycle state, BoostContainerSettings settings);
typedef void ResultObserver(
int requestCode, int responseCode, Map<dynamic, dynamic> result);
class BoostContainer extends Navigator {
final BoostContainerSettings settings;
const BoostContainer(
{GlobalKey<BoostContainerState> key,
this.settings = const BoostContainerSettings(),
String initialRoute,
RouteFactory onGenerateRoute,
RouteFactory onUnknownRoute,
List<NavigatorObserver> observers})
: super(
key: key,
initialRoute: initialRoute,
onGenerateRoute: onGenerateRoute,
onUnknownRoute: onUnknownRoute,
observers: observers);
factory BoostContainer.copy(Navigator navigator,
[BoostContainerSettings settings = const BoostContainerSettings()]) =>
BoostContainer(
key: GlobalKey<BoostContainerState>(),
settings: settings,
initialRoute: navigator.initialRoute,
onGenerateRoute: navigator.onGenerateRoute,
onUnknownRoute: navigator.onUnknownRoute,
observers: navigator.observers,
);
factory BoostContainer.obtain(
Navigator navigator, BoostContainerSettings settings) =>
BoostContainer(
key: GlobalKey<BoostContainerState>(),
settings: settings,
onGenerateRoute: (RouteSettings routeSettings) {
if (routeSettings.name == '/') {
return BoostPageRoute<dynamic>(
pageName: settings.name,
params: settings.params,
uniqueId: settings.uniqueId,
animated: false,
settings: routeSettings,
builder: settings.builder);
} else {
return navigator.onGenerateRoute(routeSettings);
}
},
observers: <NavigatorObserver>[
ContainerNavigatorObserver.bindContainerManager()
],
onUnknownRoute: navigator.onUnknownRoute);
@override
BoostContainerState createState() => BoostContainerState();
@override
StatefulElement createElement() => ContainerElement(this);
static BoostContainerState tryOf(BuildContext context) {
final BoostContainerState container =
context.ancestorStateOfType(const TypeMatcher<BoostContainerState>());
return container;
}
static BoostContainerState of(BuildContext context) {
final BoostContainerState container =
context.ancestorStateOfType(const TypeMatcher<BoostContainerState>());
assert(container != null, 'not in flutter boost');
return container;
}
String desc() => '{uniqueId=${settings.uniqueId},name=${settings.name}}';
}
class BoostContainerState extends NavigatorState {
final Set<VoidCallback> _backPressedListeners = Set<VoidCallback>();
final Set<ResultObserver> _resultObservers = Set<ResultObserver>();
String get uniqueId => widget.settings.uniqueId;
String get name => widget.settings.name;
BoostContainerSettings get settings => widget.settings;
bool get onstage =>
BoostContainerManager.of(context).onstageContainer == this;
bool get maybeOnstageNext =>
BoostContainerManager.of(context).subContainer == this;
@override
BoostContainer get widget => super.widget as BoostContainer;
ContainerNavigatorObserver findContainerNavigatorObserver(
Navigator navigator) {
for (NavigatorObserver observer in navigator.observers) {
if (observer is ContainerNavigatorObserver) {
return observer;
}
}
return null;
}
@override
void didUpdateWidget(Navigator oldWidget) {
super.didUpdateWidget(oldWidget);
findContainerNavigatorObserver(oldWidget).removeBoostNavigatorObserver(
FlutterBoost.containerManager.navigatorObserver);
}
@override
void dispose() {
findContainerNavigatorObserver(widget).removeBoostNavigatorObserver(
FlutterBoost.containerManager.navigatorObserver);
super.dispose();
}
void performBackPressed() {
Logger.log('performBackPressed');
if (_backPressedListeners.isEmpty) {
FlutterBoost.singleton
.closePage(name, uniqueId, settings.params, animated: false);
} else {
for (VoidCallback cb in _backPressedListeners) {
cb();
}
}
}
void performOnResult(Map<dynamic, dynamic> data) {
Logger.log('performOnResult ${data.toString()}');
final int requestCode = data['requestCode'];
final int responseCode = data['responseCode'];
final Map result = data['result'];
for (ResultObserver observer in _resultObservers) {
observer(requestCode, responseCode, result);
}
}
@override
bool pop<T extends Object>([T result]) {
if (canPop()) {
return super.pop(result);
} else {
if (BoostContainerManager.of(context).canPop()) {
BoostContainerManager.of(context).pop();
return true;
}
}
return false;
}
VoidCallback addBackPressedListener(VoidCallback listener) {
_backPressedListeners.add(listener);
return () => _backPressedListeners.remove(listener);
}
VoidCallback addResultObserver(ResultObserver observer) {
_resultObservers.add(observer);
return () => _resultObservers.remove(observer);
}
VoidCallback addLifeCycleObserver(BoostContainerLifeCycleObserver observer) {
return FlutterBoost.singleton.addBoostContainerLifeCycleObserver(
(ContainerLifeCycle state, BoostContainerSettings settings) {
if (settings.uniqueId == uniqueId) {
observer(state, settings);
}
});
}
}
class BoostContainerSettings {
final String uniqueId;
final String name;
final Map params;
final WidgetBuilder builder;
const BoostContainerSettings(
{this.uniqueId = 'default',
this.name = 'default',
this.params,
this.builder});
}
class ContainerElement extends StatefulElement {
ContainerElement(StatefulWidget widget) : super(widget);
}
class ContainerNavigatorObserver extends NavigatorObserver {
BoostNavigatorObserver observer;
final Set<BoostNavigatorObserver> _boostObservers =
Set<BoostNavigatorObserver>();
ContainerNavigatorObserver();
factory ContainerNavigatorObserver.bindContainerManager() =>
ContainerNavigatorObserver()
..addBoostNavigatorObserver(
FlutterBoost.containerManager.navigatorObserver);
VoidCallback addBoostNavigatorObserver(BoostNavigatorObserver observer) {
_boostObservers.add(observer);
return () => _boostObservers.remove(observer);
}
void removeBoostNavigatorObserver(BoostNavigatorObserver observer) {
_boostObservers.remove(observer);
}
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didPush(route, previousRoute);
}
}
@override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didPop(route, previousRoute);
}
}
@override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didRemove(route, previousRoute);
}
}
@override
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didReplace(newRoute: newRoute, oldRoute: oldRoute);
}
}
}
class BoostNavigatorObserver {
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {}
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {}
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {}
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_boost/AIOService/NavigationService/service/NavigationService.dart';
import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/messaging/native_page_container_event_handler.dart';
import 'package:flutter_boost/support/logger.dart';
class ContainerCoordinator implements NativePageContainerEventHandler {
static final ContainerCoordinator singleton = ContainerCoordinator();
final Map<String, PageBuilder> _pageBuilders = <String, PageBuilder>{};
PageBuilder _defaultPageBuilder;
ContainerCoordinator() {
NavigationService.listenEvent(onChannelEvent);
}
BoostContainerSettings _createContainerSettings(
String name, Map params, String pageId) {
Widget page;
final BoostContainerSettings routeSettings = BoostContainerSettings(
uniqueId: pageId,
name: name,
params: params,
builder: (BuildContext ctx) {
//Try to build a page using keyed builder.
if (_pageBuilders[name] != null) {
page = _pageBuilders[name](name, params, pageId);
}
//Build a page using default builder.
if (page == null && _defaultPageBuilder != null) {
page = _defaultPageBuilder(name, params, pageId);
}
assert(page != null);
Logger.log('build widget:$page for page:$name($pageId)');
return page;
});
return routeSettings;
}
//Register a default page builder.
void registerDefaultPageBuilder(PageBuilder builder) {
_defaultPageBuilder = builder;
}
//Register page builder for a key.
void registerPageBuilder(String pageName, PageBuilder builder) {
if (pageName != null && builder != null) {
_pageBuilders[pageName] = builder;
}
}
void registerPageBuilders(Map<String, PageBuilder> builders) {
if (builders?.isNotEmpty == true) {
_pageBuilders.addAll(builders);
}
}
void onChannelEvent(dynamic event) {
if (event is Map) {
Map map = event as Map;
final String type = map['type'];
switch (type) {
//Handler back key pressed event.
case 'backPressedCallback':
{
final String id = map['uniqueId'];
FlutterBoost.containerManager
?.containerStateOf(id)
?.performBackPressed();
}
break;
//Enter foregroud
case 'foreground':
{
FlutterBoost.containerManager?.setForeground();
}
break;
//Enter background
case 'background':
{
FlutterBoost.containerManager?.setBackground();
}
break;
//Schedule a frame.
case 'scheduleFrame':
{
WidgetsBinding.instance.scheduleForcedFrame();
Future<dynamic>.delayed(Duration(milliseconds: 250),
() => WidgetsBinding.instance.scheduleFrame());
}
break;
}
}
}
//Messaging
@override
bool nativeContainerWillShow(String name, Map params, String pageId) {
if (FlutterBoost.containerManager?.containsContainer(pageId) != true) {
FlutterBoost.containerManager
?.pushContainer(_createContainerSettings(name, params, pageId));
}
return true;
}
@override
bool nativeContainerDidShow(String name, Map params, String pageId) {
FlutterBoost.containerManager
?.showContainer(_createContainerSettings(name, params, pageId));
performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Appear);
Logger.log(
'native containner did show,\nmanager dump:\n${FlutterBoost.containerManager?.dump()}');
return true;
}
@override
bool nativeContainerWillDisappear(String name, Map params, String pageId) {
return true;
}
@override
bool nativeContainerDidDisappear(String name, Map params, String pageId) {
performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Disappear);
return true;
}
@override
bool nativeContainerDidInit(String name, Map params, String pageId) {
performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Init);
return true;
}
@override
bool nativeContainerWillDealloc(String name, Map params, String pageId) {
performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Destroy);
FlutterBoost.containerManager?.remove(pageId);
Logger.log(
'native containner dealloc, \nmanager dump:\n${FlutterBoost.containerManager?.dump()}');
return true;
}
static void performContainerLifeCycle(
BoostContainerSettings settings, ContainerLifeCycle lifeCycle) {
for (BoostContainerLifeCycleObserver observer in FlutterBoost
.singleton.observersHolder
.observersOf<BoostContainerLifeCycleObserver>()) {
observer(lifeCycle, settings);
}
Logger.log(
'BoostContainerLifeCycleObserver container:${settings.name} lifeCycle:$lifeCycle');
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_boost/AIOService/NavigationService/service/NavigationService.dart';
import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/support/logger.dart';
enum ContainerOperation { Push, Onstage, Pop, Remove }
typedef BoostContainerObserver = void Function(
ContainerOperation operation, BoostContainerSettings settings);
@immutable
class BoostContainerManager extends StatefulWidget {
final Navigator initNavigator;
const BoostContainerManager({Key key, this.initNavigator}) : super(key: key);
@override
ContainerManagerState createState() => ContainerManagerState();
static ContainerManagerState tryOf(BuildContext context) {
final ContainerManagerState manager =
context.ancestorStateOfType(const TypeMatcher<ContainerManagerState>());
return manager;
}
static ContainerManagerState of(BuildContext context) {
final ContainerManagerState manager =
context.ancestorStateOfType(const TypeMatcher<ContainerManagerState>());
assert(manager != null, 'not in flutter boost');
return manager;
}
}
class ContainerManagerState extends State<BoostContainerManager> {
final GlobalKey<OverlayState> _overlayKey = GlobalKey<OverlayState>();
final List<BoostContainer> _offstage = <BoostContainer>[];
final ManagerNavigatorObserver _navigatorObserver =
ManagerNavigatorObserver();
List<_ContainerOverlayEntry> _leastEntries;
BoostContainer _onstage;
bool _foreground = true;
String _lastShownContainer;
bool get foreground => _foreground;
ManagerNavigatorObserver get navigatorObserver => _navigatorObserver;
//Number of containers.
int get containerCounts => _offstage.length;
//Setting for current visible container.
BoostContainerSettings get onstageSettings => _onstage.settings;
//Current visible container.
BoostContainerState get onstageContainer => _stateOf(_onstage);
BoostContainerState get subContainer =>
_offstage.isEmpty ? null : _stateOf(_offstage.last);
@override
void initState() {
super.initState();
assert(widget.initNavigator != null);
_onstage = BoostContainer.copy(widget.initNavigator);
}
void updateFocuse() {
final BoostContainerState now = _stateOf(_onstage);
if (now != null) {
FocusScope.of(context).setFirstFocus(now.focusScopeNode);
}
}
@override
Widget build(BuildContext context) {
return Overlay(
key: _overlayKey,
initialEntries: const <OverlayEntry>[],
);
}
BoostContainerState _stateOf(BoostContainer container) {
if (container.key != null &&
container.key is GlobalKey<BoostContainerState>) {
final GlobalKey<BoostContainerState> globalKey =
container.key as GlobalKey<BoostContainerState>;
return globalKey.currentState;
}
assert(
false, 'key of BoostContainer must be GlobalKey<BoostContainerState>');
return null;
}
void _onShownContainerChanged(String old, String now) {
Logger.log('onShownContainerChanged old:$old now:$now');
NavigationService.onShownContainerChanged(now, old, <dynamic, dynamic>{});
}
void _refreshOverlayEntries() {
final OverlayState overlayState = _overlayKey.currentState;
if (overlayState == null) {
return;
}
if (_leastEntries != null && _leastEntries.isNotEmpty) {
for (_ContainerOverlayEntry entry in _leastEntries) {
entry.remove();
}
}
final List<BoostContainer> containers = <BoostContainer>[];
containers.addAll(_offstage);
assert(_onstage != null, 'Should have a least one BoostContainer');
containers.add(_onstage);
_leastEntries = containers
.map<_ContainerOverlayEntry>(
(BoostContainer container) => _ContainerOverlayEntry(container))
.toList(growable: false);
overlayState.insertAll(_leastEntries);
SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) {
final String now = _onstage.settings.uniqueId;
if (_lastShownContainer != now) {
final String old = _lastShownContainer;
_lastShownContainer = now;
_onShownContainerChanged(old, now);
}
updateFocuse();
});
}
@override
void setState(VoidCallback fn) {
if (SchedulerBinding.instance.schedulerPhase ==
SchedulerPhase.persistentCallbacks) {
SchedulerBinding.instance.addPostFrameCallback((Duration duration) {
_refreshOverlayEntries();
});
} else {
_refreshOverlayEntries();
}
fn();
//return super.setState(fn);
}
void setForeground() {
_foreground = true;
ContainerCoordinator.performContainerLifeCycle(
_onstage.settings, ContainerLifeCycle.Foreground);
}
void setBackground() {
_foreground = false;
ContainerCoordinator.performContainerLifeCycle(
_onstage.settings, ContainerLifeCycle.Background);
}
//If container exists bring it to front else
//create a container.
void showContainer(BoostContainerSettings settings) {
if (settings.uniqueId == _onstage.settings.uniqueId) {
_onShownContainerChanged(null, settings.uniqueId);
return;
}
final int index = _offstage.indexWhere((BoostContainer container) =>
container.settings.uniqueId == settings.uniqueId);
if (index > -1) {
final BoostContainerState old = _stateOf(_onstage);
_offstage.add(_onstage);
_onstage = _offstage.removeAt(index);
setState(() {});
for (BoostContainerObserver observer in FlutterBoost
.singleton.observersHolder
.observersOf<BoostContainerObserver>()) {
observer(ContainerOperation.Onstage, _onstage.settings);
}
Logger.log('ContainerObserver didOnstage');
} else {
pushContainer(settings);
}
}
BoostContainerState containerStateOf(String id) {
if (id == _onstage.settings.uniqueId) {
return _stateOf(_onstage);
}
final BoostContainer container = _offstage.firstWhere(
(BoostContainer container) => container.settings.uniqueId == id,
orElse: () => null);
return container == null ? null : _stateOf(container);
}
bool containsContainer(String id) {
if (id == _onstage.settings.uniqueId) {
return true;
}
return _offstage
.any((BoostContainer container) => container.settings.uniqueId == id);
}
void pushContainer(BoostContainerSettings settings) {
assert(settings.uniqueId != _onstage.settings.uniqueId);
assert(_offstage.every((BoostContainer container) =>
container.settings.uniqueId != settings.uniqueId));
final BoostContainerState old = _stateOf(_onstage);
_offstage.add(_onstage);
_onstage = BoostContainer.obtain(widget.initNavigator, settings);
setState(() {});
for (BoostContainerObserver observer in FlutterBoost
.singleton.observersHolder
.observersOf<BoostContainerObserver>()) {
observer(ContainerOperation.Push, _onstage.settings);
}
Logger.log('ContainerObserver didPush');
}
void pop() {
assert(canPop());
final BoostContainerState old = _stateOf(_onstage);
_onstage = _offstage.removeLast();
setState(() {});
for (BoostContainerObserver observer in FlutterBoost
.singleton.observersHolder
.observersOf<BoostContainerObserver>()) {
observer(ContainerOperation.Pop, _onstage.settings);
}
Logger.log('ContainerObserver didPop');
}
void remove(String uniqueId) {
if (_onstage.settings.uniqueId == uniqueId) {
pop();
} else {
final BoostContainer container = _offstage.firstWhere(
(BoostContainer container) => container.settings.uniqueId == uniqueId,
orElse: () => null);
if (container != null) {
_offstage.remove(container);
setState(() {});
for (BoostContainerObserver observer in FlutterBoost
.singleton.observersHolder
.observersOf<BoostContainerObserver>()) {
observer(ContainerOperation.Remove, _onstage.settings);
}
Logger.log('ContainerObserver didRemove');
}
}
return null;
}
bool canPop() => _offstage.isNotEmpty;
String dump() {
String info = 'onstage#:\n ${_onstage?.desc()}\noffstage#:';
for (BoostContainer container in _offstage.reversed) {
info = '$info\n ${container?.desc()}';
}
return info;
}
}
class _ContainerOverlayEntry extends OverlayEntry {
bool _removed = false;
_ContainerOverlayEntry(BoostContainer container)
: super(
builder: (BuildContext ctx) => container,
opaque: true,
maintainState: true);
@override
void remove() {
assert(!_removed);
if (_removed) {
return;
}
_removed = true;
super.remove();
}
}
class ManagerNavigatorObserver extends BoostNavigatorObserver {
BoostNavigatorObserver observer;
final Set<BoostNavigatorObserver> _boostObservers =
Set<BoostNavigatorObserver>();
VoidCallback addBoostNavigatorObserver(BoostNavigatorObserver observer) {
_boostObservers.add(observer);
return () => _boostObservers.remove(observer);
}
void removeBoostNavigatorObserver(BoostNavigatorObserver observer) {
_boostObservers.remove(observer);
}
@override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
Logger.log('ManagerNavigatorObserver didPush');
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didPush(route, previousRoute);
}
}
@override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
Logger.log('ManagerNavigatorObserver didPop');
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didPop(route, previousRoute);
}
}
@override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
Logger.log('ManagerNavigatorObserver didRemove');
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didRemove(route, previousRoute);
}
}
@override
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
Logger.log('ManagerNavigatorObserver didReplace');
for (BoostNavigatorObserver observer in _boostObservers) {
observer.didReplace(newRoute: newRoute, oldRoute: oldRoute);
}
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_boost/AIOService/NavigationService/service/NavigationService.dart';
import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/container/container_manager.dart';
import 'package:flutter_boost/messaging/page_result_mediator.dart';
import 'package:flutter_boost/router/router.dart';
import 'AIOService/loader/ServiceLoader.dart';
import 'container/container_coordinator.dart';
import 'observers_holders.dart';
export 'container/boost_container.dart';
export 'container/container_manager.dart';
typedef Widget PageBuilder(String pageName, Map params, String uniqueId);
class FlutterBoost {
static final FlutterBoost _instance = FlutterBoost();
final GlobalKey<ContainerManagerState> containerManagerKey =
GlobalKey<ContainerManagerState>();
final Router _router = Router();
final ObserversHolder _observersHolder = ObserversHolder();
final PageResultMediator _resultMediator = PageResultMediator();
FlutterBoost() {
ServiceLoader.load();
}
static FlutterBoost get singleton => _instance;
static ContainerManagerState get containerManager =>
_instance.containerManagerKey.currentState;
static TransitionBuilder init([TransitionBuilder builder]) {
return (BuildContext context, Widget child) {
assert(child is Navigator, 'child must be Navigator, what is wrong?');
//Logger.log('Running flutter boost opt!');
final BoostContainerManager manager = BoostContainerManager(
key: _instance.containerManagerKey, initNavigator: child);
if (builder != null) {
return builder(context, manager);
} else {
return manager;
}
};
}
ObserversHolder get observersHolder => _observersHolder;
///Register a default page builder.
void registerDefaultPageBuilder(PageBuilder builder) {
ContainerCoordinator.singleton.registerDefaultPageBuilder(builder);
}
///Register page builder for a key.
void registerPageBuilder(String pageName, PageBuilder builder) {
ContainerCoordinator.singleton.registerPageBuilder(pageName, builder);
}
///Register a map builders
void registerPageBuilders(Map<String, PageBuilder> builders) {
ContainerCoordinator.singleton.registerPageBuilders(builders);
}
Future<bool> openPage(String url, Map params,
{bool animated, PageResultHandler resultHandler}) {
return _router.openPage(url, params,
animated: animated, resultHandler: resultHandler);
}
Future<bool> closePage(String url, String pageId, Map params,
{bool animated}) {
return _router.closePage(url, pageId, params, animated: animated);
}
//Close currentPage page.
Future<bool> closeCurPage(Map params) {
return _router.closeCurPage(params);
}
Future<bool> closePageForContext(BuildContext context) {
BoostContainerSettings settings = BoostContainer.of(context).settings;
return closePage(settings.name, settings.uniqueId, settings.params,
animated: true);
}
///query current top page and show it
static void handleOnStartPage() async {
final Map<dynamic, dynamic> pageInfo =
await NavigationService.pageOnStart(<dynamic, dynamic>{});
if (pageInfo == null || pageInfo.isEmpty) return;
if (pageInfo.containsKey("name") &&
pageInfo.containsKey("params") &&
pageInfo.containsKey("uniqueId")) {
ContainerCoordinator.singleton.nativeContainerDidShow(
pageInfo["name"], pageInfo["params"], pageInfo["uniqueId"]);
}
}
bool onPageResult(String key, Map<String, dynamic> resultData) {
containerManager?.containerStateOf(key)?.performOnResult(resultData);
_resultMediator.onPageResult(key, resultData);
return true;
}
VoidCallback setPageResultHandler(String key, PageResultHandler handler) {
return _resultMediator.setPageResultHandler(key, handler);
}
///register for Container changed callbacks
VoidCallback addContainerObserver(BoostContainerObserver observer) =>
_observersHolder.addObserver<BoostContainerObserver>(observer);
///register for Container lifecycle callbacks
VoidCallback addBoostContainerLifeCycleObserver(
BoostContainerLifeCycleObserver observer) =>
_observersHolder.addObserver<BoostContainerLifeCycleObserver>(observer);
///register callbacks for Navigators push & pop
VoidCallback addBoostNavigatorObserver(BoostNavigatorObserver observer) =>
_observersHolder.addObserver<BoostNavigatorObserver>(observer);
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'package:flutter_boost/AIOService/NavigationService/service/NavigationService.dart';
import 'dart:async';
abstract class MessageProxy{
Future<bool> openPage(String pageName,Map params,bool animated);
Future<bool> closePage(String uniqueId,String pageName,Map params,bool animated);
}
class MessageProxyImp implements MessageProxy{
@override
Future<bool> openPage(String pageName, Map params, bool animated) {
return NavigationService.openPage(pageName, params, animated);
}
@override
Future<bool> closePage(String uniqueId, String pageName, Map params, bool animated) {
return NavigationService.closePage(uniqueId, pageName, params, animated);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
abstract class NativePageContainerEventHandler{
bool nativeContainerWillShow(String name , Map params, String pageId);
bool nativeContainerDidShow(String name , Map params, String pageId);
bool nativeContainerWillDisappear(String name , Map params, String pageId);
bool nativeContainerDidDisappear(String name , Map params, String pageId);
bool nativeContainerWillDealloc(String name , Map params, String pageId);
bool nativeContainerDidInit(String name , Map params, String pageId);
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'package:flutter_boost/support/logger.dart';
typedef void PageResultHandler(String key , Map<dynamic,dynamic> result);
typedef VoidCallback = void Function();
class PageResultMediator{
Map<String,PageResultHandler> _handlers = Map();
void onPageResult(String key , Map<dynamic,dynamic> resultData){
if(key == null) return;
Logger.log("did receive page result $resultData for page key $key");
if(_handlers.containsKey(key)){
_handlers[key](key,resultData);
_handlers.remove(key);
}
}
VoidCallback setPageResultHandler(String key, PageResultHandler handler){
if(key == null || handler == null) return (){};
_handlers[key] = handler;
return (){
_handlers.remove(key);
};
}
}
\ No newline at end of file
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:ui';
class ObserversHolder {
final Map<String, Set<dynamic>> _observers = Map<String, Set<dynamic>>();
VoidCallback addObserver<T>(T observer) {
final Set<T> set = _observers[T.toString()] ?? Set<T>();
set.add(observer);
_observers[T.toString()] = set;
return () => set.remove(observer);
}
void removeObserver<T>(T observer) =>
_observers[T.toString()]?.remove(observer);
void cleanObservers<T>(T observer) => _observers[T.toString()]?.clear();
Set<T> observersOf<T>() => _observers[T.toString()] ?? Set<T>();
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
typedef Widget PageBuilder(String pageName, Map params, String uniqueId);
class BoostPageRoute<T> extends MaterialPageRoute<T> {
final String pageName;
final String uniqueId;
final Map params;
final bool animated;
final WidgetBuilder builder;
final RouteSettings settings;
final Set<VoidCallback> backPressedListeners = Set<VoidCallback>();
@override
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
return child;
}
BoostPageRoute(
{Key stubKey,
this.pageName,
this.params,
this.uniqueId,
this.animated,
this.builder,
this.settings})
: super(
builder: (BuildContext context) => Stub(stubKey, builder(context)),
settings: settings);
static BoostPageRoute<T> of<T>(BuildContext context) {
final Route<T> route = ModalRoute.of(context);
if (route != null && route is BoostPageRoute<T>) {
return route;
} else {
throw Exception('not in a BoostPageRoute');
}
}
static BoostPageRoute<T> tryOf<T>(BuildContext context) {
final Route<T> route = ModalRoute.of(context);
if (route != null && route is BoostPageRoute<T>) {
return route;
} else {
return null;
}
}
}
@immutable
class Stub extends StatefulWidget {
final Widget child;
const Stub(Key key, this.child) : super(key: key);
@override
_StubState createState() => _StubState();
}
class _StubState extends State<Stub> {
@override
Widget build(BuildContext context) => widget.child;
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'dart:async';
import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/messaging/message_proxy.dart';
import 'package:flutter_boost/messaging/page_result_mediator.dart';
import 'package:flutter_boost/support/logger.dart';
class Router {
MessageProxy _msgProxy = MessageProxyImp();
void setMessageProxy(MessageProxy prx) {
if (prx != null) {
_msgProxy = prx;
}
}
Future<bool> openPage(String url, Map params,
{bool animated = true, PageResultHandler resultHandler}) {
if (resultHandler != null) {
params["needResult"] = true;
FlutterBoost.singleton.setPageResultHandler(url,
(String key, Map<dynamic, dynamic> result) {
Logger.log("Recieved result $result for from page key $key");
if (resultHandler != null) {
resultHandler(key, result);
}
});
}
return _msgProxy.openPage(url, params, animated);
}
Future<bool> closePage(String name, String pageId, Map params,
{bool animated = true}) {
return _msgProxy.closePage(pageId, name, params, animated);
}
//Close currentPage page.
Future<bool> closeCurPage(Map params) {
BoostContainerSettings settings;
final BoostContainerState container =
FlutterBoost.containerManager.onstageContainer;
if (container != null) {
settings = container.settings;
} else {
settings = FlutterBoost.containerManager.onstageSettings;
}
if (settings == null) {
return Future<bool>(() {
return false;
});
}
bool animated = true;
if (params.containsKey("animated")) {
animated = params["animated"] as bool;
}
return _msgProxy.closePage(
settings.uniqueId, settings.name, settings.params, animated);
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import 'logger.dart';
class Tracer {
static final Tracer singleton = Tracer();
final Map<String, Record> _records = <String, Record>{};
Tracer();
static String mark(String unique, String tag) {
Record record = singleton._records[unique];
if (record == null) {
record = Record()
..unique = unique
..marks = <Mark>[];
singleton._records[unique] = record;
}
record.marks.add(Mark(tag, DateTime.now()));
return record.toString();
}
static void markAndLog(String unique, String tag) {
Logger.log(mark(unique, tag));
}
static String dump(String unique) => singleton._records[unique]?.toString();
}
class Record {
String unique;
List<Mark> marks;
@override
String toString() {
if (marks == null || marks.isEmpty) {
return '';
}
if (marks.length == 1) {
return marks.first.tag;
}
Mark least = marks.first;
String info = 'trace<$unique>#${least.tag}';
for (int i = 1; i < marks.length; i++) {
final Mark mark = marks[i];
info =
'$info=${mark.timeStamp.millisecond - least.timeStamp.millisecond}ms=>${mark.tag}';
least = mark;
}
return info;
}
}
class Mark {
String tag;
DateTime timeStamp;
Mark(this.tag, this.timeStamp);
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Alibaba Group
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
class Logger {
static void log(String msg) {
assert((){
print('FlutterBoost#$msg');
return true;
}());
//print('FlutterBoost=>$msg');
}
static void error(String msg) {
print('FlutterBoost#$msg');
}
}
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.
version: 0.0.39
author: Alibaba Xianyu
homepage: https://github.com/alibaba/flutter_boost
environment:
sdk: ">=2.0.0-dev.68.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
xservice_kit: ^0.0.26
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
plugin:
androidPackage: com.taobao.idlefish.flutterboost
pluginClass: FlutterBoostPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.io/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.io/assets-and-images/#resolution-aware.
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.io/custom-fonts/#from-packages
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