Commit d4fd4eda authored by Jidong Chen's avatar Jidong Chen

Merge branch 'flutter_1.5_upgrade_opt' of...

Merge branch 'flutter_1.5_upgrade_opt' of https://github.com/alibaba/flutter_boost into flutter_1.5_upgrade_opt
parents c2c27908 f0885a9d
......@@ -26,10 +26,11 @@ package com.taobao.idlefish.flutterboost;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.view.ViewCompat;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
......@@ -71,6 +72,8 @@ public class BoostFlutterView extends FrameLayout {
new io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener() {
@Override
public void onFirstFrameRendered() {
Debuger.log("BoostFlutterView onFirstFrameRendered");
if(mRenderingProgressCover != null && mRenderingProgressCover.getParent() != null) {
((ViewGroup)mRenderingProgressCover.getParent()).removeView(mRenderingProgressCover);
}
......@@ -240,13 +243,18 @@ public class BoostFlutterView extends FrameLayout {
((ViewGroup)mSnapshot.getParent()).removeView(mSnapshot);
}
Debuger.log("BoostFlutterView snapshot");
final Bitmap bitmap = mFlutterEngine.getRenderer().getBitmap();
if(bitmap != null) {
Debuger.log("BoostFlutterView snapshot "+bitmap.getByteCount());
mSnapshot.setImageBitmap(mFlutterEngine.getRenderer().getBitmap());
BoostFlutterView.this.addView(mSnapshot);
//Utils.saveBitmap(bitmap,"/sdcard/idlefish/fb/ss-"+ SystemClock.uptimeMillis());
mSnapshot.setImageBitmap(bitmap);
BoostFlutterView.this.addView(mSnapshot);
}
}
mFlutterView.removeOnFirstFrameRenderedListener(mOnFirstFrameRenderedListener);
final IStateListener stateListener = FlutterBoostPlugin.sInstance.mStateListener;
if(stateListener != null) {
stateListener.beforeEngineDetach(mFlutterEngine,this);
......@@ -259,6 +267,8 @@ public class BoostFlutterView extends FrameLayout {
public void onDestroy() {
Debuger.log("BoostFlutterView onDestroy");
mFlutterView.removeOnFirstFrameRenderedListener(mOnFirstFrameRenderedListener);
mPlatformPlugin = null;
mFlutterEngine = 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
......@@ -65,7 +65,7 @@ public class ContainerRecord implements IContainerRecord {
Utils.assertCallOnMainThread();
BoostEngineProvider.assertEngineRunning();
if(mState != STATE_UNKNOW) {
if (mState != STATE_UNKNOW) {
Debuger.exception("state error");
}
......@@ -78,7 +78,7 @@ public class ContainerRecord implements IContainerRecord {
public void onAppear() {
Utils.assertCallOnMainThread();
if(mState != STATE_CREATED && mState != STATE_DISAPPEAR) {
if (mState != STATE_CREATED && mState != STATE_DISAPPEAR) {
Debuger.exception("state error");
}
......@@ -95,7 +95,7 @@ public class ContainerRecord implements IContainerRecord {
public void onDisappear() {
Utils.assertCallOnMainThread();
if(mState != STATE_APPEAR) {
if (mState != STATE_APPEAR) {
Debuger.exception("state error");
}
......@@ -112,7 +112,7 @@ public class ContainerRecord implements IContainerRecord {
public void onDestroy() {
Utils.assertCallOnMainThread();
if(mState != STATE_DISAPPEAR) {
if (mState != STATE_DISAPPEAR) {
Debuger.exception("state error");
}
......@@ -120,9 +120,11 @@ public class ContainerRecord implements IContainerRecord {
mProxy.destroy();
mContainer.getBoostFlutterView().onDestroy();
mManager.removeRecord(this);
if(!mManager.hasContainerAppear()) {
if (!mManager.hasContainerAppear()) {
mContainer.getBoostFlutterView().onPause();
mContainer.getBoostFlutterView().onStop();
}
......@@ -132,7 +134,7 @@ public class ContainerRecord implements IContainerRecord {
public void onBackPressed() {
Utils.assertCallOnMainThread();
if(mState == STATE_UNKNOW || mState == STATE_DESTROYED) {
if (mState == STATE_UNKNOW || mState == STATE_DESTROYED) {
Debuger.exception("state error");
}
......@@ -141,14 +143,14 @@ public class ContainerRecord implements IContainerRecord {
map.put("name", mContainer.getContainerUrl());
map.put("uniqueId", mUniqueId);
FlutterBoostPlugin.singleton().channel().sendEvent("lifecycle",map);
FlutterBoostPlugin.singleton().channel().sendEvent("lifecycle", map);
mContainer.getBoostFlutterView().onBackPressed();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
mContainer.getBoostFlutterView().onRequestPermissionsResult(requestCode,permissions,grantResults);
mContainer.getBoostFlutterView().onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
......@@ -158,12 +160,12 @@ public class ContainerRecord implements IContainerRecord {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
mContainer.getBoostFlutterView().onActivityResult(requestCode,resultCode,data);
mContainer.getBoostFlutterView().onActivityResult(requestCode, resultCode, data);
}
@Override
public void onContainerResult(int requestCode, Map<String,Object> result) {
mManager.setContainerResult(this,requestCode,result);
public void onContainerResult(int requestCode, Map<String, Object> result) {
mManager.setContainerResult(this, requestCode, result);
}
@Override
......@@ -187,7 +189,7 @@ public class ContainerRecord implements IContainerRecord {
private void create() {
if (mState == STATE_UNKNOW) {
invokeChannelUnsafe(
invokeChannelUnsafe("didInitPageContainer",
mContainer.getContainerUrl(),
mContainer.getContainerUrlParams(),
mUniqueId
......@@ -198,7 +200,7 @@ public class ContainerRecord implements IContainerRecord {
}
private void appear() {
invokeChannelUnsafe(
invokeChannelUnsafe("didShowPageContainer",
mContainer.getContainerUrl(),
mContainer.getContainerUrlParams(),
mUniqueId
......@@ -210,7 +212,7 @@ public class ContainerRecord implements IContainerRecord {
private void disappear() {
if (mState < STATE_DISAPPEAR) {
invokeChannel(
invokeChannel("didDisappearPageContainer",
mContainer.getContainerUrl(),
mContainer.getContainerUrlParams(),
mUniqueId
......@@ -223,7 +225,7 @@ public class ContainerRecord implements IContainerRecord {
private void destroy() {
if (mState < STATE_DESTROYED) {
invokeChannel(
invokeChannel("willDeallocPageContainer",
mContainer.getContainerUrl(),
mContainer.getContainerUrlParams(),
mUniqueId
......@@ -234,20 +236,20 @@ public class ContainerRecord implements IContainerRecord {
}
}
public void invokeChannel(String pageName, Map params, String uniqueId) {
public void invokeChannel(String method, String url, Map params, String uniqueId) {
HashMap<String, Object> args = new HashMap<>();
args.put("pageName", pageName);
args.put("pageName", url);
args.put("params", params);
args.put("uniqueId", uniqueId);
FlutterBoostPlugin.singleton().channel().invokeMethod("didInitPageContainer", args);
FlutterBoostPlugin.singleton().channel().invokeMethod(method, args);
}
public void invokeChannelUnsafe(String pageName, Map params, String uniqueId) {
public void invokeChannelUnsafe(String method, String url, Map params, String uniqueId) {
HashMap<String, Object> args = new HashMap<>();
args.put("pageName", pageName);
args.put("pageName", url);
args.put("params", params);
args.put("uniqueId", uniqueId);
FlutterBoostPlugin.singleton().channel().invokeMethodUnsafe("didInitPageContainer", args);
FlutterBoostPlugin.singleton().channel().invokeMethodUnsafe(method, args);
}
}
}
......@@ -26,6 +26,12 @@ package com.taobao.idlefish.flutterboost;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Looper;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Utils {
......@@ -35,6 +41,29 @@ public class Utils {
}
}
public static void saveBitmap(Bitmap bm, String filePath) {
File f = new File(filePath);
try {
if (!f.exists()) {
if(!f.getParentFile().exists() && !f.getParentFile().mkdirs()) {
throw new Exception("mkdir except");
}
if(!f.createNewFile()){
throw new Exception("createNewFile except");
}
}
FileOutputStream out = new FileOutputStream(f);
bm.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Throwable t){
throw new RuntimeException(t);
}
}
public static boolean checkImageValid(final Bitmap bitmap) {
if (null == bitmap) {
return false;
......
......@@ -105,7 +105,7 @@ public abstract class BoostFlutterActivity extends Activity implements IFlutterV
BoostFlutterView.Builder builder = new BoostFlutterView.Builder(this);
return builder.flutterEngine(engine)
.renderMode(FlutterView.RenderMode.texture)
.renderMode(FlutterView.RenderMode.surface)
.transparencyMode(isBackgroundTransparent() ?
FlutterView.TransparencyMode.transparent :
FlutterView.TransparencyMode.opaque)
......
......@@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 27
compileSdkVersion 26
lintOptions {
disable 'InvalidPackage'
......@@ -35,7 +35,7 @@ android {
// 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
targetSdkVersion 26
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
......@@ -58,6 +58,6 @@ 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'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:appcompat-v7:26.1.0'
}
......@@ -7,6 +7,10 @@
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 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
......
......@@ -104,6 +104,8 @@ class ContainerCoordinator {
Map map = event;
final String type = map['type'];
Logger.log("onEvent $type");
switch (type) {
//Handler back key pressed event.
case 'backPressedCallback':
......@@ -141,6 +143,8 @@ class ContainerCoordinator {
}
Future<dynamic> _onMethodCall(MethodCall call) {
Logger.log("onMetohdCall ${call.method}");
switch (call.method) {
case "didInitPageContainer":
{
......
/*
* 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<dynamic,dynamic> result,Map<dynamic,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.
*/
import 'dart:async';
import 'package:flutter_boost/container/boost_container.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_boost/messaging/boost_message_channel.dart';
class Router {
Future<Map<dynamic,dynamic>> open(String url,{Map<dynamic,dynamic> urlParams,Map<dynamic,dynamic> exts}){
return BoostMessageChannel.openPage(url,urlParams, exts);
}
Future<bool> close(String id,{Map<dynamic,dynamic> result,Map<dynamic,dynamic> exts}){
return BoostMessageChannel.closePage(id,result:result,exts: exts);
}
//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;
}
Map<String,dynamic> exts = Map();
exts["animated"] = animated;
return BoostMessageChannel.closePage(settings.uniqueId,result: {} ,exts: exts);
}
}
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