Commit 908b83ec authored by yangwu.jia's avatar yangwu.jia

Merge branch 'feature/flutter_1.9_upgrade' into feature/flutter_1.9_androidx_upgrade

# Conflicts:
#	android/src/main/java/com/idlefish/flutterboost/FlutterBoostPlugin.java
parents dc9713d1 3d998dc4
......@@ -91,9 +91,10 @@ public class ContainerRecord implements IContainerRecord {
mManager.pushRecord(this);
mProxy.appear();
mContainer.getBoostFlutterView().onAttach();
mProxy.appear();
}
@Override
......
package com.idlefish.flutterboost;
import android.os.Handler;
import androidx.annotation.Nullable;
import com.idlefish.flutterboost.interfaces.IContainerRecord;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
......@@ -217,6 +215,9 @@ public class FlutterBoostPlugin {
}
result.success(pageInfo);
NewFlutterBoost.instance().setFlutterPostFrameCallTime(new Date().getTime());
} catch (Throwable t) {
result.error("no flutter page found!", t.getMessage(), t);
}
......
......@@ -135,8 +135,10 @@ public class FlutterViewContainerManager implements IContainerManager {
final String uniqueId = ContainerRecord.genUniqueId(url);
urlParams.put(IContainerRecord.UNIQ_KEY,uniqueId);
IContainerRecord currentTopRecord = getCurrentTopRecord();
if(onResult != null) {
mOnResults.put(uniqueId,onResult);
mOnResults.put(currentTopRecord.uniqueId(),onResult);
}
NewFlutterBoost.instance().platform().openContainer(context,url,urlParams,requestCode,exts);
......
......@@ -31,6 +31,15 @@ public class NewFlutterBoost {
private PluginRegistry mRegistry;
static NewFlutterBoost sInstance = null;
private long FlutterPostFrameCallTime=0;
public long getFlutterPostFrameCallTime(){
return FlutterPostFrameCallTime;
}
public void setFlutterPostFrameCallTime(long FlutterPostFrameCallTime){
this.FlutterPostFrameCallTime=FlutterPostFrameCallTime;
}
public static NewFlutterBoost instance() {
if (sInstance == null) {
sInstance = new NewFlutterBoost();
......
package com.idlefish.flutterboost;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.TextureView;
import io.flutter.Log;
import io.flutter.embedding.engine.renderer.FlutterRenderer;
import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class XFlutterTextureView extends TextureView implements FlutterRenderer.RenderSurface {
private static final String TAG = "XFlutterTextureView";
private boolean isSurfaceAvailableForRendering;
private boolean isAttachedToFlutterRenderer;
@Nullable
private FlutterRenderer flutterRenderer;
@NonNull
private Set<OnFirstFrameRenderedListener> onFirstFrameRenderedListeners;
private final SurfaceTextureListener surfaceTextureListener;
public XFlutterTextureView(@NonNull Context context) {
this(context, (AttributeSet)null);
}
public XFlutterTextureView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.isSurfaceAvailableForRendering = false;
this.isAttachedToFlutterRenderer = false;
this.onFirstFrameRenderedListeners = new HashSet();
this.surfaceTextureListener = new SurfaceTextureListener() {
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Log.v("FlutterTextureView", "SurfaceTextureListener.onSurfaceTextureAvailable()");
XFlutterTextureView.this.isSurfaceAvailableForRendering = true;
if (XFlutterTextureView.this.isAttachedToFlutterRenderer) {
XFlutterTextureView.this.connectSurfaceToRenderer();
}
}
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
Log.v("FlutterTextureView", "SurfaceTextureListener.onSurfaceTextureSizeChanged()");
if (XFlutterTextureView.this.isAttachedToFlutterRenderer) {
XFlutterTextureView.this.changeSurfaceSize(width, height);
}
}
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
}
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
Log.v("FlutterTextureView", "SurfaceTextureListener.onSurfaceTextureDestroyed()");
XFlutterTextureView.this.isSurfaceAvailableForRendering = false;
if (XFlutterTextureView.this.isAttachedToFlutterRenderer) {
XFlutterTextureView.this.disconnectSurfaceFromRenderer();
}
return true;
}
};
this.init();
}
private void init() {
this.setSurfaceTextureListener(this.surfaceTextureListener);
}
public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
Log.v("FlutterTextureView", "Attaching to FlutterRenderer.");
if (this.flutterRenderer != null) {
Log.v("FlutterTextureView", "Already connected to a FlutterRenderer. Detaching from old one and attaching to new one.");
this.flutterRenderer.detachFromRenderSurface();
}
this.flutterRenderer = flutterRenderer;
this.isAttachedToFlutterRenderer = true;
if (this.isSurfaceAvailableForRendering) {
Log.v("FlutterTextureView", "Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
this.connectSurfaceToRenderer();
}
}
public void detachFromRenderer() {
if (this.flutterRenderer != null) {
if (this.getWindowToken() != null) {
Log.v("FlutterTextureView", "Disconnecting FlutterRenderer from Android surface.");
this.disconnectSurfaceFromRenderer();
}
this.flutterRenderer = null;
this.isAttachedToFlutterRenderer = false;
} else {
Log.w("FlutterTextureView", "detachFromRenderer() invoked when no FlutterRenderer was attached.");
}
}
private void connectSurfaceToRenderer() {
if (this.flutterRenderer != null && this.getSurfaceTexture() != null) {
Surface surface= new Surface(this.getSurfaceTexture());
this.flutterRenderer.surfaceCreated(surface);
surface.release();
} else {
throw new IllegalStateException("connectSurfaceToRenderer() should only be called when flutterRenderer and getSurfaceTexture() are non-null.");
}
}
private void changeSurfaceSize(int width, int height) {
if (this.flutterRenderer == null) {
throw new IllegalStateException("changeSurfaceSize() should only be called when flutterRenderer is non-null.");
} else {
Log.v("FlutterTextureView", "Notifying FlutterRenderer that Android surface size has changed to " + width + " x " + height);
this.flutterRenderer.surfaceChanged(width, height);
}
}
private void disconnectSurfaceFromRenderer() {
if (this.flutterRenderer == null) {
throw new IllegalStateException("disconnectSurfaceFromRenderer() should only be called when flutterRenderer is non-null.");
} else {
this.flutterRenderer.surfaceDestroyed();
}
}
public void addOnFirstFrameRenderedListener(@NonNull OnFirstFrameRenderedListener listener) {
this.onFirstFrameRenderedListeners.add(listener);
}
public void removeOnFirstFrameRenderedListener(@NonNull OnFirstFrameRenderedListener listener) {
this.onFirstFrameRenderedListeners.remove(listener);
}
public void onFirstFrameRendered() {
Log.v("FlutterTextureView", "onFirstFrameRendered()");
Iterator var1 = this.onFirstFrameRenderedListeners.iterator();
while(var1.hasNext()) {
OnFirstFrameRenderedListener listener = (OnFirstFrameRenderedListener)var1.next();
listener.onFirstFrameRendered();
}
}
}
\ No newline at end of file
......@@ -202,7 +202,7 @@ public class XFlutterView extends FrameLayout {
break;
case texture:
Log.v(TAG, "Internally using a FlutterTextureView.");
FlutterTextureView flutterTextureView = new FlutterTextureView(getContext());
XFlutterTextureView flutterTextureView = new XFlutterTextureView(getContext());
renderSurface = flutterTextureView;
addView(flutterTextureView);
break;
......@@ -585,7 +585,6 @@ public class XFlutterView extends FrameLayout {
+ " to new engine.");
detachFromFlutterEngine();
}
this.requestFocus();
this.flutterEngine = flutterEngine;
// Instruct our FlutterRenderer that we are now its designated RenderSurface.
......@@ -693,7 +692,6 @@ public class XFlutterView extends FrameLayout {
// signifies that this View does not process input (until a new engine is attached).
// TODO(mattcarroll): once this is proven to work, move this line ot TextInputPlugin
// resolveMemoryLeaks();
// Instruct our FlutterRenderer that we are no longer interested in being its RenderSurface.
FlutterRenderer flutterRenderer = flutterEngine.getRenderer();
// didRenderFirstFrame = false;
......@@ -702,32 +700,12 @@ public class XFlutterView extends FrameLayout {
flutterEngine = null;
}
public void release(){
textInputPlugin.release();
}
public void resolveMemoryLeaks(){
try {
Class clazz = TextInputPlugin.class;
for (Field f : clazz.getDeclaredFields()) {
System.out.println(f.isAccessible());
f.setAccessible(true);
if(f.get(this.textInputPlugin) instanceof TextInputChannel){
System.out.println( "xxxxxx:" +f.getName());
TextInputChannel channel=(TextInputChannel)f.get(this.textInputPlugin);
channel.setTextInputMethodHandler(null);
}
}
} catch (Throwable e) {
e.printStackTrace();
if(textInputPlugin!=null){
textInputPlugin.release();
}
}
/**
* Returns true if this {@code FlutterView} is currently attached to a {@link FlutterEngine}.
*/
......
......@@ -5,6 +5,7 @@ import android.app.Activity;
import androidx.lifecycle.Lifecycle;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
......@@ -102,6 +103,8 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContaine
host.configureFlutterEngine(flutterEngine);
host.getActivity().getWindow().setFormat(PixelFormat.TRANSLUCENT);
}
......
......@@ -3,6 +3,7 @@ package com.idlefish.flutterboost.containers;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
......@@ -18,6 +19,8 @@ import io.flutter.embedding.android.SplashScreen;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener;
import java.util.Date;
/**
* {@code View} that displays a {@link SplashScreen} until a given {@link FlutterView}
* renders its first frame.
......@@ -39,7 +42,7 @@ public class FlutterSplashView extends FrameLayout {
@Nullable
private String previousCompletedSplashIsolate;
private boolean hasRendered=false;
private Handler handler = new Handler();
@NonNull
private final FlutterView.FlutterEngineAttachmentListener flutterEngineAttachmentListener = new FlutterView.FlutterEngineAttachmentListener() {
......@@ -57,11 +60,40 @@ public class FlutterSplashView extends FrameLayout {
@NonNull
private final OnFirstFrameRenderedListener onFirstFrameRenderedListener = new OnFirstFrameRenderedListener() {
int i=0;
@Override
public void onFirstFrameRendered() {
if (splashScreen != null) {
transitionToFlutter();
if(NewFlutterBoost.instance().platform().whenEngineStart()== NewFlutterBoost.ConfigBuilder.FLUTTER_ACTIVITY_CREATED){
long now=new Date().getTime();
long flutterPostFrameCallTime=NewFlutterBoost.instance().getFlutterPostFrameCallTime();
if(flutterPostFrameCallTime!=0&& (now-flutterPostFrameCallTime)>800){
if (splashScreen != null) {
transitionToFlutter();
}
return;
}
handler.postDelayed(new Runnable() {
@Override
public void run() {
onFirstFrameRenderedListener.onFirstFrameRendered();
}
}, 200);
}else{
if (splashScreen != null) {
transitionToFlutter();
}
}
}
};
......@@ -91,24 +123,6 @@ public class FlutterSplashView extends FrameLayout {
}
}
@Nullable
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.previousCompletedSplashIsolate = previousCompletedSplashIsolate;
savedState.splashScreenState = splashScreen != null ? splashScreen.saveSplashScreenState() : null;
return savedState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
previousCompletedSplashIsolate = savedState.previousCompletedSplashIsolate;
splashScreenState = savedState.splashScreenState;
}
/**
* Displays the given {@code splashScreen} on top of the given {@code flutterView} until
* Flutter has rendered its first frame, then the {@code splashScreen} is transitioned away.
......@@ -259,17 +273,14 @@ public class FlutterSplashView extends FrameLayout {
public static class SavedState extends BaseSavedState {
public static Creator CREATOR = new Creator() {
@Override
public SavedState createFromParcel(Parcel source) {
return new SavedState(source);
public FlutterSplashView.SavedState createFromParcel(Parcel source) {
return new FlutterSplashView.SavedState(source);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
public FlutterSplashView.SavedState[] newArray(int size) {
return new FlutterSplashView.SavedState[size];
}
};
private String previousCompletedSplashIsolate;
private Bundle splashScreenState;
......@@ -279,20 +290,23 @@ public class FlutterSplashView extends FrameLayout {
SavedState(Parcel source) {
super(source);
previousCompletedSplashIsolate = source.readString();
splashScreenState = source.readBundle(getClass().getClassLoader());
this.previousCompletedSplashIsolate = source.readString();
this.splashScreenState = source.readBundle(this.getClass().getClassLoader());
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeString(previousCompletedSplashIsolate);
out.writeBundle(splashScreenState);
out.writeString(this.previousCompletedSplashIsolate);
out.writeBundle(this.splashScreenState);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
handler.removeCallbacksAndMessages(null);
}
public void onAttach() {
Debuger.log("BoostFlutterView onAttach");
......
......@@ -228,7 +228,7 @@ public class NewBoostFlutterActivity extends Activity
}
@NonNull
private View createFlutterView() {
protected View createFlutterView() {
return delegate.onCreateView(
null /* inflater */,
null /* container */,
......
......@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'container/boost_container.dart';
......@@ -60,6 +61,26 @@ class FlutterBoost {
PrePushRoute prePush,
PostPushRoute postPush}) {
if(Platform.isAndroid){
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) {
assert(child is Navigator, 'child must be Navigator, what is wrong?');
......
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