Commit 436c5960 authored by Yacumima's avatar Yacumima

improve

parent 23d41278
...@@ -3,7 +3,9 @@ package com.taobao.idlefish.flutterboost; ...@@ -3,7 +3,9 @@ package com.taobao.idlefish.flutterboost;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.EventChannel;
...@@ -13,40 +15,45 @@ import io.flutter.plugin.common.MethodChannel; ...@@ -13,40 +15,45 @@ import io.flutter.plugin.common.MethodChannel;
public class BoostChannel { public class BoostChannel {
private final MethodChannel mMethodChannel; private final MethodChannel mMethodChannel;
private final EventChannel mEventChannel;
private final Set<MethodChannel.MethodCallHandler> mMethodCallHandlers = new HashSet<>(); private final Set<MethodChannel.MethodCallHandler> mMethodCallHandlers = new HashSet<>();
private final Map<String,Set<EventListener>> mEventListeners = new HashMap<>();
private EventChannel.EventSink mEventSink; BoostChannel(MethodChannel methodChannel){
BoostChannel(MethodChannel methodChannel, EventChannel eventChannel){
mMethodChannel = methodChannel; mMethodChannel = methodChannel;
mEventChannel = eventChannel;
mMethodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() { mMethodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override @Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
Object[] handlers;
synchronized (mMethodCallHandlers) {
handlers = mMethodCallHandlers.toArray();
}
for(Object o:handlers) { if (methodCall.method.equals("__event__")) {
((MethodChannel.MethodCallHandler)o).onMethodCall(methodCall,result); String name = methodCall.argument("name");
Map args = methodCall.argument("arguments");
Object[] listeners = null;
synchronized (mEventListeners) {
Set<EventListener> set = mEventListeners.get(name);
if (set != null) {
listeners = set.toArray();
}
}
if(listeners != null) {
for(Object o:listeners) {
((EventListener)o).onEvent(name,args);
}
}
}else{
Object[] handlers;
synchronized (mMethodCallHandlers) {
handlers = mMethodCallHandlers.toArray();
}
for(Object o:handlers) {
((MethodChannel.MethodCallHandler)o).onMethodCall(methodCall,result);
}
} }
} }
}); });
mEventChannel.setStreamHandler(new EventChannel.StreamHandler(){
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
mEventSink = eventSink;
}
@Override
public void onCancel(Object o) {
}
});
} }
public void invokeMethodUnsafe(final String name,Serializable args){ public void invokeMethodUnsafe(final String name,Serializable args){
...@@ -88,6 +95,10 @@ public class BoostChannel { ...@@ -88,6 +95,10 @@ public class BoostChannel {
} }
public void invokeMethod(final String name,Serializable args,MethodChannel.Result result){ public void invokeMethod(final String name,Serializable args,MethodChannel.Result result){
if("__event__".equals(name)) {
Debuger.exception("method name should not be __event__");
}
mMethodChannel.invokeMethod(name, args, result); mMethodChannel.invokeMethod(name, args, result);
} }
...@@ -103,11 +114,33 @@ public class BoostChannel { ...@@ -103,11 +114,33 @@ public class BoostChannel {
} }
} }
public void sendEvent(Serializable event){ public void addEventListener(String name, EventListener listener) {
if(mEventSink == null) { synchronized (mEventListeners){
Debuger.exception("event stream not listen yet!"); Set<EventListener> set = mEventListeners.get(name);
if(set == null) {
set = new HashSet<>();
}
set.add(listener);
mEventListeners.put(name,set);
}
}
public void removeEventListener(EventListener listener) {
synchronized (mEventListeners) {
for(Set<EventListener> set:mEventListeners.values()) {
set.remove(listener);
}
} }
}
public void sendEvent(String name,Map args){
Map event = new HashMap();
event.put("name",name);
event.put("arguments",args);
mMethodChannel.invokeMethod("__event__",event);
}
mEventSink.success(event); public interface EventListener {
void onEvent(String name, Map args);
} }
} }
...@@ -141,7 +141,7 @@ public class ContainerRecord implements IContainerRecord { ...@@ -141,7 +141,7 @@ public class ContainerRecord implements IContainerRecord {
map.put("name", mContainer.getContainerUrl()); map.put("name", mContainer.getContainerUrl());
map.put("uniqueId", mUniqueId); map.put("uniqueId", mUniqueId);
FlutterBoostPlugin.singleton().channel().sendEvent(map); FlutterBoostPlugin.singleton().channel().sendEvent("lifecycle",map);
mContainer.getBoostFlutterView().onBackPressed(); mContainer.getBoostFlutterView().onBackPressed();
} }
......
...@@ -39,7 +39,6 @@ import com.taobao.idlefish.flutterboost.interfaces.IStateListener; ...@@ -39,7 +39,6 @@ import com.taobao.idlefish.flutterboost.interfaces.IStateListener;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry;
...@@ -70,9 +69,8 @@ public class FlutterBoostPlugin { ...@@ -70,9 +69,8 @@ public class FlutterBoostPlugin {
} }
public static void registerWith(PluginRegistry.Registrar registrar) { public static void registerWith(PluginRegistry.Registrar registrar) {
final MethodChannel method = new MethodChannel(registrar.messenger(), "flutter_boost_method"); final MethodChannel method = new MethodChannel(registrar.messenger(), "flutter_boost");
final EventChannel event = new EventChannel(registrar.messenger(), "flutter_boost_event"); singleton().registerChannel(method);
singleton().registerChannel(method,event);
} }
private final IPlatform mPlatform; private final IPlatform mPlatform;
...@@ -121,8 +119,8 @@ public class FlutterBoostPlugin { ...@@ -121,8 +119,8 @@ public class FlutterBoostPlugin {
mStateListener = listener; mStateListener = listener;
} }
private void registerChannel(MethodChannel method, EventChannel event) { private void registerChannel(MethodChannel method) {
mBoostChannel = new BoostChannel(method,event); mBoostChannel = new BoostChannel(method);
mBoostChannel.addMethodCallHandler(new BoostMethodHandler()); mBoostChannel.addMethodCallHandler(new BoostMethodHandler());
} }
...@@ -145,7 +143,7 @@ public class FlutterBoostPlugin { ...@@ -145,7 +143,7 @@ public class FlutterBoostPlugin {
if (mEngineProvider.tryGetEngine() != null) { if (mEngineProvider.tryGetEngine() != null) {
HashMap<String, String> map = new HashMap<>(); HashMap<String, String> map = new HashMap<>();
map.put("type", "foreground"); map.put("type", "foreground");
mBoostChannel.sendEvent(map); mBoostChannel.sendEvent("lifecycle",map);
} }
} }
mCurrentActiveActivity = activity; mCurrentActiveActivity = activity;
...@@ -169,7 +167,7 @@ public class FlutterBoostPlugin { ...@@ -169,7 +167,7 @@ public class FlutterBoostPlugin {
if (mEngineProvider.tryGetEngine() != null) { if (mEngineProvider.tryGetEngine() != null) {
HashMap<String, String> map = new HashMap<>(); HashMap<String, String> map = new HashMap<>();
map.put("type", "background"); map.put("type", "background");
mBoostChannel.sendEvent(map); mBoostChannel.sendEvent("lifecycle",map);
} }
mCurrentActiveActivity = null; mCurrentActiveActivity = null;
} }
...@@ -188,7 +186,7 @@ public class FlutterBoostPlugin { ...@@ -188,7 +186,7 @@ public class FlutterBoostPlugin {
if (mEngineProvider.tryGetEngine() != null) { if (mEngineProvider.tryGetEngine() != null) {
HashMap<String, String> map = new HashMap<>(); HashMap<String, String> map = new HashMap<>();
map.put("type", "background"); map.put("type", "background");
mBoostChannel.sendEvent(map); mBoostChannel.sendEvent("lifecycle",map);
} }
mCurrentActiveActivity = null; mCurrentActiveActivity = null;
} }
...@@ -211,9 +209,11 @@ public class FlutterBoostPlugin { ...@@ -211,9 +209,11 @@ public class FlutterBoostPlugin {
record = mManager.getLastGenerateRecord(); record = mManager.getLastGenerateRecord();
} }
pageInfo.put("name", record.getContainer().getContainerUrl()); if(record != null) {
pageInfo.put("params", record.getContainer().getContainerUrlParams()); pageInfo.put("name", record.getContainer().getContainerUrl());
pageInfo.put("uniqueId", record.uniqueId()); pageInfo.put("params", record.getContainer().getContainerUrlParams());
pageInfo.put("uniqueId", record.uniqueId());
}
result.success(pageInfo); result.success(pageInfo);
} catch (Throwable t) { } catch (Throwable t) {
......
...@@ -69,7 +69,7 @@ abstract public class BoostFlutterFragment extends Fragment implements IFlutterV ...@@ -69,7 +69,7 @@ abstract public class BoostFlutterFragment extends Fragment implements IFlutterV
BoostFlutterView.Builder builder = new BoostFlutterView.Builder(getContextActivity()); BoostFlutterView.Builder builder = new BoostFlutterView.Builder(getContextActivity());
return builder.flutterEngine(engine) return builder.flutterEngine(engine)
.renderMode(FlutterView.RenderMode.surface) .renderMode(FlutterView.RenderMode.texture)
.transparencyMode(FlutterView.TransparencyMode.opaque) .transparencyMode(FlutterView.TransparencyMode.opaque)
.build(); .build();
} }
......
...@@ -38,6 +38,11 @@ public class MyApplication extends FlutterApplication { ...@@ -38,6 +38,11 @@ public class MyApplication extends FlutterApplication {
public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) { public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
PageRouter.openPageByUrl(context,url,urlParams,requestCode); PageRouter.openPageByUrl(context,url,urlParams,requestCode);
} }
@Override
public int whenEngineStart() {
return LAZY;
}
}); });
} }
} }
...@@ -29,9 +29,6 @@ class _MyAppState extends State<MyApp> { ...@@ -29,9 +29,6 @@ class _MyAppState extends State<MyApp> {
return FlutterRouteWidget(); return FlutterRouteWidget();
}, },
}); });
FlutterBoost.handleOnStartPage();
} }
@override @override
......
...@@ -62,7 +62,7 @@ class TabRouteWidget extends StatelessWidget { ...@@ -62,7 +62,7 @@ class TabRouteWidget extends StatelessWidget {
body: Center( body: Center(
child: RaisedButton( child: RaisedButton(
onPressed: () { onPressed: () {
FlutterBoost.singleton.openPage("second", {}, animated: true); FlutterBoost.singleton.open("second");
}, },
child: Text('Open second route'), child: Text('Open second route'),
), ),
...@@ -107,7 +107,7 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -107,7 +107,7 @@ class FlutterRouteWidget extends StatelessWidget {
///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。 ///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。
///例如:sample://nativePage?aaa=bbb ///例如:sample://nativePage?aaa=bbb
onTap: () => onTap: () =>
FlutterBoost.singleton.openPage("sample://nativePage", { FlutterBoost.singleton.open("sample://nativePage", urlParams:{
"query": {"aaa": "bbb"} "query": {"aaa": "bbb"}
}), }),
), ),
...@@ -124,7 +124,7 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -124,7 +124,7 @@ class FlutterRouteWidget extends StatelessWidget {
///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。 ///后面的参数会在native的IPlatform.startActivity方法回调中拼接到url的query部分。
///例如:sample://nativePage?aaa=bbb ///例如:sample://nativePage?aaa=bbb
onTap: () => onTap: () =>
FlutterBoost.singleton.openPage("sample://flutterPage", { FlutterBoost.singleton.open("sample://flutterPage", urlParams:{
"query": {"aaa": "bbb"} "query": {"aaa": "bbb"}
}), }),
), ),
...@@ -152,7 +152,7 @@ class FlutterRouteWidget extends StatelessWidget { ...@@ -152,7 +152,7 @@ class FlutterRouteWidget extends StatelessWidget {
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), )),
onTap: () => FlutterBoost.singleton onTap: () => FlutterBoost.singleton
.openPage("sample://flutterFragmentPage", {}), .open("sample://flutterFragmentPage"),
) )
], ],
), ),
...@@ -201,7 +201,7 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -201,7 +201,7 @@ class FragmentRouteWidget extends StatelessWidget {
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), )),
onTap: () => onTap: () =>
FlutterBoost.singleton.openPage("sample://nativePage", {}), FlutterBoost.singleton.open("sample://nativePage"),
), ),
InkWell( InkWell(
child: Container( child: Container(
...@@ -213,7 +213,7 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -213,7 +213,7 @@ class FragmentRouteWidget extends StatelessWidget {
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), )),
onTap: () => onTap: () =>
FlutterBoost.singleton.openPage("sample://flutterPage", {}), FlutterBoost.singleton.open("sample://flutterPage"),
), ),
InkWell( InkWell(
child: Container( child: Container(
...@@ -225,7 +225,7 @@ class FragmentRouteWidget extends StatelessWidget { ...@@ -225,7 +225,7 @@ class FragmentRouteWidget extends StatelessWidget {
style: TextStyle(fontSize: 22.0, color: Colors.black), style: TextStyle(fontSize: 22.0, color: Colors.black),
)), )),
onTap: () => FlutterBoost.singleton onTap: () => FlutterBoost.singleton
.openPage("sample://flutterFragmentPage", {}), .open("sample://flutterFragmentPage"),
) )
], ],
), ),
......
...@@ -21,51 +21,95 @@ ...@@ -21,51 +21,95 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
import 'dart:async'; import 'dart:async';
import 'dart:ui';
import 'package:flutter/services.dart';
import 'package:flutter_boost/container/boost_container.dart'; typedef Future<dynamic> EventListener(String name, Map arguments);
import 'package:flutter_boost/flutter_boost.dart'; typedef Future<dynamic> MethodHandler(MethodCall call);
import 'package:flutter_boost/messaging/boost_message_channel.dart';
class Router { class BoostChannel {
final MethodChannel _methodChannel = MethodChannel("flutter_boost");
final Map<String, List<EventListener>> _eventListeners = Map();
final Set<MethodHandler> _methodHandlers = Set();
Future<Map<dynamic,dynamic>> open(String url,{Map<String,dynamic> urlParams,Map<String,dynamic> exts}){ BoostChannel() {
return BoostMessageChannel.openPage(url,urlParams, exts); _methodChannel.setMethodCallHandler((MethodCall call){
if (call.method == "__event__") {
String name = call.arguments["name"];
Map arg = call.arguments["arguments"];
List<EventListener> list = _eventListeners[name];
if (list != null) {
for (EventListener l in list) {
l(name, arg);
}
}
}else{
for(MethodHandler handler in _methodHandlers) {
handler(call);
}
}
});
} }
Future<bool> close(String id,{Map<String,dynamic> result,Map<String,dynamic> exts}){ void sendEvent(String name, Map arguments) {
return BoostMessageChannel.closePage(id,result:result,exts: exts); if (name == null) {
return;
}
if (arguments == null) {
arguments = Map();
}
Map msg = Map();
msg["name"] = name;
msg["arguments"] = arguments;
_methodChannel.invokeMethod("__event__", msg);
} }
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
assert(method != "__event__");
//Close currentPage page. return _methodChannel.invokeMethod<T>(method,arguments);
Future<bool> closeCurPage(Map params) { }
BoostContainerSettings settings;
final BoostContainerState container = Future<List<T>> invokeListMethod<T>(String method, [ dynamic arguments ]) async {
FlutterBoost.containerManager.onstageContainer; assert(method != "__event__");
if (container != null) { return _methodChannel.invokeListMethod<T>(method,arguments);
settings = container.settings; }
} else {
settings = FlutterBoost.containerManager.onstageSettings;
}
if (settings == null) { Future<Map<K, V>> invokeMapMethod<K, V>(String method, [ dynamic arguments ]) async {
return Future<bool>(() { assert(method != "__event__");
return false;
}); return _methodChannel.invokeMapMethod<K, V>(method,arguments);
} }
VoidCallback addEventListener(String name, EventListener listener) {
assert(name != null && listener != null);
bool animated = true; List<EventListener> list = _eventListeners[name];
if (params.containsKey("animated")) { if (list == null) {
animated = params["animated"] as bool; list = List();
_eventListeners[name] = list;
} }
Map<String,dynamic> exts = Map(); list.add(listener);
exts["animated"] = animated;
return () {
list.remove(listener);
};
}
VoidCallback addMethodHandler(MethodHandler handler) {
assert(handler != null);
_methodHandlers.add(handler);
return BoostMessageChannel.closePage(settings.uniqueId,result: {} ,exts: exts); return (){
_methodHandlers.remove(handler);
};
} }
} }
...@@ -25,8 +25,8 @@ import 'package:flutter/material.dart'; ...@@ -25,8 +25,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_boost/container/container_coordinator.dart'; import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:flutter_boost/container/container_manager.dart'; import 'package:flutter_boost/container/container_manager.dart';
import 'package:flutter_boost/flutter_boost.dart'; import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/router/boost_page_route.dart'; import 'package:flutter_boost/container/boost_page_route.dart';
import 'package:flutter_boost/support/logger.dart'; import 'package:flutter_boost/logger.dart';
enum ContainerLifeCycle { enum ContainerLifeCycle {
Init, Init,
...@@ -192,7 +192,11 @@ class BoostContainerState extends NavigatorState { ...@@ -192,7 +192,11 @@ class BoostContainerState extends NavigatorState {
if (canPop()) { if (canPop()) {
return super.pop(result); return super.pop(result);
} else { } else {
FlutterBoost.singleton.closePage(name, uniqueId, params); if (T is Map<String,dynamic>) {
FlutterBoost.singleton.close(uniqueId, result:result as Map<String,dynamic>);
}else{
FlutterBoost.singleton.close(uniqueId);
}
} }
return false; return false;
......
...@@ -24,20 +24,32 @@ ...@@ -24,20 +24,32 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_boost/channel/boost_channel.dart';
import 'package:flutter_boost/container/boost_container.dart'; import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/flutter_boost.dart'; import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/messaging/native_container_event_handler.dart'; import 'package:flutter_boost/logger.dart';
import 'package:flutter_boost/support/logger.dart';
class ContainerCoordinator implements NativeContainerEventHandler { class ContainerCoordinator {
static final ContainerCoordinator singleton = ContainerCoordinator(); static ContainerCoordinator get singleton => _instance;
static ContainerCoordinator _instance;
final Map<String, PageBuilder> _pageBuilders = <String, PageBuilder>{}; final Map<String, PageBuilder> _pageBuilders = <String, PageBuilder>{};
PageBuilder _defaultPageBuilder; PageBuilder _defaultPageBuilder;
ContainerCoordinator() { ContainerCoordinator(BoostChannel channel) {
FlutterBoost.singleton.addEventListener("lifecycle", (String name , Map arguments){ assert(_instance == null);
onChannelEvent(arguments);
_instance = this;
channel.addEventListener("lifecycle",
(String name, Map arguments) {
_onChannelEvent(arguments);
});
channel.addMethodHandler((MethodCall call) {
return _onMethodCall(call);
}); });
} }
...@@ -87,7 +99,7 @@ class ContainerCoordinator implements NativeContainerEventHandler { ...@@ -87,7 +99,7 @@ class ContainerCoordinator implements NativeContainerEventHandler {
} }
} }
void onChannelEvent(dynamic event) { Future<dynamic> _onChannelEvent(dynamic event) {
if (event is Map) { if (event is Map) {
Map map = event; Map map = event;
final String type = map['type']; final String type = map['type'];
...@@ -124,11 +136,69 @@ class ContainerCoordinator implements NativeContainerEventHandler { ...@@ -124,11 +136,69 @@ class ContainerCoordinator implements NativeContainerEventHandler {
break; break;
} }
} }
return Future<dynamic>(() {});
}
Future<dynamic> _onMethodCall(MethodCall call) {
switch (call.method) {
case "didInitPageContainer":
{
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
_nativeContainerDidInit(pageName, params, uniqueId);
}
break;
case "willShowPageContainer":
{
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
_nativeContainerWillShow(pageName, params, uniqueId);
}
break;
case "didShowPageContainer":
{
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
nativeContainerDidShow(pageName, params, uniqueId);
}
break;
case "willDisappearPageContainer":
{
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
_nativeContainerWillDisappear(pageName, params, uniqueId);
}
break;
case "didDisappearPageContainer":
{
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
_nativeContainerDidDisappear(pageName, params, uniqueId);
}
break;
case "willDeallocPageContainer":
{
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
_nativeContainerWillDealloc(pageName, params, uniqueId);
}
break;
case "onNativePageResult":
{}
break;
}
return Future<dynamic>(() {});
} }
//Messaging bool _nativeContainerWillShow(String name, Map params, String pageId) {
@override
bool nativeContainerWillShow(String name, Map params, String pageId) {
if (FlutterBoost.containerManager?.containsContainer(pageId) != true) { if (FlutterBoost.containerManager?.containsContainer(pageId) != true) {
FlutterBoost.containerManager FlutterBoost.containerManager
?.pushContainer(_createContainerSettings(name, params, pageId)); ?.pushContainer(_createContainerSettings(name, params, pageId));
...@@ -137,7 +207,6 @@ class ContainerCoordinator implements NativeContainerEventHandler { ...@@ -137,7 +207,6 @@ class ContainerCoordinator implements NativeContainerEventHandler {
return true; return true;
} }
@override
bool nativeContainerDidShow(String name, Map params, String pageId) { bool nativeContainerDidShow(String name, Map params, String pageId) {
FlutterBoost.containerManager FlutterBoost.containerManager
?.showContainer(_createContainerSettings(name, params, pageId)); ?.showContainer(_createContainerSettings(name, params, pageId));
...@@ -151,27 +220,23 @@ class ContainerCoordinator implements NativeContainerEventHandler { ...@@ -151,27 +220,23 @@ class ContainerCoordinator implements NativeContainerEventHandler {
return true; return true;
} }
@override bool _nativeContainerWillDisappear(String name, Map params, String pageId) {
bool nativeContainerWillDisappear(String name, Map params, String pageId) {
return true; return true;
} }
@override bool _nativeContainerDidDisappear(String name, Map params, String pageId) {
bool nativeContainerDidDisappear(String name, Map params, String pageId) {
performContainerLifeCycle(_createContainerSettings(name, params, pageId), performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Disappear); ContainerLifeCycle.Disappear);
return true; return true;
} }
@override bool _nativeContainerDidInit(String name, Map params, String pageId) {
bool nativeContainerDidInit(String name, Map params, String pageId) {
performContainerLifeCycle(_createContainerSettings(name, params, pageId), performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Init); ContainerLifeCycle.Init);
return true; return true;
} }
@override bool _nativeContainerWillDealloc(String name, Map params, String pageId) {
bool nativeContainerWillDealloc(String name, Map params, String pageId) {
performContainerLifeCycle(_createContainerSettings(name, params, pageId), performContainerLifeCycle(_createContainerSettings(name, params, pageId),
ContainerLifeCycle.Destroy); ContainerLifeCycle.Destroy);
......
...@@ -23,11 +23,10 @@ ...@@ -23,11 +23,10 @@
*/ */
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter_boost/messaging/boost_message_channel.dart';
import 'package:flutter_boost/container/boost_container.dart'; import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/container/container_coordinator.dart'; import 'package:flutter_boost/container/container_coordinator.dart';
import 'package:flutter_boost/flutter_boost.dart'; import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/support/logger.dart'; import 'package:flutter_boost/logger.dart';
enum ContainerOperation { Push, Onstage, Pop, Remove } enum ContainerOperation { Push, Onstage, Pop, Remove }
...@@ -135,7 +134,12 @@ class ContainerManagerState extends State<BoostContainerManager> { ...@@ -135,7 +134,12 @@ class ContainerManagerState extends State<BoostContainerManager> {
void _onShownContainerChanged(String old, String now) { void _onShownContainerChanged(String old, String now) {
Logger.log('onShownContainerChanged old:$old now:$now'); Logger.log('onShownContainerChanged old:$old now:$now');
BoostMessageChannel.onShownContainerChanged(now, old, <dynamic, dynamic>{});
Map<String, dynamic> properties = new Map<String, dynamic>();
properties['newName'] = now;
properties['oldName'] = old;
FlutterBoost.singleton.channel.invokeMethod('onShownContainerChanged',properties);
} }
void _refreshOverlayEntries() { void _refreshOverlayEntries() {
......
...@@ -24,17 +24,15 @@ ...@@ -24,17 +24,15 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_boost/messaging/boost_message_channel.dart';
import 'package:flutter_boost/container/boost_container.dart'; import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/container/container_manager.dart'; import 'package:flutter_boost/container/container_manager.dart';
import 'package:flutter_boost/router/router.dart';
import 'channel/boost_channel.dart';
import 'container/container_coordinator.dart'; import 'container/container_coordinator.dart';
import 'observers_holders.dart'; import 'observers_holders.dart';
export 'container/boost_container.dart'; export 'container/boost_container.dart';
export 'container/container_manager.dart'; export 'container/container_manager.dart';
import 'package:flutter/services.dart';
typedef Widget PageBuilder(String pageName, Map params, String uniqueId); typedef Widget PageBuilder(String pageName, Map params, String uniqueId);
...@@ -50,10 +48,7 @@ class FlutterBoost { ...@@ -50,10 +48,7 @@ class FlutterBoost {
final GlobalKey<ContainerManagerState> containerManagerKey = final GlobalKey<ContainerManagerState> containerManagerKey =
GlobalKey<ContainerManagerState>(); GlobalKey<ContainerManagerState>();
final ObserversHolder _observersHolder = ObserversHolder(); final ObserversHolder _observersHolder = ObserversHolder();
final Router _router = Router(); final BoostChannel _boostChannel = BoostChannel();
final MethodChannel _methodChannel = MethodChannel('flutter_boost_method');
int _callbackID = 0;
static FlutterBoost get singleton => _instance; static FlutterBoost get singleton => _instance;
...@@ -64,6 +59,21 @@ class FlutterBoost { ...@@ -64,6 +59,21 @@ class FlutterBoost {
{TransitionBuilder builder, {TransitionBuilder builder,
PrePushRoute prePush, PrePushRoute prePush,
PostPushRoute postPush}) { PostPushRoute postPush}) {
WidgetsBinding.instance.addPostFrameCallback((_){
singleton.channel.invokeMethod<Map>('pageOnStart').then((Map pageInfo){
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"]);
}
});
});
return (BuildContext context, Widget child) { return (BuildContext context, Widget child) {
assert(child is Navigator, 'child must be Navigator, what is wrong?'); assert(child is Navigator, 'child must be Navigator, what is wrong?');
...@@ -83,51 +93,10 @@ class FlutterBoost { ...@@ -83,51 +93,10 @@ class FlutterBoost {
ObserversHolder get observersHolder => _observersHolder; ObserversHolder get observersHolder => _observersHolder;
FlutterBoost() { BoostChannel get channel => _boostChannel;
BoostMessageChannel.methodChannel = _methodChannel;
_methodChannel.setMethodCallHandler((MethodCall call){
if(call.method == "__event__"){
return BoostMessageChannel.handleEventCall(call);
}else if(call.method == "didDisappearPageContainer"){
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
ContainerCoordinator.singleton
.nativeContainerDidDisappear(pageName, params, uniqueId);
}else if(call.method == "nativeContainerDidInit"){
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
ContainerCoordinator.singleton
.nativeContainerDidInit(pageName, params, uniqueId);
}else if(call.method == "didShowPageContainer"){
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
ContainerCoordinator.singleton
.nativeContainerDidShow(pageName, params, uniqueId);
}else if(call.method == "willDeallocPageContainer"){
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
ContainerCoordinator.singleton
.nativeContainerWillDealloc(pageName, params, uniqueId);
}else if(call.method == "willDisappearPageContainer"){
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
ContainerCoordinator.singleton
.nativeContainerWillDisappear(pageName, params, uniqueId);
}else if(call.method == "willShowPageContainer"){
String pageName = call.arguments["pageName"];
Map params = call.arguments["params"];
String uniqueId = call.arguments["uniqueId"];
ContainerCoordinator.singleton
.nativeContainerWillShow(pageName, params, uniqueId);
}
return Future<dynamic>((){});
});
FlutterBoost(){
ContainerCoordinator(_boostChannel);
} }
///Register a default page builder. ///Register a default page builder.
...@@ -141,95 +110,40 @@ class FlutterBoost { ...@@ -141,95 +110,40 @@ class FlutterBoost {
} }
Future<Map<dynamic,dynamic>> open(String url,{Map<String,dynamic> urlParams,Map<String,dynamic> exts}){ Future<Map<dynamic,dynamic>> open(String url,{Map<String,dynamic> urlParams,Map<String,dynamic> exts}){
if(urlParams == null) {
urlParams = Map();
}
if(exts == null){
exts = Map();
}
urlParams["__calback_id__"] = _callbackID;
_callbackID += 2;
return _router.open(url,urlParams: urlParams,exts: exts);
}
Future<bool> close(String id,{Map<String,dynamic> result,Map<String,dynamic> exts}){
if(result == null) {
result = Map();
}
if(exts == null){
exts = Map();
}
return _router.close(id,result: result,exts: exts);
}
//Listen broadcast event from native.
Function addEventListener(String name , EventListener listener){
return BoostMessageChannel.addEventListener(name, listener);
}
//Send broadcast event to native. Map<String, dynamic> properties = new Map<String, dynamic>();
void sendEvent(String name , Map arguments){ properties["url"] = url;
BoostMessageChannel.sendEvent(name, arguments); properties["urlParams"] = urlParams;
properties["exts"] = exts;
return channel.invokeMethod<Map<dynamic, dynamic>>(
'openPage', properties);
} }
Future<Map<String,dynamic>> openPage(String name, Map params,{bool animated}) { Future<bool> close(String id,{Map<String,dynamic> result,Map<String,dynamic> exts}){
Map<String,dynamic> exts = Map();
if(animated != null){
exts["animated"] = animated;
}else{
exts["animated"] = true;
}
return open(name,urlParams: params , exts: exts);
}
Future<bool> closePage(String url, String id, Map params, assert(id != null);
{bool animated}) {
Map<String,dynamic> exts = Map(); Map<String, dynamic> properties = new Map<String, dynamic>();
if(animated != null){ properties["uniqueId"] = id;
exts["animated"] = animated; if (result != null) {
}else{ properties["result"] = result;
exts["animated"] = true;
} }
if (exts != null) {
if(url != null){ properties["exts"] = exts;
exts["url"] = url;
} }
return channel.invokeMethod<bool>('closePage', properties);
if(params != null){
exts["params"] = params;
}
return close(id, result: {} , exts: exts);
} }
Future<bool> closeCurrent({Map<String,dynamic> result,Map<String,dynamic> exts}) {
//Close currentPage page. String id = containerManager?.onstageSettings?.uniqueId;
Future<bool> closeCurPage(Map params) { return close(id,result: result,exts: exts);
return _router.closeCurPage(params);
} }
Future<bool> closePageForContext(BuildContext context) { Future<bool> closeByContext(BuildContext context,{Map<String,dynamic> result,Map<String,dynamic> exts}) {
BoostContainerSettings settings = BoostContainer.of(context).settings; String id = BoostContainer.of(context)?.settings?.uniqueId;
return closePage(settings.name, settings.uniqueId, settings.params, return close(id,result: result,exts: exts);
animated: true);
} }
///query current top page and show it
static void handleOnStartPage() async {
final Map<dynamic, dynamic> pageInfo =
await BoostMessageChannel.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"]);
}
}
///register for Container changed callbacks ///register for Container changed callbacks
VoidCallback addContainerObserver(BoostContainerObserver observer) => VoidCallback addContainerObserver(BoostContainerObserver observer) =>
_observersHolder.addObserver<BoostContainerObserver>(observer); _observersHolder.addObserver<BoostContainerObserver>(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 'dart:async';
import 'package:flutter/services.dart';
typedef Future<dynamic> EventListener(String name , Map arguments);
class BoostMessageChannel {
static MethodChannel methodChannel;
static Map<String,List<EventListener>> _lists = Map();
static void sendEvent(String name , Map arguments){
if(name == null) {
return;
}
if(arguments == null){
arguments = Map();
}
Map msg = Map();
msg["name"] = name;
msg["arguments"] = arguments;
methodChannel.invokeMethod("__event__",msg);
}
static Function addEventListener(String name , EventListener listener){
if(name == null || listener == null){
return (){};
}
List<EventListener> list = _lists[name];
if(list == null){
list = List();
_lists[name] = list;
}
list.add(listener);
return (){
list.remove(listener);
};
}
static Future<dynamic> handleEventCall(MethodCall call){
if(call.method != "__event__"){
return Future<dynamic>((){});
}
String name = call.arguments["name"];
Map arg = call.arguments["arguments"];
List<EventListener> list = _lists[name];
if(list != null){
for(EventListener l in list){
l(name,arg);
}
}
return Future<dynamic>((){});
}
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 methodChannel.invokeMethod('onShownContainerChanged',properties).then<bool>((value){
return (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 methodChannel.invokeMethod('onFlutterPageResult',properties).then<bool>((value){
return (value);
});
}
static Future<Map> pageOnStart(Map params) async {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["params"]=params;
try {
return await methodChannel.invokeMethod('pageOnStart',properties).then<Map>((value){
return value as Map;
});
} catch (e) {
print('Page on start exception');
return Future<Map>((){});
}
}
static Future<Map<dynamic,dynamic>> openPage(String url,Map urlParams, Map exts) {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["url"]=url;
properties["urlParams"]=urlParams;
properties["exts"]=exts;
return methodChannel.invokeMethod('openPage',properties).then<Map<dynamic,dynamic>>((value){
return (value);
});
}
static Future<bool> closePage(String uniqueId,{Map<String,dynamic> result,Map<String,dynamic> exts}) {
Map<String,dynamic> properties = new Map<String,dynamic>();
properties["uniqueId"]=uniqueId;
if(result != null){
properties["result"]=result;
}
if(exts != null) {
properties["exts"] = exts;
}
return methodChannel.invokeMethod('closePage',properties).then<bool>((value){
return 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.
*/
abstract class NativeContainerEventHandler{
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 '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);
}
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