Commit 7a6ee43a authored by justin's avatar justin

泄漏问题修改

parent 0d11a6a2
...@@ -22,7 +22,7 @@ rootProject.allprojects { ...@@ -22,7 +22,7 @@ rootProject.allprojects {
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
android { android {
compileSdkVersion 28 compileSdkVersion 29
buildToolsVersion '27.0.3' buildToolsVersion '27.0.3'
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
......
package com.idlefish.flutterboost;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.NonNull;
import android.view.HapticFeedbackConstants;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.Window;
import java.util.ArrayList;
import java.util.List;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
public class XPlatformPlugin {
public static final int DEFAULT_SYSTEM_UI = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
private Activity activity;
private PlatformChannel platformChannel;
private PlatformChannel.SystemChromeStyle currentTheme;
private int mEnabledOverlays;
private PlatformChannel.PlatformMessageHandler mPlatformMessageHandler = new PlatformChannel.PlatformMessageHandler() {
@Override
public void playSystemSound(@NonNull PlatformChannel.SoundType soundType) {
XPlatformPlugin.this.playSystemSound(soundType);
}
@Override
public void vibrateHapticFeedback(@NonNull PlatformChannel.HapticFeedbackType feedbackType) {
XPlatformPlugin.this.vibrateHapticFeedback(feedbackType);
}
@Override
public void setPreferredOrientations(int androidOrientation) {
setSystemChromePreferredOrientations(androidOrientation);
}
@Override
public void setApplicationSwitcherDescription(@NonNull PlatformChannel.AppSwitcherDescription description) {
setSystemChromeApplicationSwitcherDescription(description);
}
@Override
public void showSystemOverlays(@NonNull List<PlatformChannel.SystemUiOverlay> overlays) {
setSystemChromeEnabledSystemUIOverlays(overlays);
}
@Override
public void restoreSystemUiOverlays() {
restoreSystemChromeSystemUIOverlays();
}
@Override
public void setSystemUiOverlayStyle(@NonNull PlatformChannel.SystemChromeStyle systemUiOverlayStyle) {
setSystemChromeSystemUIOverlayStyle(systemUiOverlayStyle);
}
@Override
public void popSystemNavigator() {
XPlatformPlugin.this.popSystemNavigator();
}
@Override
public CharSequence getClipboardData(@Nullable PlatformChannel.ClipboardContentFormat format) {
return XPlatformPlugin.this.getClipboardData(format);
}
@Override
public void setClipboardData(@NonNull String text) {
XPlatformPlugin.this.setClipboardData(text);
}
@Override
public List<Rect> getSystemGestureExclusionRects() {
return XPlatformPlugin.this.getSystemGestureExclusionRects();
}
@Override
public void setSystemGestureExclusionRects(@NonNull ArrayList<Rect> rects) {
XPlatformPlugin.this.setSystemGestureExclusionRects(rects);
}
};
public XPlatformPlugin( PlatformChannel platformChannel) {
this.platformChannel = platformChannel;
mEnabledOverlays = DEFAULT_SYSTEM_UI;
}
public void attachToActivity(Activity activity ){
this.activity = activity;
this.platformChannel.setPlatformMessageHandler(mPlatformMessageHandler);
}
/**
* Releases all resources held by this {@code PlatformPlugin}.
* <p>
* Do not invoke any methods on a {@code PlatformPlugin} after invoking this method.
*/
public void detachActivity() {
this.activity=null;
this.mPlatformMessageHandler=null;
}
private void playSystemSound(PlatformChannel.SoundType soundType) {
if (soundType == PlatformChannel.SoundType.CLICK) {
View view = activity.getWindow().getDecorView();
view.playSoundEffect(SoundEffectConstants.CLICK);
}
}
private void vibrateHapticFeedback(PlatformChannel.HapticFeedbackType feedbackType) {
View view = activity.getWindow().getDecorView();
switch (feedbackType) {
case STANDARD:
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
break;
case LIGHT_IMPACT:
view.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
break;
case MEDIUM_IMPACT:
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
break;
case HEAVY_IMPACT:
// HapticFeedbackConstants.CONTEXT_CLICK from API level 23.
view.performHapticFeedback(6);
break;
case SELECTION_CLICK:
view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
break;
}
}
private void setSystemChromePreferredOrientations(int androidOrientation) {
activity.setRequestedOrientation(androidOrientation);
}
@SuppressWarnings("deprecation")
private void setSystemChromeApplicationSwitcherDescription(PlatformChannel.AppSwitcherDescription description) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return;
}
// Linter refuses to believe we're only executing this code in API 28 unless we use distinct if blocks and
// hardcode the API 28 constant.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P && Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
activity.setTaskDescription(new ActivityManager.TaskDescription(description.label, /*icon=*/ null, description.color));
}
if (Build.VERSION.SDK_INT >= 28) {
ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription(description.label, 0, description.color);
activity.setTaskDescription(taskDescription);
}
}
private void setSystemChromeEnabledSystemUIOverlays(List<PlatformChannel.SystemUiOverlay> overlaysToShow) {
// Start by assuming we want to hide all system overlays (like an immersive game).
int enabledOverlays = DEFAULT_SYSTEM_UI
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
if (overlaysToShow.size() == 0) {
enabledOverlays |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
// Re-add any desired system overlays.
for (int i = 0; i < overlaysToShow.size(); ++i) {
PlatformChannel.SystemUiOverlay overlayToShow = overlaysToShow.get(i);
switch (overlayToShow) {
case TOP_OVERLAYS:
enabledOverlays &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
break;
case BOTTOM_OVERLAYS:
enabledOverlays &= ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
enabledOverlays &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
break;
}
}
mEnabledOverlays = enabledOverlays;
updateSystemUiOverlays();
}
/**
* Refreshes Android's window system UI (AKA system chrome) to match Flutter's desired
* {@link PlatformChannel.SystemChromeStyle}.
* <p>
* Updating the system UI Overlays is accomplished by altering the decor view of the
* {@link Window} associated with the {@link Activity} that was provided to this
* {@code PlatformPlugin}.
*/
public void updateSystemUiOverlays(){
activity.getWindow().getDecorView().setSystemUiVisibility(mEnabledOverlays);
if (currentTheme != null) {
setSystemChromeSystemUIOverlayStyle(currentTheme);
}
}
private void restoreSystemChromeSystemUIOverlays() {
updateSystemUiOverlays();
}
private void setSystemChromeSystemUIOverlayStyle(PlatformChannel.SystemChromeStyle systemChromeStyle) {
Window window = activity.getWindow();
View view = window.getDecorView();
int flags = view.getSystemUiVisibility();
// You can change the navigation bar color (including translucent colors)
// in Android, but you can't change the color of the navigation buttons until Android O.
// LIGHT vs DARK effectively isn't supported until then.
// Build.VERSION_CODES.O
if (Build.VERSION.SDK_INT >= 26) {
if (systemChromeStyle.systemNavigationBarIconBrightness != null) {
switch (systemChromeStyle.systemNavigationBarIconBrightness) {
case DARK:
//View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
flags |= 0x10;
break;
case LIGHT:
flags &= ~0x10;
break;
}
}
if (systemChromeStyle.systemNavigationBarColor != null) {
window.setNavigationBarColor(systemChromeStyle.systemNavigationBarColor);
}
}
// Build.VERSION_CODES.M
if (Build.VERSION.SDK_INT >= 23) {
if (systemChromeStyle.statusBarIconBrightness != null) {
switch (systemChromeStyle.statusBarIconBrightness) {
case DARK:
// View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
flags |= 0x2000;
break;
case LIGHT:
flags &= ~0x2000;
break;
}
}
if (systemChromeStyle.statusBarColor != null) {
window.setStatusBarColor(systemChromeStyle.statusBarColor);
}
}
if (systemChromeStyle.systemNavigationBarDividerColor != null) {
// Not available until Android P.
// window.setNavigationBarDividerColor(systemNavigationBarDividerColor);
}
view.setSystemUiVisibility(flags);
currentTheme = systemChromeStyle;
}
private void popSystemNavigator() {
activity.finish();
}
private CharSequence getClipboardData(PlatformChannel.ClipboardContentFormat format) {
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = clipboard.getPrimaryClip();
if (clip == null)
return null;
if (format == null || format == PlatformChannel.ClipboardContentFormat.PLAIN_TEXT) {
return clip.getItemAt(0).coerceToText(activity);
}
return null;
}
private void setClipboardData(String text) {
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("text label?", text);
clipboard.setPrimaryClip(clip);
}
private List<Rect> getSystemGestureExclusionRects() {
if (Build.VERSION.SDK_INT >= 29) {
Window window = activity.getWindow();
View view = window.getDecorView();
return view.getSystemGestureExclusionRects();
}
return null;
}
private void setSystemGestureExclusionRects(ArrayList<Rect> rects) {
if (Build.VERSION.SDK_INT < 29) {
return;
}
Window window = activity.getWindow();
View view = window.getDecorView();
view.setSystemGestureExclusionRects(rects);
}
}
...@@ -21,6 +21,7 @@ import android.view.*; ...@@ -21,6 +21,7 @@ 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.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
import io.flutter.Log; import io.flutter.Log;
import io.flutter.embedding.android.DrawableSplashScreen; import io.flutter.embedding.android.DrawableSplashScreen;
import io.flutter.embedding.android.FlutterView; import io.flutter.embedding.android.FlutterView;
...@@ -439,12 +440,8 @@ public class BoostFlutterActivity extends Activity ...@@ -439,12 +440,8 @@ public class BoostFlutterActivity extends Activity
@Nullable @Nullable
@Override @Override
public PlatformPlugin providePlatformPlugin(@Nullable Activity activity, @NonNull FlutterEngine flutterEngine) { public XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine) {
if (activity != null) { return new XPlatformPlugin( flutterEngine.getPlatformChannel());
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
} }
/** /**
......
...@@ -22,6 +22,7 @@ import java.util.Map; ...@@ -22,6 +22,7 @@ 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.XFlutterView;
import com.idlefish.flutterboost.XPlatformPlugin;
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;
...@@ -29,7 +30,7 @@ import io.flutter.app.FlutterActivity; ...@@ -29,7 +30,7 @@ import io.flutter.app.FlutterActivity;
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.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.platform.PlatformPlugin; import io.flutter.plugin.platform.PlatformPlugin;
import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
...@@ -38,7 +39,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -38,7 +39,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
private static final String TAG = "FlutterActivityAndFragmentDelegate"; private static final String TAG = "FlutterActivityAndFragmentDelegate";
private static int ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE=0;
@NonNull @NonNull
private Host host; private Host host;
@Nullable @Nullable
...@@ -48,7 +49,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -48,7 +49,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
@Nullable @Nullable
private XFlutterView flutterView; private XFlutterView flutterView;
@Nullable @Nullable
private PlatformPlugin platformPlugin; private XPlatformPlugin platformPlugin;
private boolean isFlutterEngineFromHost; private boolean isFlutterEngineFromHost;
...@@ -94,7 +95,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -94,7 +95,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(host.getActivity(), flutterEngine); platformPlugin = host.providePlatformPlugin(flutterEngine);
host.configureFlutterEngine(flutterEngine); host.configureFlutterEngine(flutterEngine);
...@@ -128,13 +129,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -128,13 +129,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
Log.v(TAG, "Creating FlutterView."); Log.v(TAG, "Creating FlutterView.");
flutterEngine.getActivityControlSurface().attachToActivity(
host.getActivity(),
host.getLifecycle()
);
mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this); mSyncer = FlutterBoost.instance().containerManager().generateSyncer(this);
ensureAlive(); ensureAlive();
...@@ -175,13 +169,19 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -175,13 +169,19 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
Log.v(TAG, "onResume()"); Log.v(TAG, "onResume()");
ensureAlive(); ensureAlive();
flutterEngine.getLifecycleChannel().appIsResumed(); flutterEngine.getLifecycleChannel().appIsResumed();
if(ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE==0||
flutterEngine.getActivityControlSurface().attachToActivity( ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE!=this.host.getActivity().hashCode()){
host.getActivity(), flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
host.getLifecycle() flutterEngine.getActivityControlSurface().attachToActivity(
); host.getActivity(),
host.getLifecycle()
);
ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE=this.host.getActivity().hashCode();
}
if(platformPlugin!=null)
platformPlugin.attachToActivity( host.getActivity());
} }
...@@ -190,7 +190,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -190,7 +190,6 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
public void onPostResume() { public void onPostResume() {
Log.v(TAG, "onPostResume()"); Log.v(TAG, "onPostResume()");
ensureAlive(); ensureAlive();
// Utils.setStatusBarLightMode(host.getActivity(), true);
} }
...@@ -229,10 +228,15 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -229,10 +228,15 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
// Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment, // Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment,
// and this Fragment's Activity. // and this Fragment's Activity.
if (platformPlugin != null) { if (platformPlugin != null) {
// platformPlugin.destroy(); platformPlugin.detachActivity();
platformPlugin = null; platformPlugin = null;
} }
if(ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE!=0||
ACTIVITY_CONTROL_SURFACE_ATTACH_TO_ACTVITY_HASH_CODE==this.host.getActivity().hashCode()){
flutterEngine.getActivityControlSurface().detachFromActivityForConfigChanges();
}
Utils.fixInputMethodManagerLeak(host.getActivity()); Utils.fixInputMethodManagerLeak(host.getActivity());
} }
...@@ -460,7 +464,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer ...@@ -460,7 +464,7 @@ public class FlutterActivityAndFragmentDelegate implements IFlutterViewContainer
* Flutter experience should control system chrome. * Flutter experience should control system chrome.
*/ */
@Nullable @Nullable
PlatformPlugin providePlatformPlugin(@Nullable Activity activity, @NonNull FlutterEngine flutterEngine); XPlatformPlugin providePlatformPlugin( @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.
......
...@@ -19,6 +19,7 @@ import android.view.ViewGroup; ...@@ -19,6 +19,7 @@ import android.view.ViewGroup;
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.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;
...@@ -470,12 +471,9 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm ...@@ -470,12 +471,9 @@ public class FlutterFragment extends Fragment implements FlutterActivityAndFragm
@Nullable @Nullable
@Override @Override
public PlatformPlugin providePlatformPlugin(@Nullable Activity activity, @NonNull FlutterEngine flutterEngine) { public XPlatformPlugin providePlatformPlugin( @NonNull FlutterEngine flutterEngine) {
if (activity != null) { return new XPlatformPlugin(flutterEngine.getPlatformChannel());
return new PlatformPlugin(getActivity(), flutterEngine.getPlatformChannel());
} else {
return null;
}
} }
/** /**
......
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