Commit 3a7185d0 authored by justin's avatar justin

1.22适配

parent ec7c6e0b
...@@ -27,7 +27,7 @@ android { ...@@ -27,7 +27,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 28
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
} }
lintOptions { lintOptions {
disable 'InvalidPackage' disable 'InvalidPackage'
...@@ -35,10 +35,10 @@ android { ...@@ -35,10 +35,10 @@ android {
} }
dependencies { dependencies {
compileOnly 'com.android.support:appcompat-v7:28.0.0' compileOnly 'androidx.appcompat:appcompat:1.0.0'
compileOnly 'com.android.support:design:28.0.0' compileOnly 'com.google.android.material:material:1.0.0'
compileOnly 'com.android.support:support-v4:28.0.0' compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'android.arch.lifecycle:common-java8:1.1.1' implementation 'androidx.lifecycle:lifecycle-common-java8:2.0.0'
compileOnly 'com.alibaba:fastjson:1.2.41' compileOnly 'com.alibaba:fastjson:1.2.41'
} }
......
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
...@@ -2,7 +2,7 @@ package com.idlefish.flutterboost; ...@@ -2,7 +2,7 @@ package com.idlefish.flutterboost;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import com.idlefish.flutterboost.interfaces.IContainerRecord; import com.idlefish.flutterboost.interfaces.IContainerRecord;
import io.flutter.Log; import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.FlutterPlugin;
......
...@@ -6,7 +6,7 @@ import android.app.Application; ...@@ -6,7 +6,7 @@ import android.app.Application;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import com.idlefish.flutterboost.interfaces.*; import com.idlefish.flutterboost.interfaces.*;
...@@ -355,7 +355,7 @@ public class FlutterBoost { ...@@ -355,7 +355,7 @@ public class FlutterBoost {
mEngine = new FlutterEngine(mPlatform.getApplication().getApplicationContext(),FlutterLoader.getInstance(),new FlutterJNI(),null,false); mEngine = new FlutterEngine(mPlatform.getApplication().getApplicationContext(),FlutterLoader.getInstance(),new FlutterJNI(),null,false);
} }
// registerPlugins(mEngine); registerPlugins(mEngine);
// mRegistry = new BoostPluginRegistry(createEngine()); // mRegistry = new BoostPluginRegistry(createEngine());
// mPlatform.registerPlugins(mRegistry); // mPlatform.registerPlugins(mRegistry);
} }
......
package com.idlefish.flutterboost; package com.idlefish.flutterboost;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.os.Handler;
import android.util.Log; import android.util.Log;
import com.idlefish.flutterboost.interfaces.IContainerRecord; import com.idlefish.flutterboost.interfaces.IContainerRecord;
......
package com.idlefish.flutterboost;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import io.flutter.embedding.engine.systemchannels.KeyEventChannel;
import io.flutter.plugin.editing.TextInputPlugin;
public class XAndroidKeyProcessor {
@NonNull
private final KeyEventChannel keyEventChannel;
@NonNull
private final XTextInputPlugin textInputPlugin;
private int combiningCharacter;
public XAndroidKeyProcessor(@NonNull KeyEventChannel keyEventChannel, @NonNull XTextInputPlugin textInputPlugin) {
this.keyEventChannel = keyEventChannel;
this.textInputPlugin = textInputPlugin;
}
public void onKeyUp(@NonNull KeyEvent keyEvent) {
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar());
keyEventChannel.keyUp(
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter)
);
}
public void onKeyDown(@NonNull KeyEvent keyEvent) {
if (textInputPlugin.getLastInputConnection() != null
&& textInputPlugin.getInputMethodManager().isAcceptingText()) {
textInputPlugin.getLastInputConnection().sendKeyEvent(keyEvent);
}
Character complexCharacter = applyCombiningCharacterToBaseCharacter(keyEvent.getUnicodeChar());
keyEventChannel.keyDown(
new KeyEventChannel.FlutterKeyEvent(keyEvent, complexCharacter)
);
}
/**
* Applies the given Unicode character in {@code newCharacterCodePoint} to a previously
* entered Unicode combining character and returns the combination of these characters
* if a combination exists.
* <p>
* This method mutates {@link #combiningCharacter} over time to combine characters.
* <p>
* One of the following things happens in this method:
* <ul>
* <li>If no previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is not a combining character, then {@code newCharacterCodePoint} is returned.</li>
* <li>If no previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is a combining character, then {@code newCharacterCodePoint} is saved as the
* {@link #combiningCharacter} and null is returned.</li>
* <li>If a previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is also a combining character, then the {@code newCharacterCodePoint} is combined with
* the existing {@link #combiningCharacter} and null is returned.</li>
* <li>If a previous {@link #combiningCharacter} exists and the {@code newCharacterCodePoint}
* is not a combining character, then the {@link #combiningCharacter} is applied to the
* regular {@code newCharacterCodePoint} and the resulting complex character is returned. The
* {@link #combiningCharacter} is cleared.</li>
* </ul>
* <p>
* The following reference explains the concept of a "combining character":
* https://en.wikipedia.org/wiki/Combining_character
*/
@Nullable
private Character applyCombiningCharacterToBaseCharacter(int newCharacterCodePoint) {
if (newCharacterCodePoint == 0) {
return null;
}
Character complexCharacter = (char) newCharacterCodePoint;
boolean isNewCodePointACombiningCharacter = (newCharacterCodePoint & KeyCharacterMap.COMBINING_ACCENT) != 0;
if (isNewCodePointACombiningCharacter) {
// If a combining character was entered before, combine this one with that one.
int plainCodePoint = newCharacterCodePoint & KeyCharacterMap.COMBINING_ACCENT_MASK;
if (combiningCharacter != 0) {
combiningCharacter = KeyCharacterMap.getDeadChar(combiningCharacter, plainCodePoint);
} else {
combiningCharacter = plainCodePoint;
}
} else {
// The new character is a regular character. Apply combiningCharacter to it, if it exists.
if (combiningCharacter != 0) {
int combinedChar = KeyCharacterMap.getDeadChar(combiningCharacter, newCharacterCodePoint);
if (combinedChar > 0) {
complexCharacter = (char) combinedChar;
}
combiningCharacter = 0;
}
}
return complexCharacter;
}
}
\ No newline at end of file
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.RenderSurface;
public class XFlutterTextureView extends TextureView implements RenderSurface {
private static final String TAG = "FlutterTextureView";
private boolean isSurfaceAvailableForRendering = false;
private boolean isAttachedToFlutterRenderer = false;
@Nullable
private FlutterRenderer flutterRenderer;
private Surface renderSurface;
// Connects the {@code SurfaceTexture} beneath this {@code TextureView} with Flutter's native code.
// Callbacks are received by this Object and then those messages are forwarded to our
// FlutterRenderer, and then on to the JNI bridge over to native Flutter code.
private final SurfaceTextureListener surfaceTextureListener = new SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Log.v(TAG, "SurfaceTextureListener.onSurfaceTextureAvailable()");
isSurfaceAvailableForRendering = true;
// If we're already attached to a FlutterRenderer then we're now attached to both a renderer
// and the Android window, so we can begin rendering now.
if (isAttachedToFlutterRenderer) {
connectSurfaceToRenderer();
}
}
@Override
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {
Log.v(TAG, "SurfaceTextureListener.onSurfaceTextureSizeChanged()");
if (isAttachedToFlutterRenderer) {
changeSurfaceSize(width, height);
}
}
@Override
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
// Invoked every time a new frame is available. We don't care.
}
@Override
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
Log.v(TAG, "SurfaceTextureListener.onSurfaceTextureDestroyed()");
isSurfaceAvailableForRendering = false;
// If we're attached to a FlutterRenderer then we need to notify it that our SurfaceTexture
// has been destroyed.
if (isAttachedToFlutterRenderer) {
disconnectSurfaceFromRenderer();
}
// Return true to indicate that no further painting will take place
// within this SurfaceTexture.
return true;
}
};
/**
* Constructs a {@code FlutterTextureView} programmatically, without any XML attributes.
*/
public XFlutterTextureView(@NonNull Context context) {
this(context, null);
}
/**
* Constructs a {@code FlutterTextureView} in an XML-inflation-compliant manner.
*/
public XFlutterTextureView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// Listen for when our underlying SurfaceTexture becomes available, changes size, or
// gets destroyed, and take the appropriate actions.
setSurfaceTextureListener(surfaceTextureListener);
}
@Nullable
@Override
public FlutterRenderer getAttachedRenderer() {
return flutterRenderer;
}
/**
* Invoked by the owner of this {@code FlutterTextureView} when it wants to begin rendering
* a Flutter UI to this {@code FlutterTextureView}.
*
* If an Android {@link SurfaceTexture} is available, this method will give that
* {@link SurfaceTexture} to the given {@link FlutterRenderer} to begin rendering
* Flutter's UI to this {@code FlutterTextureView}.
*
* If no Android {@link SurfaceTexture} is available yet, this {@code FlutterTextureView}
* will wait until a {@link SurfaceTexture} becomes available and then give that
* {@link SurfaceTexture} to the given {@link FlutterRenderer} to begin rendering
* Flutter's UI to this {@code FlutterTextureView}.
*/
public void attachToRenderer(@NonNull FlutterRenderer flutterRenderer) {
Log.v(TAG, "Attaching to FlutterRenderer.");
if (this.flutterRenderer != null) {
Log.v(TAG, "Already connected to a FlutterRenderer. Detaching from old one and attaching to new one.");
this.flutterRenderer.stopRenderingToSurface();
}
this.flutterRenderer = flutterRenderer;
isAttachedToFlutterRenderer = true;
// If we're already attached to an Android window then we're now attached to both a renderer
// and the Android window. We can begin rendering now.
if (isSurfaceAvailableForRendering) {
Log.v(TAG, "Surface is available for rendering. Connecting FlutterRenderer to Android surface.");
connectSurfaceToRenderer();
}
}
/**
* Invoked by the owner of this {@code FlutterTextureView} when it no longer wants to render
* a Flutter UI to this {@code FlutterTextureView}.
*
* This method will cease any on-going rendering from Flutter to this {@code FlutterTextureView}.
*/
public void detachFromRenderer() {
if (flutterRenderer != null) {
// If we're attached to an Android window then we were rendering a Flutter UI. Now that
// this FlutterTextureView is detached from the FlutterRenderer, we need to stop rendering.
// TODO(mattcarroll): introduce a isRendererConnectedToSurface() to wrap "getWindowToken() != null"
if (getWindowToken() != null) {
Log.v(TAG, "Disconnecting FlutterRenderer from Android surface.");
disconnectSurfaceFromRenderer();
}
flutterRenderer = null;
isAttachedToFlutterRenderer = false;
} else {
Log.w(TAG, "detachFromRenderer() invoked when no FlutterRenderer was attached.");
}
}
// FlutterRenderer and getSurfaceTexture() must both be non-null.
private void connectSurfaceToRenderer() {
if (flutterRenderer == null || getSurfaceTexture() == null) {
throw new IllegalStateException("connectSurfaceToRenderer() should only be called when flutterRenderer and getSurfaceTexture() are non-null.");
}
// flutterRenderer.startRenderingToSurface(new Surface(getSurfaceTexture()));
renderSurface = new Surface(getSurfaceTexture());
flutterRenderer.startRenderingToSurface(renderSurface);
}
// FlutterRenderer must be non-null.
private void changeSurfaceSize(int width, int height) {
if (flutterRenderer == null) {
throw new IllegalStateException("changeSurfaceSize() should only be called when flutterRenderer is non-null.");
}
Log.v(TAG, "Notifying FlutterRenderer that Android surface size has changed to " + width + " x " + height);
flutterRenderer.surfaceChanged(width, height);
}
// FlutterRenderer must be non-null.
private void disconnectSurfaceFromRenderer() {
if (flutterRenderer == null) {
throw new IllegalStateException("disconnectSurfaceFromRenderer() should only be called when flutterRenderer is non-null.");
}
flutterRenderer.stopRenderingToSurface();
if(renderSurface!=null){
renderSurface.release();
renderSurface = null;
}
}
}
\ No newline at end of file
...@@ -2,9 +2,9 @@ package com.idlefish.flutterboost.containers; ...@@ -2,9 +2,9 @@ package com.idlefish.flutterboost.containers;
import android.app.Activity; import android.app.Activity;
import android.arch.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import android.arch.lifecycle.LifecycleRegistry; import androidx.lifecycle.LifecycleRegistry;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
...@@ -15,13 +15,11 @@ import android.graphics.drawable.ColorDrawable; ...@@ -15,13 +15,11 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
import com.idlefish.flutterboost.FlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import com.idlefish.flutterboost.interfaces.IFlutterViewContainer; import com.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import io.flutter.Log; import io.flutter.Log;
...@@ -58,8 +56,6 @@ public class BoostFlutterActivity extends Activity ...@@ -58,8 +56,6 @@ public class BoostFlutterActivity extends Activity
// Default configuration. // Default configuration.
protected static final String DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque.name(); protected static final String DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque.name();
private static XPlatformPlugin sXPlatformPlugin;
public static Intent createDefaultIntent(@NonNull Context launchContext) { public static Intent createDefaultIntent(@NonNull Context launchContext) {
return withNewEngine().build(launchContext); return withNewEngine().build(launchContext);
} }
...@@ -247,7 +243,7 @@ public class BoostFlutterActivity extends Activity ...@@ -247,7 +243,7 @@ public class BoostFlutterActivity extends Activity
} }
protected XFlutterView getFlutterView() { protected FlutterView getFlutterView() {
return delegate.getFlutterView(); return delegate.getFlutterView();
} }
...@@ -445,9 +441,13 @@ public class BoostFlutterActivity extends Activity ...@@ -445,9 +441,13 @@ public class BoostFlutterActivity extends Activity
} }
@Nullable @Nullable
@Override public PlatformPlugin providePlatformPlugin(
public XPlatformPlugin providePlatformPlugin(@NonNull FlutterEngine flutterEngine) { @Nullable Activity activity, @NonNull FlutterEngine flutterEngine) {
return BoostViewUtils.getPlatformPlugin(flutterEngine.getPlatformChannel()); if (activity != null) {
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
} }
/** /**
......
package com.idlefish.flutterboost.containers;
import com.idlefish.flutterboost.XPlatformPlugin;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
class BoostViewUtils {
private static volatile XPlatformPlugin mInstance;
private BoostViewUtils() {
}
public static XPlatformPlugin getPlatformPlugin(PlatformChannel channel) {
if (mInstance == null) {
synchronized (BoostViewUtils.class) {
if (mInstance == null) {
mInstance = new XPlatformPlugin(channel);
}
}
}
return mInstance;
}
}
...@@ -2,15 +2,14 @@ package com.idlefish.flutterboost.containers; ...@@ -2,15 +2,14 @@ package com.idlefish.flutterboost.containers;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.arch.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.view.*; import android.view.*;
import java.io.Serializable; import java.io.Serializable;
...@@ -21,9 +20,6 @@ import java.util.Map; ...@@ -21,9 +20,6 @@ import java.util.Map;
import com.idlefish.flutterboost.FlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Utils; import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import com.idlefish.flutterboost.interfaces.IContainerRecord;
import com.idlefish.flutterboost.interfaces.IFlutterViewContainer; import com.idlefish.flutterboost.interfaces.IFlutterViewContainer;
import com.idlefish.flutterboost.interfaces.IOperateSyncer; import com.idlefish.flutterboost.interfaces.IOperateSyncer;
import io.flutter.Log; import io.flutter.Log;
...@@ -48,9 +44,9 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -48,9 +44,9 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
@Nullable @Nullable
private FlutterSplashView flutterSplashView; private FlutterSplashView flutterSplashView;
@Nullable @Nullable
private XFlutterView flutterView; private FlutterView flutterView;
@Nullable @Nullable
private XPlatformPlugin platformPlugin; private PlatformPlugin platformPlugin;
private boolean isFlutterEngineFromHost; private boolean isFlutterEngineFromHost;
...@@ -75,7 +71,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -75,7 +71,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
return flutterEngine; return flutterEngine;
} }
public XFlutterView getFlutterView() { public FlutterView getFlutterView() {
return flutterView; return flutterView;
} }
...@@ -96,7 +92,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -96,7 +92,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
// TODO(mattcarroll): the PlatformPlugin needs to be reimagined because it implicitly takes // TODO(mattcarroll): the PlatformPlugin needs to be reimagined because it implicitly takes
// control of the entire window. This is unacceptable for non-fullscreen // control of the entire window. This is unacceptable for non-fullscreen
// use-cases. // use-cases.
platformPlugin = host.providePlatformPlugin(flutterEngine); platformPlugin = host.providePlatformPlugin(host.getActivity(), flutterEngine);
host.configureFlutterEngine(flutterEngine); host.configureFlutterEngine(flutterEngine);
...@@ -133,7 +129,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -133,7 +129,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this); mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this);
ensureAlive(); ensureAlive();
flutterView = new XFlutterView(host.getActivity(), FlutterBoost.instance().platform().renderMode(), host.getTransparencyMode()); flutterView = new FlutterView(host.getActivity(), FlutterBoost.instance().platform().renderMode(), host.getTransparencyMode());
flutterSplashView = new FlutterSplashView(host.getContext()); flutterSplashView = new FlutterSplashView(host.getContext());
...@@ -183,17 +179,22 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -183,17 +179,22 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
} }
if(platformPlugin!=null)
platformPlugin.attachToActivity( host.getActivity());
} }
public void onPostResume() { void onPostResume() {
Log.v(TAG, "onPostResume()"); Log.v(TAG, "onPostResume()");
ensureAlive(); ensureAlive();
if (flutterEngine != null) {
if (platformPlugin != null) {
platformPlugin.updateSystemUiOverlays();
}
} else {
Log.w(TAG, "onPostResume() invoked before FlutterFragment was attached to an Activity.");
}
} }
...@@ -219,22 +220,17 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -219,22 +220,17 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
ensureAlive(); ensureAlive();
flutterView.release(); // flutterView.release();
} }
public void onDetach() { public void onDetach() {
Log.v(TAG, "onDetach()"); Log.v(TAG, "onDetach()");
ensureAlive(); ensureAlive();
// Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment,
// and this Fragment's Activity.
if (platformPlugin != null) { if (platformPlugin != null) {
platformPlugin.detachActivity(getContextActivity()); platformPlugin.destroy();
platformPlugin = null; platformPlugin = null;
} }
if(ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE!=0 && if(ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE!=0 &&
ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE==this.host.getActivity().hashCode()){ ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE==this.host.getActivity().hashCode()){
flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges(); flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
...@@ -244,11 +240,22 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -244,11 +240,22 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
} }
// public void onBackPressed() {
// ensureAlive();
// if (flutterEngine != null) {
// Log.v(TAG, "Forwarding onBackPressed() to FlutterEngine.");
// flutterEngine.getNavigationChannel().popRoute();
// } else {
// Log.w(TAG, "Invoked onBackPressed() before FlutterFragment was attached to an Activity.");
// }
// }
public void onBackPressed() { public void onBackPressed() {
mSyncer.onBackPressed(); mSyncer.onBackPressed();
ensureAlive(); ensureAlive();
} }
...@@ -466,9 +473,8 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -466,9 +473,8 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
* Hook for the host to create/provide a {@link PlatformPlugin} if the associated * Hook for the host to create/provide a {@link PlatformPlugin} if the associated
* Flutter experience should control system chrome. * Flutter experience should control system chrome.
*/ */
@Nullable PlatformPlugin providePlatformPlugin(
XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine); @Nullable Activity activity, @NonNull FlutterEngine flutterEngine);
/** /**
* Hook for the host to configure the {@link FlutterEngine} as desired. * Hook for the host to configure the {@link FlutterEngine} as desired.
*/ */
......
package com.idlefish.flutterboost.containers; package com.idlefish.flutterboost.containers;
import android.app.Activity; import android.app.Activity;
import android.arch.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v4.app.Fragment; import androidx.fragment.app.Fragment;
import android.support.v4.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.idlefish.flutterboost.FlutterBoost; import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import io.flutter.embedding.android.*; import io.flutter.embedding.android.*;
import io.flutter.embedding.engine.FlutterEngine; import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterShellArgs; import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.plugin.platform.PlatformPlugin;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -233,7 +232,7 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm ...@@ -233,7 +232,7 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm
private FlutterActivityAndFragmentDelegate delegate; private FlutterActivityAndFragmentDelegate delegate;
protected XFlutterView getFlutterView() { protected FlutterView getFlutterView() {
return delegate.getFlutterView(); return delegate.getFlutterView();
} }
...@@ -467,8 +466,13 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm ...@@ -467,8 +466,13 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm
@Nullable @Nullable
@Override @Override
public XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine) { public PlatformPlugin providePlatformPlugin(
return BoostViewUtils.getPlatformPlugin(flutterEngine.getPlatformChannel()); @Nullable Activity activity, @NonNull FlutterEngine flutterEngine) {
if (activity != null) {
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
} }
/** /**
......
...@@ -4,8 +4,8 @@ import android.content.Context; ...@@ -4,8 +4,8 @@ import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
...@@ -29,7 +29,7 @@ public class FlutterSplashView extends FrameLayout { ...@@ -29,7 +29,7 @@ public class FlutterSplashView extends FrameLayout {
@Nullable @Nullable
private SplashScreen splashScreen; private SplashScreen splashScreen;
@Nullable @Nullable
private XFlutterView flutterView; private FlutterView flutterView;
@Nullable @Nullable
private View splashScreenView; private View splashScreenView;
@Nullable @Nullable
...@@ -103,7 +103,7 @@ public class FlutterSplashView extends FrameLayout { ...@@ -103,7 +103,7 @@ public class FlutterSplashView extends FrameLayout {
* If no {@code splashScreen} is provided, this {@code FlutterSplashView} displays the * If no {@code splashScreen} is provided, this {@code FlutterSplashView} displays the
* given {@code flutterView} on its own. * given {@code flutterView} on its own.
*/ */
public void displayFlutterViewWithSplash(@NonNull XFlutterView flutterView, @Nullable SplashScreen splashScreen) { public void displayFlutterViewWithSplash(@NonNull FlutterView flutterView, @Nullable SplashScreen splashScreen) {
// If we were displaying a previous FlutterView, remove it. // If we were displaying a previous FlutterView, remove it.
if (this.flutterView != null) { if (this.flutterView != null) {
this.flutterView.removeOnFirstFrameRenderedListener(onFirstFrameRenderedListener); this.flutterView.removeOnFirstFrameRenderedListener(onFirstFrameRenderedListener);
......
...@@ -25,7 +25,7 @@ apply plugin: 'com.android.application' ...@@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
compileSdkVersion 28 compileSdkVersion 29
lintOptions { lintOptions {
disable 'InvalidPackage' disable 'InvalidPackage'
...@@ -38,7 +38,7 @@ android { ...@@ -38,7 +38,7 @@ android {
targetSdkVersion 28 targetSdkVersion 28
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
} }
buildTypes { buildTypes {
...@@ -56,11 +56,11 @@ flutter { ...@@ -56,11 +56,11 @@ flutter {
dependencies { dependencies {
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'com.android.support:design:28.0.0' implementation 'com.google.android.material:material:1.0.0'
implementation 'com.android.support:support-v4:28.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.alibaba:fastjson:1.2.41' implementation 'com.alibaba:fastjson:1.2.41'
} }
...@@ -3,10 +3,10 @@ package com.taobao.idlefish.flutterboostexample; ...@@ -3,10 +3,10 @@ package com.taobao.idlefish.flutterboostexample;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.os.Build; import android.os.Build;
import android.support.annotation.NonNull; import androidx.annotation.NonNull;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import android.support.v4.view.ViewCompat; import androidx.core.view.ViewCompat;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
......
...@@ -6,9 +6,9 @@ import android.graphics.Color; ...@@ -6,9 +6,9 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v7.app.ActionBar; import androidx.appcompat.app.ActionBar;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
......
package com.taobao.idlefish.flutterboostexample; package com.taobao.idlefish.flutterboostexample;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
......
package com.taobao.idlefish.flutterboostexample; package com.taobao.idlefish.flutterboostexample;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import androidx.annotation.Nullable;
import android.support.v7.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
......
...@@ -5,7 +5,7 @@ buildscript { ...@@ -5,7 +5,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.1.2' classpath 'com.android.tools.build:gradle:3.2.0'
} }
} }
......
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.enableR8=true android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
...@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
...@@ -18,7 +18,8 @@ class _MyAppState extends State<MyApp> { ...@@ -18,7 +18,8 @@ class _MyAppState extends State<MyApp> {
super.initState(); super.initState();
FlutterBoost.singleton.registerPageBuilders({ FlutterBoost.singleton.registerPageBuilders({
'embeded': (pageName, params, _)=>EmbededFirstRouteWidget(), '/': (pageName, params, _) => Container(),
'embeded': (pageName, params, _) => EmbededFirstRouteWidget(),
'first': (pageName, params, _) => FirstRouteWidget(), 'first': (pageName, params, _) => FirstRouteWidget(),
'firstFirst': (pageName, params, _) => FirstFirstRouteWidget(), 'firstFirst': (pageName, params, _) => FirstFirstRouteWidget(),
'second': (pageName, params, _) => SecondRouteWidget(), 'second': (pageName, params, _) => SecondRouteWidget(),
...@@ -26,49 +27,77 @@ class _MyAppState extends State<MyApp> { ...@@ -26,49 +27,77 @@ class _MyAppState extends State<MyApp> {
'tab': (pageName, params, _) => TabRouteWidget(), 'tab': (pageName, params, _) => TabRouteWidget(),
'platformView': (pageName, params, _) => PlatformRouteWidget(), 'platformView': (pageName, params, _) => PlatformRouteWidget(),
'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params), 'flutterFragment': (pageName, params, _) => FragmentRouteWidget(params),
///可以在native层通过 getContainerParams 来传递参数 ///可以在native层通过 getContainerParams 来传递参数
'flutterPage': (pageName, params, _) { 'flutterPage': (pageName, params, _) {
print("flutterPage params:$params"); print("flutterPage params:$params");
return FlutterRouteWidget(params:params); return FlutterRouteWidget(params: params);
}, },
'f2f_first': (pageName, params, _) => F2FFirstPage(), 'f2f_first': (pageName, params, _) => F2FFirstPage(),
'f2f_second': (pageName, params, _) => F2FSecondPage(), 'f2f_second': (pageName, params, _) => F2FSecondPage(),
}); });
FlutterBoost.singleton.addBoostNavigatorObserver(TestBoostNavigatorObserver()); FlutterBoost.singleton
FlutterBoost.singleton.addContainerObserver(( .addBoostNavigatorObserver(TestBoostNavigatorObserver());
ContainerOperation operation, BoostContainerSettings settings){ FlutterBoost.singleton.addContainerObserver(
(ContainerOperation operation, BoostContainerSettings settings) {
operation; operation;
settings; settings;
}); });
FlutterBoostAPI.singleton.routeSettingsBuilder = (String url, FlutterBoostAPI.singleton.routeSettingsBuilder = (String url,
{Map<String, dynamic> urlParams, Map<String, dynamic> exts}) => BoostRouteSettings( {Map<String, dynamic> urlParams, Map<String, dynamic> exts}) =>
uniqueId: '${url}_${DateTime.now().millisecondsSinceEpoch}', BoostRouteSettings(
name: url, uniqueId: '${url}_${DateTime.now().millisecondsSinceEpoch}',
params: urlParams, name: url,
); params: urlParams,
);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return WidgetsApp(
title: 'Flutter Boost example', title: 'Flutter Boost example',
builder: FlutterBoost.init(postPush: _onRoutePushed), builder: FlutterBoost.init(postPush: _onRoutePushed),
home: Container( color: Colors.white,
color:Colors.white localizationsDelegates: [DefaultMaterialLocalizations.delegate],
)); onUnknownRoute:(RouteSettings settings){
if(settings.name=="/")
return unKnownRoute( settings);
},
// home: Container(),
);
} }
Route unKnownRoute(RouteSettings settings){
void _onRoutePushed( return new PageRouteBuilder<dynamic>(
String pageName, String uniqueId, Map params, Route route, Future _) { pageBuilder: (BuildContext context,Animation<double> animation,
Animation<double> secondaryAnimation){
return new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text("First Page",textDirection: TextDirection.ltr,),
const Padding(padding: const EdgeInsets.all(10.0)),
new GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: new Container(
padding: const EdgeInsets.all(10.0),
color:Colors.blue,
child: const Text("Back"),
),
)
]
);
}
);
} }
void _onRoutePushed(
String pageName, String uniqueId, Map params, Route route, Future _) {}
} }
class TestBoostNavigatorObserver extends ContainerNavigatorObserver{ class TestBoostNavigatorObserver extends ContainerNavigatorObserver {
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
route.settings.name!="/"; route.settings.name != "/";
//1. 底下 //1. 底下
//新页面已经push完成 //新页面已经push完成
...@@ -86,10 +115,8 @@ class TestBoostNavigatorObserver extends ContainerNavigatorObserver{ ...@@ -86,10 +115,8 @@ class TestBoostNavigatorObserver extends ContainerNavigatorObserver{
void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) { void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
print("flutterboost#didReplace"); print("flutterboost#didReplace");
} }
void willPush(Route<dynamic> route, Route<dynamic> previousRoute) {
void willPush(Route<dynamic> route, Route<dynamic> previousRoute) {
print("flutterboost#willPush"); print("flutterboost#willPush");
} }
} }
...@@ -183,6 +183,9 @@ class BoostContainerState extends NavigatorState { ...@@ -183,6 +183,9 @@ class BoostContainerState extends NavigatorState {
@override @override
Future<bool> maybePop<T extends Object>([T result]) async { Future<bool> maybePop<T extends Object>([T result]) async {
if(routerHistory.isEmpty)
pop(result);
final Route<T> route = routerHistory.last; final Route<T> route = routerHistory.last;
final RoutePopDisposition disposition = await route.willPop(); final RoutePopDisposition disposition = await route.willPop();
if (mounted) { if (mounted) {
......
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