Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
flutter_boost_1.22.4
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
谢冠章
flutter_boost_1.22.4
Commits
d9ac3683
Commit
d9ac3683
authored
Oct 09, 2019
by
yangwu.jia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Boost 1.9升级
parent
570f4acb
Changes
32
Show whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
2458 additions
and
228 deletions
+2458
-228
android/build.gradle
android/build.gradle
+6
-3
android/src/main/java/com/idlefish/flutterboost/BoostEngineProvider.java
...n/java/com/idlefish/flutterboost/BoostEngineProvider.java
+13
-12
android/src/main/java/com/idlefish/flutterboost/BoostFlutterEngine.java
...in/java/com/idlefish/flutterboost/BoostFlutterEngine.java
+95
-103
android/src/main/java/com/idlefish/flutterboost/BoostFlutterView.java
...main/java/com/idlefish/flutterboost/BoostFlutterView.java
+7
-6
android/src/main/java/com/idlefish/flutterboost/BoostPluginRegistry.java
...n/java/com/idlefish/flutterboost/BoostPluginRegistry.java
+141
-0
android/src/main/java/com/idlefish/flutterboost/ContainerRecord.java
.../main/java/com/idlefish/flutterboost/ContainerRecord.java
+50
-15
android/src/main/java/com/idlefish/flutterboost/FlutterBoost.java
...src/main/java/com/idlefish/flutterboost/FlutterBoost.java
+12
-12
android/src/main/java/com/idlefish/flutterboost/FlutterBoostPlugin.java
...in/java/com/idlefish/flutterboost/FlutterBoostPlugin.java
+276
-0
android/src/main/java/com/idlefish/flutterboost/FlutterViewContainerManager.java
...om/idlefish/flutterboost/FlutterViewContainerManager.java
+4
-4
android/src/main/java/com/idlefish/flutterboost/NewFlutterBoost.java
.../main/java/com/idlefish/flutterboost/NewFlutterBoost.java
+209
-0
android/src/main/java/com/idlefish/flutterboost/StateListener.java
...rc/main/java/com/idlefish/flutterboost/StateListener.java
+1
-1
android/src/main/java/com/idlefish/flutterboost/XFlutterView.java
...src/main/java/com/idlefish/flutterboost/XFlutterView.java
+3
-3
android/src/main/java/com/idlefish/flutterboost/XTextInputPlugin.java
...main/java/com/idlefish/flutterboost/XTextInputPlugin.java
+8
-0
android/src/main/java/com/idlefish/flutterboost/containers/BoostFlutterActivity.java
...dlefish/flutterboost/containers/BoostFlutterActivity.java
+6
-5
android/src/main/java/com/idlefish/flutterboost/containers/BoostFlutterDefaultActivity.java
.../flutterboost/containers/BoostFlutterDefaultActivity.java
+5
-0
android/src/main/java/com/idlefish/flutterboost/containers/BoostFlutterFragment.java
...dlefish/flutterboost/containers/BoostFlutterFragment.java
+6
-5
android/src/main/java/com/idlefish/flutterboost/containers/FlutterActivityAndFragmentDelegate.java
...rboost/containers/FlutterActivityAndFragmentDelegate.java
+596
-0
android/src/main/java/com/idlefish/flutterboost/containers/FlutterSplashView.java
...m/idlefish/flutterboost/containers/FlutterSplashView.java
+294
-0
android/src/main/java/com/idlefish/flutterboost/containers/NewBoostFlutterActivity.java
...fish/flutterboost/containers/NewBoostFlutterActivity.java
+615
-0
android/src/main/java/com/idlefish/flutterboost/interfaces/IFlutterEngineProvider.java
...efish/flutterboost/interfaces/IFlutterEngineProvider.java
+5
-3
android/src/main/java/com/idlefish/flutterboost/interfaces/IFlutterViewContainer.java
...lefish/flutterboost/interfaces/IFlutterViewContainer.java
+2
-1
android/src/main/java/com/idlefish/flutterboost/interfaces/INativeRouter.java
...a/com/idlefish/flutterboost/interfaces/INativeRouter.java
+13
-0
android/src/main/java/com/idlefish/flutterboost/interfaces/IStateListener.java
.../com/idlefish/flutterboost/interfaces/IStateListener.java
+2
-2
example/android/app/build.gradle
example/android/app/build.gradle
+5
-5
example/android/app/src/main/AndroidManifest.xml
example/android/app/src/main/AndroidManifest.xml
+15
-1
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/FlutterFragment.java
.../taobao/idlefish/flutterboostexample/FlutterFragment.java
+6
-0
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/FlutterPageActivity.java
...bao/idlefish/flutterboostexample/FlutterPageActivity.java
+6
-0
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/MyApplication.java
...om/taobao/idlefish/flutterboostexample/MyApplication.java
+49
-41
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/PageRouter.java
...a/com/taobao/idlefish/flutterboostexample/PageRouter.java
+4
-2
example/ios/Runner/GeneratedPluginRegistrant.m
example/ios/Runner/GeneratedPluginRegistrant.m
+2
-2
example/lib/main.dart
example/lib/main.dart
+1
-1
pubspec.yaml
pubspec.yaml
+1
-1
No files found.
android/build.gradle
View file @
d9ac3683
...
...
@@ -26,6 +26,7 @@ android {
buildToolsVersion
'27.0.3'
defaultConfig
{
minSdkVersion
16
targetSdkVersion
28
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
lintOptions
{
...
...
@@ -34,9 +35,11 @@ android {
}
dependencies
{
implementation
'com.alibaba:fastjson:1.2.41'
implementation
'com.android.support:support-v4:26.1.0'
implementation
'com.android.support:appcompat-v7:26.1.0'
implementation
'com.android.support:appcompat-v7:28.0.0'
implementation
'com.android.support:design:28.0.0'
implementation
'com.android.support:support-v4:28.0.0'
implementation
'android.arch.lifecycle:common-java8:1.1.1'
}
ext
{
...
...
android/src/main/java/com/idlefish/flutterboost/BoostEngineProvider.java
View file @
d9ac3683
...
...
@@ -28,12 +28,13 @@ import android.content.Context;
import
com.idlefish.flutterboost.interfaces.IFlutterEngineProvider
;
import
com.idlefish.flutterboost.interfaces.IStateListener
;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.embedding.engine.FlutterShellArgs
;
import
io.flutter.view.FlutterMain
;
public
class
BoostEngineProvider
implements
IFlutterEngineProvider
{
private
Boost
FlutterEngine
mEngine
=
null
;
private
FlutterEngine
mEngine
=
null
;
public
BoostEngineProvider
()
{}
...
...
@@ -43,7 +44,7 @@ public class BoostEngineProvider implements IFlutterEngineProvider {
}
@Override
public
Boost
FlutterEngine
provideEngine
(
Context
context
)
{
public
FlutterEngine
provideEngine
(
Context
context
)
{
Utils
.
assertCallOnMainThread
();
if
(
mEngine
==
null
)
{
...
...
@@ -51,25 +52,25 @@ public class BoostEngineProvider implements IFlutterEngineProvider {
FlutterMain
.
ensureInitializationComplete
(
context
.
getApplicationContext
(),
flutterShellArgs
.
toArray
());
mEngine
=
create
Engine
(
context
.
getApplicationContext
());
mEngine
=
new
Flutter
Engine
(
context
.
getApplicationContext
());
final
IStateListener
stateListener
=
FlutterBoost
.
sInstance
.
mStateListener
;
if
(
stateListener
!=
null
)
{
stateListener
.
onEngineCreated
(
mEngine
);
}
//
final IStateListener stateListener = FlutterBoost.sInstance.mStateListener;
//
if(stateListener != null) {
//
stateListener.onEngineCreated(mEngine);
//
}
}
return
mEngine
;
}
@Override
public
Boost
FlutterEngine
tryGetEngine
()
{
public
FlutterEngine
tryGetEngine
()
{
return
mEngine
;
}
public
static
void
assertEngineRunning
(){
final
BoostFlutterEngine
engine
=
FlutterBoost
.
singleton
().
engineProvider
().
tryGetEngine
();
if
(
engine
==
null
||
!
engine
.
isRunning
())
{
throw
new
RuntimeException
(
"engine is not running yet!"
);
}
final
FlutterEngine
engine
=
NewFlutterBoost
.
instance
().
engineProvider
().
tryGetEngine
();
//
if(engine == null || !engine.isRunning()) {
//
throw new RuntimeException("engine is not running yet!");
//
}
}
}
android/src/main/java/com/idlefish/flutterboost/BoostFlutterEngine.java
View file @
d9ac3683
...
...
@@ -30,122 +30,114 @@ import io.flutter.view.FlutterView;
import
io.flutter.view.TextureRegistry
;
public
class
BoostFlutterEngine
extends
FlutterEngine
{
protected
final
Context
mContext
;
protected
final
BoostPluginRegistry
mBoostPluginRegistry
;
protected
final
DartExecutor
.
DartEntrypoint
mEntrypoint
;
protected
final
String
mInitRoute
;
private
final
FakeRender
mFakeRender
;
protected
WeakReference
<
Activity
>
mCurrentActivityRef
;
public
BoostFlutterEngine
(
@NonNull
Context
context
)
{
this
(
context
,
null
,
null
);
}
public
BoostFlutterEngine
(
@NonNull
Context
context
,
DartExecutor
.
DartEntrypoint
entrypoint
,
String
initRoute
)
{
super
(
context
);
mContext
=
context
.
getApplicationContext
();
mBoostPluginRegistry
=
new
BoostPluginRegistry
(
this
,
context
);
if
(
entrypoint
!=
null
)
{
mEntrypoint
=
entrypoint
;
}
else
{
mEntrypoint
=
defaultDartEntrypoint
(
context
);
}
if
(
initRoute
!=
null
)
{
mInitRoute
=
initRoute
;
}
else
{
mInitRoute
=
defaultInitialRoute
(
context
);
}
FlutterJNI
flutterJNI
=
null
;
try
{
Field
field
=
FlutterEngine
.
class
.
getDeclaredField
(
"flutterJNI"
);
field
.
setAccessible
(
true
);
flutterJNI
=
(
FlutterJNI
)
field
.
get
(
this
);
}
catch
(
Throwable
t
)
{
try
{
for
(
Field
field:
FlutterEngine
.
class
.
getDeclaredFields
())
{
field
.
setAccessible
(
true
);
Object
o
=
field
.
get
(
this
);
if
(
o
instanceof
FlutterJNI
)
{
flutterJNI
=
(
FlutterJNI
)
o
;
}
}
if
(
flutterJNI
==
null
)
{
throw
new
RuntimeException
(
"FlutterJNI not found"
);
}
}
catch
(
Throwable
it
){
Debuger
.
exception
(
it
);
}
}
mFakeRender
=
new
FakeRender
(
flutterJNI
);
}
public
void
startRun
(
@Nullable
Activity
activity
)
{
mCurrentActivityRef
=
new
WeakReference
<>(
activity
);
if
(!
getDartExecutor
().
isExecutingDart
())
{
Debuger
.
log
(
"engine start running..."
);
getNavigationChannel
().
setInitialRoute
(
mInitRoute
);
getDartExecutor
().
executeDartEntrypoint
(
mEntrypoint
);
final
IStateListener
stateListener
=
FlutterBoost
.
sInstance
.
mStateListener
;
if
(
stateListener
!=
null
)
{
stateListener
.
onEngineStarted
(
this
);
}
FlutterBoost
.
singleton
().
platform
().
registerPlugins
(
mBoostPluginRegistry
);
if
(
activity
!=
null
)
{
FlutterRenderer
.
ViewportMetrics
metrics
=
new
FlutterRenderer
.
ViewportMetrics
();
metrics
.
devicePixelRatio
=
activity
.
getResources
().
getDisplayMetrics
().
density
;
final
View
decor
=
activity
.
getWindow
().
getDecorView
();
if
(
decor
!=
null
)
{
metrics
.
width
=
decor
.
getWidth
();
metrics
.
height
=
decor
.
getHeight
();
}
if
(
metrics
.
width
<=
0
||
metrics
.
height
<=
0
)
{
metrics
.
width
=
Utils
.
getMetricsWidth
(
activity
);
metrics
.
height
=
Utils
.
getMetricsHeight
(
activity
);
}
metrics
.
paddingTop
=
Utils
.
getStatusBarHeight
(
activity
);
metrics
.
paddingRight
=
0
;
metrics
.
paddingBottom
=
0
;
metrics
.
paddingLeft
=
0
;
metrics
.
viewInsetTop
=
0
;
metrics
.
viewInsetRight
=
0
;
metrics
.
viewInsetBottom
=
0
;
metrics
.
viewInsetLeft
=
0
;
getRenderer
().
setViewportMetrics
(
metrics
);
}
}
}
// public BoostFlutterEngine(@NonNull Context context, DartExecutor.DartEntrypoint entrypoint, String initRoute) {
// super(context);
// mContext = context.getApplicationContext();
//// mBoostPluginRegistry = new BoostPluginRegistry(this, context);
//
// if (entrypoint != null) {
// mEntrypoint = entrypoint;
// } else {
// mEntrypoint = defaultDartEntrypoint(context);
// }
//
// if (initRoute != null) {
// mInitRoute = initRoute;
// } else {
// mInitRoute = defaultInitialRoute(context);
// }
//
// FlutterJNI flutterJNI = null;
// try {
// Field field = FlutterEngine.class.getDeclaredField("flutterJNI");
// field.setAccessible(true);
//
// flutterJNI = (FlutterJNI) field.get(this);
// } catch (Throwable t) {
// try {
// for(Field field:FlutterEngine.class.getDeclaredFields()) {
// field.setAccessible(true);
// Object o = field.get(this);
//
// if(o instanceof FlutterJNI) {
// flutterJNI = (FlutterJNI)o;
// }
// }
//
// if(flutterJNI == null) {
// throw new RuntimeException("FlutterJNI not found");
// }
// }catch (Throwable it){
// Debuger.exception(it);
// }
// }
// mFakeRender = new FakeRender(flutterJNI);
// }
// public void startRun(@Nullable Activity activity) {
// mCurrentActivityRef = new WeakReference<>(activity);
//
// if (!getDartExecutor().isExecutingDart()) {
//
// Debuger.log("engine start running...");
//
// getNavigationChannel().setInitialRoute(mInitRoute);
// getDartExecutor().executeDartEntrypoint(mEntrypoint);
//
// final IStateListener stateListener = FlutterBoost.sInstance.mStateListener;
// if (stateListener != null) {
// stateListener.onEngineStarted(this);
// }
//
//// FlutterBoost.singleton().platform().registerPlugins(mBoostPluginRegistry);
//
// if(activity != null) {
// FlutterRenderer.ViewportMetrics metrics = new FlutterRenderer.ViewportMetrics();
// metrics.devicePixelRatio = activity.getResources().getDisplayMetrics().density;
// final View decor = activity.getWindow().getDecorView();
// if(decor != null) {
// metrics.width = decor.getWidth();
// metrics.height = decor.getHeight();
// }
//
// if (metrics.width <= 0 || metrics.height <= 0) {
// metrics.width = Utils.getMetricsWidth(activity);
// metrics.height = Utils.getMetricsHeight(activity);
// }
//
// metrics.paddingTop = Utils.getStatusBarHeight(activity);
// metrics.paddingRight = 0;
// metrics.paddingBottom = 0;
// metrics.paddingLeft = 0;
// metrics.viewInsetTop = 0;
// metrics.viewInsetRight = 0;
// metrics.viewInsetBottom = 0;
// metrics.viewInsetLeft = 0;
//
// getRenderer().setViewportMetrics(metrics);
// }
// }
// }
protected
DartExecutor
.
DartEntrypoint
defaultDartEntrypoint
(
Context
context
)
{
return
new
DartExecutor
.
DartEntrypoint
(
context
.
getResources
().
getAssets
(),
FlutterMain
.
findAppBundlePath
(
context
),
"main"
);
return
DartExecutor
.
DartEntrypoint
.
createDefault
();
}
protected
String
defaultInitialRoute
(
Context
context
)
{
return
"/"
;
}
public
BoostPluginRegistry
getBoostPluginRegistry
()
{
return
mBoostPluginRegistry
;
}
//
public BoostPluginRegistry getBoostPluginRegistry() {
//
return mBoostPluginRegistry;
//
}
public
boolean
isRunning
()
{
return
getDartExecutor
().
isExecutingDart
();
...
...
@@ -165,14 +157,14 @@ public class BoostFlutterEngine extends FlutterEngine {
}
if
(
hit
)
{
return
mFakeRender
;
return
null
;
}
else
{
return
super
.
getRenderer
();
}
}
public
class
BoostPluginRegistry
extends
FlutterPluginRegistry
{
private
final
FlutterEngine
mEngine
;
private
FlutterEngine
mEngine
;
public
BoostPluginRegistry
(
FlutterEngine
engine
,
Context
context
)
{
super
(
engine
,
context
);
...
...
android/src/main/java/com/idlefish/flutterboost/BoostFlutterView.java
View file @
d9ac3683
...
...
@@ -136,7 +136,7 @@ public class BoostFlutterView extends FrameLayout {
mFlutterView
.
addOnFirstFrameRenderedListener
(
mOnFirstFrameRenderedListener
);
mFlutterEngine
.
startRun
((
Activity
)
getContext
());
//
mFlutterEngine.startRun((Activity)getContext());
final
IStateListener
stateListener
=
FlutterBoost
.
sInstance
.
mStateListener
;
if
(
stateListener
!=
null
)
{
...
...
@@ -185,7 +185,8 @@ public class BoostFlutterView extends FrameLayout {
}
protected
BoostFlutterEngine
createFlutterEngine
(
Context
context
)
{
return
FlutterBoost
.
singleton
().
engineProvider
().
provideEngine
(
context
);
// return FlutterBoost.singleton().engineProvider().provideEngine(context);
return
null
;
}
public
void
addFirstFrameRendered
(
OnFirstFrameRenderedListener
listener
)
{
...
...
@@ -310,7 +311,7 @@ public class BoostFlutterView extends FrameLayout {
public
void
onRequestPermissionsResult
(
int
requestCode
,
String
[]
permissions
,
int
[]
grantResults
)
{
if
(
mFlutterEngine
!=
null
)
{
mFlutterEngine
.
getPluginRegistry
().
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
//
mFlutterEngine.getPluginRegistry().onRequestPermissionsResult(requestCode, permissions, grantResults);
}
else
{
Debuger
.
log
(
"onRequestPermissionResult() invoked before BoostFlutterView was attached to an Activity."
);
}
...
...
@@ -319,7 +320,7 @@ public class BoostFlutterView extends FrameLayout {
public
void
onNewIntent
(
Intent
intent
)
{
if
(
mFlutterEngine
!=
null
)
{
mFlutterEngine
.
getPluginRegistry
().
onNewIntent
(
intent
);
//
mFlutterEngine.getPluginRegistry().onNewIntent(intent);
}
else
{
Debuger
.
log
(
"onNewIntent() invoked before BoostFlutterView was attached to an Activity."
);
}
...
...
@@ -328,7 +329,7 @@ public class BoostFlutterView extends FrameLayout {
public
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
if
(
mFlutterEngine
!=
null
)
{
mFlutterEngine
.
getPluginRegistry
().
onActivityResult
(
requestCode
,
resultCode
,
data
);
//
mFlutterEngine.getPluginRegistry().onActivityResult(requestCode, resultCode, data);
}
else
{
Debuger
.
log
(
"onActivityResult() invoked before BoostFlutterView was attached to an Activity."
);
}
...
...
@@ -336,7 +337,7 @@ public class BoostFlutterView extends FrameLayout {
public
void
onUserLeaveHint
()
{
if
(
mFlutterEngine
!=
null
)
{
mFlutterEngine
.
getPluginRegistry
().
onUserLeaveHint
();
//
mFlutterEngine.getPluginRegistry().onUserLeaveHint();
}
else
{
Debuger
.
log
(
"onUserLeaveHint() invoked before BoostFlutterView was attached to an Activity."
);
}
...
...
android/src/main/java/com/idlefish/flutterboost/BoostPluginRegistry.java
0 → 100644
View file @
d9ac3683
package
com.idlefish.flutterboost
;
import
android.app.Activity
;
import
android.content.Context
;
import
com.idlefish.flutterboost.interfaces.IContainerRecord
;
import
io.flutter.app.FlutterPluginRegistry
;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.plugin.common.BinaryMessenger
;
import
io.flutter.plugin.common.PluginRegistry
;
import
io.flutter.plugin.platform.PlatformViewRegistry
;
import
io.flutter.view.FlutterView
;
import
io.flutter.view.TextureRegistry
;
import
java.lang.ref.WeakReference
;
public
class
BoostPluginRegistry
extends
FlutterPluginRegistry
{
protected
WeakReference
<
Activity
>
mCurrentActivityRef
;
private
FlutterEngine
mEngine
;
public
BoostPluginRegistry
(
FlutterEngine
engine
,
Context
context
)
{
super
(
engine
,
context
);
mEngine
=
engine
;
}
public
PluginRegistry
.
Registrar
registrarFor
(
String
pluginKey
)
{
return
new
BoostRegistrar
(
mEngine
,
super
.
registrarFor
(
pluginKey
));
}
public
class
BoostRegistrar
implements
PluginRegistry
.
Registrar
{
private
final
PluginRegistry
.
Registrar
mRegistrar
;
private
final
FlutterEngine
mEngine
;
BoostRegistrar
(
FlutterEngine
engine
,
PluginRegistry
.
Registrar
registrar
)
{
mRegistrar
=
registrar
;
mEngine
=
engine
;
}
@Override
public
Activity
activity
()
{
Activity
activity
;
IContainerRecord
record
;
record
=
FlutterBoost
.
singleton
().
containerManager
().
getCurrentTopRecord
();
if
(
record
==
null
)
{
record
=
FlutterBoost
.
singleton
().
containerManager
().
getLastGenerateRecord
();
}
if
(
record
==
null
)
{
activity
=
FlutterBoost
.
singleton
().
currentActivity
();
}
else
{
activity
=
record
.
getContainer
().
getContextActivity
();
}
if
(
activity
==
null
&&
mCurrentActivityRef
!=
null
)
{
activity
=
mCurrentActivityRef
.
get
();
}
if
(
activity
==
null
)
{
throw
new
RuntimeException
(
"current has no valid Activity yet"
);
}
return
activity
;
}
@Override
public
Context
context
()
{
return
mRegistrar
.
context
();
}
@Override
public
Context
activeContext
()
{
return
mRegistrar
.
activeContext
();
}
@Override
public
BinaryMessenger
messenger
()
{
return
mEngine
.
getDartExecutor
();
}
@Override
public
TextureRegistry
textures
()
{
return
mEngine
.
getRenderer
();
}
@Override
public
PlatformViewRegistry
platformViewRegistry
()
{
return
mRegistrar
.
platformViewRegistry
();
}
@Override
public
FlutterView
view
()
{
throw
new
RuntimeException
(
"should not use!!!"
);
}
@Override
public
String
lookupKeyForAsset
(
String
s
)
{
return
mRegistrar
.
lookupKeyForAsset
(
s
);
}
@Override
public
String
lookupKeyForAsset
(
String
s
,
String
s1
)
{
return
mRegistrar
.
lookupKeyForAsset
(
s
,
s1
);
}
@Override
public
PluginRegistry
.
Registrar
publish
(
Object
o
)
{
return
mRegistrar
.
publish
(
o
);
}
@Override
public
PluginRegistry
.
Registrar
addRequestPermissionsResultListener
(
PluginRegistry
.
RequestPermissionsResultListener
requestPermissionsResultListener
)
{
return
mRegistrar
.
addRequestPermissionsResultListener
(
requestPermissionsResultListener
);
}
@Override
public
PluginRegistry
.
Registrar
addActivityResultListener
(
PluginRegistry
.
ActivityResultListener
activityResultListener
)
{
return
mRegistrar
.
addActivityResultListener
(
activityResultListener
);
}
@Override
public
PluginRegistry
.
Registrar
addNewIntentListener
(
PluginRegistry
.
NewIntentListener
newIntentListener
)
{
return
mRegistrar
.
addNewIntentListener
(
newIntentListener
);
}
@Override
public
PluginRegistry
.
Registrar
addUserLeaveHintListener
(
PluginRegistry
.
UserLeaveHintListener
userLeaveHintListener
)
{
return
mRegistrar
.
addUserLeaveHintListener
(
userLeaveHintListener
);
}
@Override
public
PluginRegistry
.
Registrar
addViewDestroyListener
(
PluginRegistry
.
ViewDestroyListener
viewDestroyListener
)
{
return
mRegistrar
.
addViewDestroyListener
(
viewDestroyListener
);
}
}
}
android/src/main/java/com/idlefish/flutterboost/ContainerRecord.java
View file @
d9ac3683
...
...
@@ -76,7 +76,7 @@ public class ContainerRecord implements IContainerRecord {
}
mState
=
STATE_CREATED
;
mContainer
.
getBoostFlutterView
().
onResume
();
//
mContainer.getBoostFlutterView().onResume();
mProxy
.
create
();
}
...
...
@@ -129,15 +129,15 @@ public class ContainerRecord implements IContainerRecord {
mProxy
.
destroy
();
mContainer
.
getBoostFlutterView
().
onDestroy
();
//
mContainer.getBoostFlutterView().onDestroy();
mManager
.
removeRecord
(
this
);
mManager
.
setContainerResult
(
this
,-
1
,-
1
,
null
);
if
(!
mManager
.
hasContainerAppear
())
{
mContainer
.
getBoostFlutterView
().
onPause
();
mContainer
.
getBoostFlutterView
().
onStop
();
//
mContainer.getBoostFlutterView().onPause();
//
mContainer.getBoostFlutterView().onStop();
}
}
...
...
@@ -154,45 +154,80 @@ public class ContainerRecord implements IContainerRecord {
map
.
put
(
"name"
,
mContainer
.
getContainerUrl
());
map
.
put
(
"uniqueId"
,
mUniqueId
);
FlutterBoost
.
singleton
().
channel
().
sendEvent
(
"lifecycle"
,
map
);
NewFlutterBoost
.
instance
().
channel
().
sendEvent
(
"lifecycle"
,
map
);
mContainer
.
getBoostFlutterView
().
onBackPressed
();
//
mContainer.getBoostFlutterView().onBackPressed();
}
@Override
public
void
onRequestPermissionsResult
(
int
requestCode
,
String
[]
permissions
,
int
[]
grantResults
)
{
mContainer
.
getBoostFlutterView
().
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
}
@Override
public
void
onNewIntent
(
Intent
intent
)
{
mContainer
.
getBoostFlutterView
().
onNewIntent
(
intent
);
}
@Override
public
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
mContainer
.
getBoostFlutterView
().
onActivityResult
(
requestCode
,
resultCode
,
data
);
}
@Override
public
void
onContainerResult
(
int
requestCode
,
int
resultCode
,
Map
<
String
,
Object
>
result
)
{
mManager
.
setContainerResult
(
this
,
requestCode
,
resultCode
,
result
);
}
@Override
public
void
onUserLeaveHint
()
{
mContainer
.
getBoostFlutterView
().
onUserLeaveHint
();
}
@Override
public
void
onTrimMemory
(
int
level
)
{
mContainer
.
getBoostFlutterView
().
onTrimMemory
(
level
);
}
@Override
public
void
onLowMemory
()
{
mContainer
.
getBoostFlutterView
().
onLowMemory
();
}
//
// @Override
// public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
// mContainer.getBoostFlutterView().onRequestPermissionsResult(requestCode, permissions, grantResults);
// }
//
// @Override
// public void onNewIntent(Intent intent) {
// mContainer.getBoostFlutterView().onNewIntent(intent);
// }
//
// @Override
// public void onActivityResult(int requestCode, int resultCode, Intent data) {
// mContainer.getBoostFlutterView().onActivityResult(requestCode, resultCode, data);
// }
//
// @Override
// public void onContainerResult(int requestCode, int resultCode, Map<String, Object> result) {
// mManager.setContainerResult(this, requestCode,resultCode, result);
// }
//
// @Override
// public void onUserLeaveHint() {
// mContainer.getBoostFlutterView().onUserLeaveHint();
// }
//
// @Override
// public void onTrimMemory(int level) {
// mContainer.getBoostFlutterView().onTrimMemory(level);
// }
//
// @Override
// public void onLowMemory() {
// mContainer.getBoostFlutterView().onLowMemory();
// }
private
class
MethodChannelProxy
{
...
...
@@ -252,7 +287,7 @@ public class ContainerRecord implements IContainerRecord {
args
.
put
(
"pageName"
,
url
);
args
.
put
(
"params"
,
params
);
args
.
put
(
"uniqueId"
,
uniqueId
);
FlutterBoost
.
singleton
().
channel
().
invokeMethod
(
method
,
args
);
NewFlutterBoost
.
instance
().
channel
().
invokeMethod
(
method
,
args
);
}
public
void
invokeChannelUnsafe
(
String
method
,
String
url
,
Map
params
,
String
uniqueId
)
{
...
...
@@ -260,7 +295,7 @@ public class ContainerRecord implements IContainerRecord {
args
.
put
(
"pageName"
,
url
);
args
.
put
(
"params"
,
params
);
args
.
put
(
"uniqueId"
,
uniqueId
);
FlutterBoost
.
singleton
().
channel
().
invokeMethodUnsafe
(
method
,
args
);
NewFlutterBoost
.
instance
().
channel
().
invokeMethodUnsafe
(
method
,
args
);
}
}
...
...
android/src/main/java/com/idlefish/flutterboost/FlutterBoost.java
View file @
d9ac3683
...
...
@@ -51,11 +51,11 @@ public class FlutterBoost {
sInstance
=
new
FlutterBoost
(
platform
);
}
if
(
platform
.
whenEngineStart
()
==
IPlatform
.
IMMEDIATELY
)
{
sInstance
.
mEngineProvider
.
provideEngine
(
platform
.
getApplication
())
.
startRun
(
null
);
}
//
if (platform.whenEngineStart() == IPlatform.IMMEDIATELY) {
//
sInstance.mEngineProvider
//
.provideEngine(platform.getApplication())
//
.startRun(null);
//
}
}
public
static
FlutterBoost
singleton
()
{
...
...
@@ -84,9 +84,9 @@ public class FlutterBoost {
mEngineProvider
=
provider
;
platform
.
getApplication
().
registerActivityLifecycleCallbacks
(
new
ActivityLifecycleCallbacks
());
BoostChannel
.
addActionAfterRegistered
(
new
BoostChannel
.
ActionAfterRegistered
()
{
FlutterBoostPlugin
.
addActionAfterRegistered
(
new
FlutterBoostPlugin
.
ActionAfterRegistered
()
{
@Override
public
void
onChannelRegistered
(
BoostChannel
channel
)
{
public
void
onChannelRegistered
(
FlutterBoostPlugin
channel
)
{
channel
.
addMethodCallHandler
(
new
BoostMethodHandler
());
}
});
...
...
@@ -104,8 +104,8 @@ public class FlutterBoost {
return
sInstance
.
mPlatform
;
}
public
BoostChannel
channel
()
{
return
BoostChannel
.
singleton
();
public
FlutterBoostPlugin
channel
()
{
return
FlutterBoostPlugin
.
singleton
();
}
public
Activity
currentActivity
()
{
...
...
@@ -124,9 +124,9 @@ public class FlutterBoost {
@Override
public
void
onActivityCreated
(
Activity
activity
,
Bundle
savedInstanceState
)
{
if
(
platform
().
whenEngineStart
()
==
IPlatform
.
ANY_ACTIVITY_CREATED
)
{
sInstance
.
mEngineProvider
.
provideEngine
(
activity
)
.
startRun
(
activity
);
//
sInstance.mEngineProvider
//
.provideEngine(activity)
//
.startRun(activity);
}
}
...
...
android/src/main/java/com/idlefish/flutterboost/
BoostChannel
.java
→
android/src/main/java/com/idlefish/flutterboost/
FlutterBoostPlugin
.java
View file @
d9ac3683
...
...
@@ -2,6 +2,7 @@ package com.idlefish.flutterboost;
import
android.support.annotation.Nullable
;
import
com.idlefish.flutterboost.interfaces.IContainerRecord
;
import
com.idlefish.flutterboost.interfaces.IStateListener
;
import
java.io.Serializable
;
...
...
@@ -14,42 +15,42 @@ import io.flutter.plugin.common.MethodCall;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.plugin.common.PluginRegistry
;
public
class
BoostChannel
{
public
class
FlutterBoostPlugin
{
private
static
BoostChannel
sInstance
;
private
static
FlutterBoostPlugin
sInstance
;
private
final
MethodChannel
mMethodChannel
;
private
final
Set
<
MethodChannel
.
MethodCallHandler
>
mMethodCallHandlers
=
new
HashSet
<>();
private
final
Map
<
String
,
Set
<
EventListener
>>
mEventListeners
=
new
HashMap
<>();
private
final
Map
<
String
,
Set
<
EventListener
>>
mEventListeners
=
new
HashMap
<>();
private
static
final
Set
<
ActionAfterRegistered
>
sActions
=
new
HashSet
<>();
public
static
BoostChannel
singleton
()
{
public
static
FlutterBoostPlugin
singleton
()
{
if
(
sInstance
==
null
)
{
throw
new
RuntimeException
(
"
BoostChannel
not register yet"
);
throw
new
RuntimeException
(
"
FlutterBoostPlugin
not register yet"
);
}
return
sInstance
;
}
public
static
void
addActionAfterRegistered
(
ActionAfterRegistered
action
)
{
if
(
action
==
null
)
return
;
if
(
action
==
null
)
return
;
if
(
sInstance
==
null
)
{
if
(
sInstance
==
null
)
{
sActions
.
add
(
action
);
}
else
{
}
else
{
action
.
onChannelRegistered
(
sInstance
);
}
}
public
static
void
registerWith
(
PluginRegistry
.
Registrar
registrar
)
{
sInstance
=
new
BoostChannel
(
registrar
);
sInstance
=
new
FlutterBoostPlugin
(
registrar
);
for
(
ActionAfterRegistered
a
:
sActions
)
{
for
(
ActionAfterRegistered
a
:
sActions
)
{
a
.
onChannelRegistered
(
sInstance
);
}
if
(
FlutterBoost
.
sInstance
!=
null
)
{
if
(
FlutterBoost
.
sInstance
!=
null
)
{
final
IStateListener
stateListener
=
FlutterBoost
.
sInstance
.
mStateListener
;
if
(
stateListener
!=
null
)
{
stateListener
.
onChannelRegistered
(
registrar
,
sInstance
);
...
...
@@ -59,7 +60,7 @@ public class BoostChannel {
sActions
.
clear
();
}
private
BoostChannel
(
PluginRegistry
.
Registrar
registrar
)
{
private
FlutterBoostPlugin
(
PluginRegistry
.
Registrar
registrar
)
{
mMethodChannel
=
new
MethodChannel
(
registrar
.
messenger
(),
"flutter_boost"
);
mMethodChannel
.
setMethodCallHandler
(
new
MethodChannel
.
MethodCallHandler
()
{
...
...
@@ -78,26 +79,29 @@ public class BoostChannel {
}
}
if
(
listeners
!=
null
)
{
for
(
Object
o:
listeners
)
{
((
EventListener
)
o
).
onEvent
(
name
,
args
);
if
(
listeners
!=
null
)
{
for
(
Object
o
:
listeners
)
{
((
EventListener
)
o
).
onEvent
(
name
,
args
);
}
}
}
else
{
}
else
{
Object
[]
handlers
;
synchronized
(
mMethodCallHandlers
)
{
handlers
=
mMethodCallHandlers
.
toArray
();
}
for
(
Object
o:
handlers
)
{
((
MethodChannel
.
MethodCallHandler
)
o
).
onMethodCall
(
methodCall
,
result
);
for
(
Object
o
:
handlers
)
{
((
MethodChannel
.
MethodCallHandler
)
o
).
onMethodCall
(
methodCall
,
result
);
}
}
}
});
addMethodCallHandler
(
new
BoostMethodHandler
());
}
public
void
invokeMethodUnsafe
(
final
String
name
,
Serializable
args
)
{
public
void
invokeMethodUnsafe
(
final
String
name
,
Serializable
args
)
{
invokeMethod
(
name
,
args
,
new
MethodChannel
.
Result
()
{
@Override
public
void
success
(
@Nullable
Object
o
)
{
...
...
@@ -106,17 +110,17 @@ public class BoostChannel {
@Override
public
void
error
(
String
s
,
@Nullable
String
s1
,
@Nullable
Object
o
)
{
Debuger
.
log
(
"invoke method "
+
name
+
" error:"
+
s
+
" | "
+
s1
);
Debuger
.
log
(
"invoke method "
+
name
+
" error:"
+
s
+
" | "
+
s1
);
}
@Override
public
void
notImplemented
()
{
Debuger
.
log
(
"invoke method "
+
name
+
" notImplemented"
);
Debuger
.
log
(
"invoke method "
+
name
+
" notImplemented"
);
}
});
}
public
void
invokeMethod
(
final
String
name
,
Serializable
args
)
{
public
void
invokeMethod
(
final
String
name
,
Serializable
args
)
{
invokeMethod
(
name
,
args
,
new
MethodChannel
.
Result
()
{
@Override
public
void
success
(
@Nullable
Object
o
)
{
...
...
@@ -125,18 +129,18 @@ public class BoostChannel {
@Override
public
void
error
(
String
s
,
@Nullable
String
s1
,
@Nullable
Object
o
)
{
Debuger
.
exception
(
"invoke method "
+
name
+
" error:"
+
s
+
" | "
+
s1
);
Debuger
.
exception
(
"invoke method "
+
name
+
" error:"
+
s
+
" | "
+
s1
);
}
@Override
public
void
notImplemented
()
{
Debuger
.
exception
(
"invoke method "
+
name
+
" notImplemented"
);
Debuger
.
exception
(
"invoke method "
+
name
+
" notImplemented"
);
}
});
}
public
void
invokeMethod
(
final
String
name
,
Serializable
args
,
MethodChannel
.
Result
result
)
{
if
(
"__event__"
.
equals
(
name
))
{
public
void
invokeMethod
(
final
String
name
,
Serializable
args
,
MethodChannel
.
Result
result
)
{
if
(
"__event__"
.
equals
(
name
))
{
Debuger
.
exception
(
"method name should not be __event__"
);
}
...
...
@@ -144,7 +148,7 @@ public class BoostChannel {
}
public
void
addMethodCallHandler
(
MethodChannel
.
MethodCallHandler
handler
)
{
synchronized
(
mMethodCallHandlers
){
synchronized
(
mMethodCallHandlers
)
{
mMethodCallHandlers
.
add
(
handler
);
}
}
...
...
@@ -156,29 +160,29 @@ public class BoostChannel {
}
public
void
addEventListener
(
String
name
,
EventListener
listener
)
{
synchronized
(
mEventListeners
){
synchronized
(
mEventListeners
)
{
Set
<
EventListener
>
set
=
mEventListeners
.
get
(
name
);
if
(
set
==
null
)
{
if
(
set
==
null
)
{
set
=
new
HashSet
<>();
}
set
.
add
(
listener
);
mEventListeners
.
put
(
name
,
set
);
mEventListeners
.
put
(
name
,
set
);
}
}
public
void
removeEventListener
(
EventListener
listener
)
{
synchronized
(
mEventListeners
)
{
for
(
Set
<
EventListener
>
set:
mEventListeners
.
values
())
{
for
(
Set
<
EventListener
>
set
:
mEventListeners
.
values
())
{
set
.
remove
(
listener
);
}
}
}
public
void
sendEvent
(
String
name
,
Map
args
)
{
public
void
sendEvent
(
String
name
,
Map
args
)
{
Map
event
=
new
HashMap
();
event
.
put
(
"name"
,
name
);
event
.
put
(
"arguments"
,
args
);
mMethodChannel
.
invokeMethod
(
"__event__"
,
event
);
event
.
put
(
"name"
,
name
);
event
.
put
(
"arguments"
,
args
);
mMethodChannel
.
invokeMethod
(
"__event__"
,
event
);
}
public
interface
EventListener
{
...
...
@@ -186,6 +190,87 @@ public class BoostChannel {
}
public
interface
ActionAfterRegistered
{
void
onChannelRegistered
(
BoostChannel
channel
);
void
onChannelRegistered
(
FlutterBoostPlugin
channel
);
}
class
BoostMethodHandler
implements
MethodChannel
.
MethodCallHandler
{
@Override
public
void
onMethodCall
(
MethodCall
methodCall
,
final
MethodChannel
.
Result
result
)
{
FlutterViewContainerManager
mManager
=
(
FlutterViewContainerManager
)
NewFlutterBoost
.
instance
().
containerManager
();
switch
(
methodCall
.
method
)
{
case
"pageOnStart"
:
{
Map
<
String
,
Object
>
pageInfo
=
new
HashMap
<>();
try
{
IContainerRecord
record
=
mManager
.
getCurrentTopRecord
();
if
(
record
==
null
)
{
record
=
mManager
.
getLastGenerateRecord
();
}
if
(
record
!=
null
)
{
pageInfo
.
put
(
"name"
,
record
.
getContainer
().
getContainerUrl
());
pageInfo
.
put
(
"params"
,
record
.
getContainer
().
getContainerUrlParams
());
pageInfo
.
put
(
"uniqueId"
,
record
.
uniqueId
());
}
result
.
success
(
pageInfo
);
}
catch
(
Throwable
t
)
{
result
.
error
(
"no flutter page found!"
,
t
.
getMessage
(),
t
);
}
}
break
;
case
"openPage"
:
{
try
{
Map
<
String
,
Object
>
params
=
methodCall
.
argument
(
"urlParams"
);
Map
<
String
,
Object
>
exts
=
methodCall
.
argument
(
"exts"
);
String
url
=
methodCall
.
argument
(
"url"
);
mManager
.
openContainer
(
url
,
params
,
exts
,
new
FlutterViewContainerManager
.
OnResult
()
{
@Override
public
void
onResult
(
Map
<
String
,
Object
>
rlt
)
{
if
(
result
!=
null
)
{
result
.
success
(
rlt
);
}
}
});
}
catch
(
Throwable
t
)
{
result
.
error
(
"open page error"
,
t
.
getMessage
(),
t
);
}
}
break
;
case
"closePage"
:
{
try
{
String
uniqueId
=
methodCall
.
argument
(
"uniqueId"
);
Map
<
String
,
Object
>
resultData
=
methodCall
.
argument
(
"result"
);
Map
<
String
,
Object
>
exts
=
methodCall
.
argument
(
"exts"
);
mManager
.
closeContainer
(
uniqueId
,
resultData
,
exts
);
result
.
success
(
true
);
}
catch
(
Throwable
t
)
{
result
.
error
(
"close page error"
,
t
.
getMessage
(),
t
);
}
}
break
;
case
"onShownContainerChanged"
:
{
try
{
String
newId
=
methodCall
.
argument
(
"newName"
);
String
oldId
=
methodCall
.
argument
(
"oldName"
);
mManager
.
onShownContainerChanged
(
newId
,
oldId
);
result
.
success
(
true
);
}
catch
(
Throwable
t
)
{
result
.
error
(
"onShownContainerChanged"
,
t
.
getMessage
(),
t
);
}
}
break
;
default
:
{
result
.
notImplemented
();
}
}
}
}
}
android/src/main/java/com/idlefish/flutterboost/FlutterViewContainerManager.java
View file @
d9ac3683
...
...
@@ -111,9 +111,9 @@ public class FlutterViewContainerManager implements IContainerManager {
}
void
openContainer
(
String
url
,
Map
<
String
,
Object
>
urlParams
,
Map
<
String
,
Object
>
exts
,
OnResult
onResult
)
{
Context
context
=
FlutterBoost
.
singleton
().
currentActivity
();
Context
context
=
NewFlutterBoost
.
instance
().
currentActivity
();
if
(
context
==
null
)
{
context
=
FlutterBoost
.
singleton
().
platform
().
getApplication
();
context
=
NewFlutterBoost
.
instance
().
platform
().
getApplication
();
}
if
(
urlParams
==
null
)
{
...
...
@@ -132,7 +132,7 @@ public class FlutterViewContainerManager implements IContainerManager {
mOnResults
.
put
(
uniqueId
,
onResult
);
}
FlutterBoost
.
singleton
().
platform
().
openContainer
(
context
,
url
,
urlParams
,
requestCode
,
exts
);
NewFlutterBoost
.
instance
().
platform
().
openContainer
(
context
,
url
,
urlParams
,
requestCode
,
exts
);
}
IContainerRecord
closeContainer
(
String
uniqueId
,
Map
<
String
,
Object
>
result
,
Map
<
String
,
Object
>
exts
)
{
...
...
@@ -148,7 +148,7 @@ public class FlutterViewContainerManager implements IContainerManager {
Debuger
.
exception
(
"closeContainer can not find uniqueId:"
+
uniqueId
);
}
FlutterBoost
.
singleton
().
platform
().
closeContainer
(
targetRecord
,
result
,
exts
);
NewFlutterBoost
.
instance
().
platform
().
closeContainer
(
targetRecord
,
result
,
exts
);
return
targetRecord
;
}
...
...
android/src/main/java/com/idlefish/flutterboost/NewFlutterBoost.java
0 → 100644
View file @
d9ac3683
package
com.idlefish.flutterboost
;
import
android.app.Activity
;
import
android.app.Application
;
import
android.content.Context
;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
import
com.idlefish.flutterboost.interfaces.*
;
import
io.flutter.app.FlutterPluginRegistry
;
import
io.flutter.embedding.engine.FlutterEngine
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
NewFlutterBoost
{
private
Platform
mPlatform
;
private
FlutterViewContainerManager
mManager
;
private
IFlutterEngineProvider
mEngineProvider
;
private
Activity
mCurrentActiveActivity
;
static
NewFlutterBoost
sInstance
=
null
;
public
static
NewFlutterBoost
instance
()
{
if
(
sInstance
==
null
)
{
sInstance
=
new
NewFlutterBoost
();
}
return
sInstance
;
}
public
void
init
(
Platform
platform
)
{
mPlatform
=
platform
;
mManager
=
new
FlutterViewContainerManager
();
mEngineProvider
=
platform
.
engineProvider
();
platform
.
getApplication
().
registerActivityLifecycleCallbacks
(
new
Application
.
ActivityLifecycleCallbacks
()
{
@Override
public
void
onActivityCreated
(
Activity
activity
,
Bundle
savedInstanceState
)
{
if
(
mPlatform
.
whenEngineStart
()
==
IPlatform
.
ANY_ACTIVITY_CREATED
)
{
}
}
@Override
public
void
onActivityStarted
(
Activity
activity
)
{
if
(
mCurrentActiveActivity
==
null
)
{
Debuger
.
log
(
"Application entry foreground"
);
if
(
NewFlutterBoost
.
instance
().
engineProvider
().
tryGetEngine
()
!=
null
)
{
HashMap
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"type"
,
"foreground"
);
channel
().
sendEvent
(
"lifecycle"
,
map
);
}
}
mCurrentActiveActivity
=
activity
;
}
@Override
public
void
onActivityResumed
(
Activity
activity
)
{
mCurrentActiveActivity
=
activity
;
}
@Override
public
void
onActivityPaused
(
Activity
activity
)
{
}
@Override
public
void
onActivityStopped
(
Activity
activity
)
{
if
(
mCurrentActiveActivity
==
activity
)
{
Debuger
.
log
(
"Application entry background"
);
if
(
mEngineProvider
.
tryGetEngine
()
!=
null
)
{
HashMap
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"type"
,
"background"
);
channel
().
sendEvent
(
"lifecycle"
,
map
);
}
mCurrentActiveActivity
=
null
;
}
}
@Override
public
void
onActivitySaveInstanceState
(
Activity
activity
,
Bundle
outState
)
{
}
@Override
public
void
onActivityDestroyed
(
Activity
activity
)
{
if
(
mCurrentActiveActivity
==
activity
)
{
Debuger
.
log
(
"Application entry background"
);
if
(
mEngineProvider
.
tryGetEngine
()
!=
null
)
{
HashMap
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"type"
,
"background"
);
channel
().
sendEvent
(
"lifecycle"
,
map
);
}
mCurrentActiveActivity
=
null
;
}
}
});
BoostPluginRegistry
registry
=
new
BoostPluginRegistry
(
this
.
engineProvider
().
provideEngine
(
mPlatform
.
getApplication
()),
mPlatform
.
getApplication
());
mPlatform
.
registerPlugins
(
registry
);
}
public
static
class
ConfigBuilder
{
protected
static
final
String
DEFAULT_DART_ENTRYPOINT
=
"main"
;
protected
static
final
String
DEFAULT_INITIAL_ROUTE
=
"/"
;
private
String
dartEntrypoint
=
DEFAULT_DART_ENTRYPOINT
;
private
String
initialRoute
=
DEFAULT_INITIAL_ROUTE
;
private
boolean
isDebug
=
false
;
private
int
whenEngineStart
=
1
;
private
Application
mApp
;
private
INativeRouter
router
=
null
;
public
ConfigBuilder
(
Application
app
,
INativeRouter
router
)
{
this
.
router
=
router
;
this
.
mApp
=
app
;
}
public
ConfigBuilder
dartEntrypoint
(
@NonNull
String
dartEntrypoint
)
{
this
.
dartEntrypoint
=
dartEntrypoint
;
return
this
;
}
public
ConfigBuilder
isDebug
(
boolean
isDebug
)
{
this
.
isDebug
=
isDebug
;
return
this
;
}
public
ConfigBuilder
whenEngineStart
(
@NonNull
int
whenEngineStart
)
{
this
.
whenEngineStart
=
whenEngineStart
;
return
this
;
}
public
Platform
build
()
{
Platform
platform
=
new
Platform
()
{
@Override
public
Application
getApplication
()
{
return
ConfigBuilder
.
this
.
mApp
;
}
public
boolean
isDebug
()
{
return
ConfigBuilder
.
this
.
isDebug
;
}
@Override
public
void
openContainer
(
Context
context
,
String
url
,
Map
<
String
,
Object
>
urlParams
,
int
requestCode
,
Map
<
String
,
Object
>
exts
)
{
router
.
openContainer
(
context
,
url
,
urlParams
,
requestCode
,
exts
);
}
@Override
public
IFlutterEngineProvider
engineProvider
()
{
return
new
BoostEngineProvider
();
}
public
int
whenEngineStart
()
{
return
ConfigBuilder
.
this
.
whenEngineStart
;
}
};
return
platform
;
}
}
public
IFlutterEngineProvider
engineProvider
()
{
return
sInstance
.
mEngineProvider
;
}
public
IContainerManager
containerManager
()
{
return
sInstance
.
mManager
;
}
public
IPlatform
platform
()
{
return
sInstance
.
mPlatform
;
}
public
FlutterBoostPlugin
channel
()
{
return
FlutterBoostPlugin
.
singleton
();
}
public
Activity
currentActivity
()
{
return
sInstance
.
mCurrentActiveActivity
;
}
public
IFlutterViewContainer
findContainerById
(
String
id
)
{
return
mManager
.
findContainerById
(
id
);
}
}
android/src/main/java/com/idlefish/flutterboost/StateListener.java
View file @
d9ac3683
...
...
@@ -16,7 +16,7 @@ public class StateListener implements IStateListener {
}
@Override
public
void
onChannelRegistered
(
PluginRegistry
.
Registrar
registrar
,
BoostChannel
channel
)
{
public
void
onChannelRegistered
(
PluginRegistry
.
Registrar
registrar
,
FlutterBoostPlugin
channel
)
{
Debuger
.
log
(
">>onFlutterViewInited"
);
}
...
...
android/src/main/java/com/idlefish/flutterboost/XFlutterView.java
View file @
d9ac3683
...
...
@@ -449,7 +449,7 @@ public class XFlutterView extends FrameLayout {
this
.
flutterEngine
=
flutterEngine
;
// initialize PlatformViewsController
this
.
flutterEngine
.
getPluginRegistry
().
getPlatformViewsController
().
attach
(
getContext
(),
flutterEngine
.
getRenderer
(),
flutterEngine
.
getDartExecutor
());
//
this.flutterEngine.getPluginRegistry().getPlatformViewsController().attach(getContext(),flutterEngine.getRenderer(),flutterEngine.getDartExecutor());
// Instruct our FlutterRenderer that we are now its designated RenderSurface.
this
.
flutterEngine
.
getRenderer
().
attachToRenderSurface
(
renderSurface
);
...
...
@@ -533,8 +533,8 @@ public class XFlutterView extends FrameLayout {
Log
.
d
(
TAG
,
"Detaching from Flutter Engine"
);
// detach platformviews in page in case memory leak
flutterEngine
.
getPluginRegistry
().
getPlatformViewsController
().
detach
();
flutterEngine
.
getPluginRegistry
().
getPlatformViewsController
().
onFlutterViewDestroyed
();
//
flutterEngine.getPluginRegistry().getPlatformViewsController().detach();
//
flutterEngine.getPluginRegistry().getPlatformViewsController().onFlutterViewDestroyed();
// Inform the Android framework that it should retrieve a new InputConnection
// now that the engine is detached. The new InputConnection will be null, which
...
...
android/src/main/java/com/idlefish/flutterboost/XTextInputPlugin.java
View file @
d9ac3683
package
com.idlefish.flutterboost
;
import
android.content.Context
;
import
android.os.Build
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.support.annotation.RequiresApi
;
import
android.text.Editable
;
import
android.text.InputType
;
import
android.text.Selection
;
...
...
@@ -59,6 +61,11 @@ public class XTextInputPlugin {
setTextInputClient
(
textInputClientId
,
configuration
);
}
@Override
public
void
setPlatformViewClient
(
int
i
)
{
}
@Override
public
void
setEditingState
(
TextInputChannel
.
TextEditState
editingState
)
{
setTextInputEditingState
(
mView
,
editingState
);
...
...
@@ -206,6 +213,7 @@ public class XTextInputPlugin {
}
}
@RequiresApi
(
api
=
Build
.
VERSION_CODES
.
CUPCAKE
)
private
void
setTextInputEditingState
(
View
view
,
TextInputChannel
.
TextEditState
state
)
{
if
(!
mRestartInputPending
&&
state
.
text
.
equals
(
mEditable
.
toString
()))
{
applyStateToSelection
(
state
);
...
...
android/src/main/java/com/idlefish/flutterboost/containers/BoostFlutterActivity.java
100755 → 100644
View file @
d9ac3683
...
...
@@ -117,7 +117,8 @@ public abstract class BoostFlutterActivity extends Activity implements IFlutterV
}
protected
BoostFlutterEngine
createFlutterEngine
(){
return
FlutterBoost
.
singleton
().
engineProvider
().
provideEngine
(
this
);
// return FlutterBoost.singleton().engineProvider().provideEngine(this);
return
null
;
}
protected
BoostFlutterView
createFlutterView
(
BoostFlutterEngine
engine
){
...
...
@@ -247,10 +248,10 @@ public abstract class BoostFlutterActivity extends Activity implements IFlutterV
return
this
;
}
@Override
public
BoostFlutterView
getBoostFlutterView
()
{
return
mFlutterView
;
}
//
@Override
//
public BoostFlutterView getBoostFlutterView() {
//
return mFlutterView;
//
}
@Override
public
void
finishContainer
(
Map
<
String
,
Object
>
result
)
{
...
...
android/src/main/java/com/idlefish/flutterboost/containers/BoostFlutterDefaultActivity.java
View file @
d9ac3683
...
...
@@ -9,6 +9,11 @@ import java.util.Map;
public
class
BoostFlutterDefaultActivity
extends
BoostFlutterActivity
{
@Override
public
FlutterSplashView
getBoostFlutterView
()
{
return
null
;
}
@Override
public
String
getContainerUrl
()
{
return
getIntent
().
getStringExtra
(
"url"
);
...
...
android/src/main/java/com/idlefish/flutterboost/containers/BoostFlutterFragment.java
View file @
d9ac3683
...
...
@@ -67,7 +67,8 @@ abstract public class BoostFlutterFragment extends Fragment implements IFlutterV
}
protected
BoostFlutterEngine
createFlutterEngine
(){
return
FlutterBoost
.
singleton
().
engineProvider
().
provideEngine
(
getContext
());
// return FlutterBoost.singleton().engineProvider().provideEngine(getContext());
return
null
;
}
protected
BoostFlutterView
createFlutterView
(
BoostFlutterEngine
engine
){
...
...
@@ -140,10 +141,10 @@ abstract public class BoostFlutterFragment extends Fragment implements IFlutterV
return
getActivity
();
}
@Override
public
BoostFlutterView
getBoostFlutterView
()
{
return
mFlutterView
;
}
//
@Override
//
public BoostFlutterView getBoostFlutterView() {
//
return mFlutterView;
//
}
@Override
public
void
finishContainer
(
Map
<
String
,
Object
>
result
)
{
...
...
android/src/main/java/com/idlefish/flutterboost/containers/FlutterActivityAndFragmentDelegate.java
0 → 100644
View file @
d9ac3683
package
com.idlefish.flutterboost.containers
;
import
android.annotation.SuppressLint
;
import
android.app.Activity
;
import
android.arch.lifecycle.Lifecycle
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
java.io.Serializable
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Map
;
import
com.idlefish.flutterboost.BoostFlutterView
;
import
com.idlefish.flutterboost.FlutterBoost
;
import
com.idlefish.flutterboost.NewFlutterBoost
;
import
com.idlefish.flutterboost.interfaces.IFlutterViewContainer
;
import
com.idlefish.flutterboost.interfaces.IOperateSyncer
;
import
io.flutter.Log
;
import
io.flutter.app.FlutterActivity
;
import
io.flutter.embedding.android.*
;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.embedding.engine.FlutterEngineCache
;
import
io.flutter.embedding.engine.FlutterShellArgs
;
import
io.flutter.embedding.engine.dart.DartExecutor
;
import
io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener
;
import
io.flutter.plugin.platform.PlatformPlugin
;
import
io.flutter.view.FlutterMain
;
import
static
android
.
content
.
ComponentCallbacks2
.
TRIM_MEMORY_RUNNING_LOW
;
public
class
FlutterActivityAndFragmentDelegate
implements
IFlutterViewContainer
{
private
static
final
String
TAG
=
"FlutterActivityAndFragmentDelegate"
;
@NonNull
private
Host
host
;
@Nullable
private
FlutterEngine
flutterEngine
;
@Nullable
private
FlutterSplashView
flutterSplashView
;
@Nullable
private
FlutterView
flutterView
;
@Nullable
private
PlatformPlugin
platformPlugin
;
private
boolean
isFlutterEngineFromHost
;
protected
IOperateSyncer
mSyncer
;
@NonNull
private
final
OnFirstFrameRenderedListener
onFirstFrameRenderedListener
=
new
OnFirstFrameRenderedListener
()
{
@Override
public
void
onFirstFrameRendered
()
{
host
.
onFirstFrameRendered
();
}
};
FlutterActivityAndFragmentDelegate
(
@NonNull
Host
host
)
{
this
.
host
=
host
;
}
void
release
()
{
this
.
host
=
null
;
this
.
flutterEngine
=
null
;
this
.
flutterView
=
null
;
this
.
platformPlugin
=
null
;
}
@Nullable
FlutterEngine
getFlutterEngine
()
{
return
flutterEngine
;
}
void
onAttach
(
@NonNull
Context
context
)
{
ensureAlive
();
initializeFlutter
(
context
);
// When "retain instance" is true, the FlutterEngine will survive configuration
// changes. Therefore, we create a new one only if one does not already exist.
if
(
flutterEngine
==
null
)
{
setupFlutterEngine
();
}
// Regardless of whether or not a FlutterEngine already existed, the PlatformPlugin
// is bound to a specific Activity. Therefore, it needs to be created and configured
// every time this Fragment attaches to a new Activity.
// TODO(mattcarroll): the PlatformPlugin needs to be reimagined because it implicitly takes
// control of the entire window. This is unacceptable for non-fullscreen
// use-cases.
platformPlugin
=
host
.
providePlatformPlugin
(
host
.
getActivity
(),
flutterEngine
);
if
(
host
.
shouldAttachEngineToActivity
())
{
// Notify any plugins that are currently attached to our FlutterEngine that they
// are now attached to an Activity.
//
// Passing this Fragment's Lifecycle should be sufficient because as long as this Fragment
// is attached to its Activity, the lifecycles should be in sync. Once this Fragment is
// detached from its Activity, that Activity will be detached from the FlutterEngine, too,
// which means there shouldn't be any possibility for the Fragment Lifecycle to get out of
// sync with the Activity. We use the Fragment's Lifecycle because it is possible that the
// attached Activity is not a LifecycleOwner.
Log
.
d
(
TAG
,
"Attaching FlutterEngine to the Activity that owns this Fragment."
);
flutterEngine
.
getActivityControlSurface
().
attachToActivity
(
host
.
getActivity
(),
host
.
getLifecycle
()
);
}
host
.
configureFlutterEngine
(
flutterEngine
);
}
private
void
initializeFlutter
(
@NonNull
Context
context
)
{
FlutterMain
.
ensureInitializationComplete
(
context
.
getApplicationContext
(),
host
.
getFlutterShellArgs
().
toArray
()
);
}
private
void
setupFlutterEngine
()
{
Log
.
d
(
TAG
,
"Setting up FlutterEngine."
);
// First, check if the host wants to use a cached FlutterEngine.
String
cachedEngineId
=
host
.
getCachedEngineId
();
if
(
cachedEngineId
!=
null
)
{
flutterEngine
=
FlutterEngineCache
.
getInstance
().
get
(
cachedEngineId
);
isFlutterEngineFromHost
=
true
;
if
(
flutterEngine
==
null
)
{
throw
new
IllegalStateException
(
"The requested cached FlutterEngine did not exist in the FlutterEngineCache: '"
+
cachedEngineId
+
"'"
);
}
return
;
}
// Second, defer to subclasses for a custom FlutterEngine.
flutterEngine
=
host
.
provideFlutterEngine
(
host
.
getContext
());
if
(
flutterEngine
!=
null
)
{
isFlutterEngineFromHost
=
true
;
return
;
}
// Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our
// FlutterView.
Log
.
d
(
TAG
,
"No preferred FlutterEngine was provided. Creating a new FlutterEngine for"
+
" this FlutterFragment."
);
flutterEngine
=
new
FlutterEngine
(
host
.
getContext
());
isFlutterEngineFromHost
=
false
;
}
@SuppressLint
(
"ResourceType"
)
@NonNull
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
Log
.
v
(
TAG
,
"Creating FlutterView."
);
mSyncer
=
NewFlutterBoost
.
instance
().
containerManager
().
generateSyncer
(
this
);
ensureAlive
();
flutterView
=
new
FlutterView
(
host
.
getActivity
(),
host
.
getRenderMode
(),
host
.
getTransparencyMode
());
flutterView
.
addOnFirstFrameRenderedListener
(
onFirstFrameRenderedListener
);
flutterSplashView
=
new
FlutterSplashView
(
host
.
getContext
());
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
JELLY_BEAN_MR1
)
{
flutterSplashView
.
setId
(
View
.
generateViewId
());
}
else
{
// TODO(mattcarroll): Find a better solution to this ID. This is a random, static ID.
// It might conflict with other Views, and it means that only a single FlutterSplashView
// can exist in a View hierarchy at one time.
flutterSplashView
.
setId
(
486947586
);
}
flutterSplashView
.
displayFlutterViewWithSplash
(
flutterView
,
host
.
provideSplashScreen
());
mSyncer
.
onCreate
();
return
flutterSplashView
;
}
void
onStart
()
{
Log
.
v
(
TAG
,
"onStart()"
);
ensureAlive
();
// We post() the code that attaches the FlutterEngine to our FlutterView because there is
// some kind of blocking logic on the native side when the surface is connected. That lag
// causes launching Activitys to wait a second or two before launching. By post()'ing this
// behavior we are able to move this blocking logic to after the Activity's launch.
// TODO(mattcarroll): figure out how to avoid blocking the MAIN thread when connecting a surface
new
Handler
().
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
Log
.
v
(
TAG
,
"Attaching FlutterEngine to FlutterView."
);
flutterView
.
attachToFlutterEngine
(
flutterEngine
);
doInitialFlutterViewRun
();
}
});
}
private
void
doInitialFlutterViewRun
()
{
// Don't attempt to start a FlutterEngine if we're using a cached FlutterEngine.
if
(
host
.
getCachedEngineId
()
!=
null
)
{
return
;
}
if
(
flutterEngine
.
getDartExecutor
().
isExecutingDart
())
{
// No warning is logged because this situation will happen on every config
// change if the developer does not choose to retain the Fragment instance.
// So this is expected behavior in many cases.
return
;
}
Log
.
d
(
TAG
,
"Executing Dart entrypoint: "
+
host
.
getDartEntrypointFunctionName
()
+
", and sending initial route: "
+
host
.
getInitialRoute
());
// The engine needs to receive the Flutter app's initial route before executing any
// Dart code to ensure that the initial route arrives in time to be applied.
if
(
host
.
getInitialRoute
()
!=
null
)
{
flutterEngine
.
getNavigationChannel
().
setInitialRoute
(
host
.
getInitialRoute
());
}
// Configure the Dart entrypoint and execute it.
DartExecutor
.
DartEntrypoint
entrypoint
=
new
DartExecutor
.
DartEntrypoint
(
host
.
getAppBundlePath
(),
host
.
getDartEntrypointFunctionName
()
);
flutterEngine
.
getDartExecutor
().
executeDartEntrypoint
(
entrypoint
);
}
void
onResume
()
{
mSyncer
.
onAppear
();
Log
.
v
(
TAG
,
"onResume()"
);
ensureAlive
();
flutterEngine
.
getLifecycleChannel
().
appIsResumed
();
}
void
onPostResume
()
{
Log
.
v
(
TAG
,
"onPostResume()"
);
ensureAlive
();
if
(
flutterEngine
!=
null
)
{
if
(
platformPlugin
!=
null
)
{
// TODO(mattcarroll): find a better way to handle the update of UI overlays than calling through
// to platformPlugin. We're implicitly entangling the Window, Activity, Fragment,
// and engine all with this one call.
platformPlugin
.
updateSystemUiOverlays
();
}
}
else
{
Log
.
w
(
TAG
,
"onPostResume() invoked before FlutterFragment was attached to an Activity."
);
}
}
void
onPause
()
{
Log
.
v
(
TAG
,
"onPause()"
);
mSyncer
.
onDisappear
();
ensureAlive
();
flutterEngine
.
getLifecycleChannel
().
appIsInactive
();
}
void
onStop
()
{
Log
.
v
(
TAG
,
"onStop()"
);
ensureAlive
();
flutterEngine
.
getLifecycleChannel
().
appIsPaused
();
flutterView
.
detachFromFlutterEngine
();
}
void
onDestroyView
()
{
Log
.
v
(
TAG
,
"onDestroyView()"
);
mSyncer
.
onDestroy
();
ensureAlive
();
flutterView
.
removeOnFirstFrameRenderedListener
(
onFirstFrameRenderedListener
);
}
void
onDetach
()
{
Log
.
v
(
TAG
,
"onDetach()"
);
ensureAlive
();
if
(
host
.
shouldAttachEngineToActivity
())
{
// Notify plugins that they are no longer attached to an Activity.
Log
.
d
(
TAG
,
"Detaching FlutterEngine from the Activity that owns this Fragment."
);
if
(
host
.
getActivity
().
isChangingConfigurations
())
{
flutterEngine
.
getActivityControlSurface
().
detachFromActivityForConfigChanges
();
}
else
{
flutterEngine
.
getActivityControlSurface
().
detachFromActivity
();
}
}
// Null out the platformPlugin to avoid a possible retain cycle between the plugin, this Fragment,
// and this Fragment's Activity.
if
(
platformPlugin
!=
null
)
{
platformPlugin
.
destroy
();
platformPlugin
=
null
;
}
// Destroy our FlutterEngine if we're not set to retain it.
if
(
host
.
shouldDestroyEngineWithHost
())
{
flutterEngine
.
destroy
();
if
(
host
.
getCachedEngineId
()
!=
null
)
{
FlutterEngineCache
.
getInstance
().
remove
(
host
.
getCachedEngineId
());
}
flutterEngine
=
null
;
}
}
void
onBackPressed
()
{
mSyncer
.
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.");
// }
}
void
onRequestPermissionsResult
(
int
requestCode
,
@NonNull
String
[]
permissions
,
@NonNull
int
[]
grantResults
)
{
mSyncer
.
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
ensureAlive
();
if
(
flutterEngine
!=
null
)
{
Log
.
v
(
TAG
,
"Forwarding onRequestPermissionsResult() to FlutterEngine:\n"
+
"requestCode: "
+
requestCode
+
"\n"
+
"permissions: "
+
Arrays
.
toString
(
permissions
)
+
"\n"
+
"grantResults: "
+
Arrays
.
toString
(
grantResults
));
flutterEngine
.
getActivityControlSurface
().
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
}
else
{
Log
.
w
(
TAG
,
"onRequestPermissionResult() invoked before FlutterFragment was attached to an Activity."
);
}
}
void
onNewIntent
(
@NonNull
Intent
intent
)
{
mSyncer
.
onNewIntent
(
intent
);
ensureAlive
();
if
(
flutterEngine
!=
null
)
{
Log
.
v
(
TAG
,
"Forwarding onNewIntent() to FlutterEngine."
);
flutterEngine
.
getActivityControlSurface
().
onNewIntent
(
intent
);
}
else
{
Log
.
w
(
TAG
,
"onNewIntent() invoked before FlutterFragment was attached to an Activity."
);
}
}
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
mSyncer
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
Map
<
String
,
Object
>
result
=
null
;
if
(
data
!=
null
)
{
Serializable
rlt
=
data
.
getSerializableExtra
(
RESULT_KEY
);
if
(
rlt
instanceof
Map
)
{
result
=
(
Map
<
String
,
Object
>)
rlt
;
}
}
mSyncer
.
onContainerResult
(
requestCode
,
resultCode
,
result
);
ensureAlive
();
if
(
flutterEngine
!=
null
)
{
Log
.
v
(
TAG
,
"Forwarding onActivityResult() to FlutterEngine:\n"
+
"requestCode: "
+
requestCode
+
"\n"
+
"resultCode: "
+
resultCode
+
"\n"
+
"data: "
+
data
);
flutterEngine
.
getActivityControlSurface
().
onActivityResult
(
requestCode
,
resultCode
,
data
);
}
else
{
Log
.
w
(
TAG
,
"onActivityResult() invoked before FlutterFragment was attached to an Activity."
);
}
}
void
onUserLeaveHint
()
{
ensureAlive
();
if
(
flutterEngine
!=
null
)
{
Log
.
v
(
TAG
,
"Forwarding onUserLeaveHint() to FlutterEngine."
);
flutterEngine
.
getActivityControlSurface
().
onUserLeaveHint
();
}
else
{
Log
.
w
(
TAG
,
"onUserLeaveHint() invoked before FlutterFragment was attached to an Activity."
);
}
}
void
onTrimMemory
(
int
level
)
{
mSyncer
.
onTrimMemory
(
level
);
ensureAlive
();
if
(
flutterEngine
!=
null
)
{
// Use a trim level delivered while the application is running so the
// framework has a chance to react to the notification.
if
(
level
==
TRIM_MEMORY_RUNNING_LOW
)
{
Log
.
v
(
TAG
,
"Forwarding onTrimMemory() to FlutterEngine. Level: "
+
level
);
flutterEngine
.
getSystemChannel
().
sendMemoryPressureWarning
();
}
}
else
{
Log
.
w
(
TAG
,
"onTrimMemory() invoked before FlutterFragment was attached to an Activity."
);
}
}
void
onLowMemory
()
{
Log
.
v
(
TAG
,
"Forwarding onLowMemory() to FlutterEngine."
);
mSyncer
.
onLowMemory
();
ensureAlive
();
flutterEngine
.
getSystemChannel
().
sendMemoryPressureWarning
();
}
/**
* Ensures that this delegate has not been {@link #release()}'ed.
* <p>
* An {@code IllegalStateException} is thrown if this delegate has been {@link #release()}'ed.
*/
private
void
ensureAlive
()
{
if
(
host
==
null
)
{
throw
new
IllegalStateException
(
"Cannot execute method on a destroyed FlutterActivityAndFragmentDelegate."
);
}
}
@Override
public
Activity
getContextActivity
()
{
return
(
Activity
)
this
.
host
;
}
@Override
public
FlutterSplashView
getBoostFlutterView
()
{
return
this
.
flutterSplashView
;
}
@Override
public
void
finishContainer
(
Map
<
String
,
Object
>
result
)
{
Activity
activity
=
(
Activity
)
this
.
host
;
activity
.
finish
();
}
@Override
public
String
getContainerUrl
()
{
return
"flutterPage"
;
}
@Override
public
Map
getContainerUrlParams
()
{
return
null
;
}
@Override
public
void
onContainerShown
()
{
}
@Override
public
void
onContainerHidden
()
{
}
/**
* The {@link FlutterActivity} or {@link FlutterFragment} that owns this
* {@code FlutterActivityAndFragmentDelegate}.
*/
/* package */
interface
Host
extends
SplashScreenProvider
,
FlutterEngineProvider
,
FlutterEngineConfigurator
{
/**
* Returns the {@link Context} that backs the host {@link Activity} or {@code Fragment}.
*/
@NonNull
Context
getContext
();
/**
* Returns the host {@link Activity} or the {@code Activity} that is currently attached
* to the host {@code Fragment}.
*/
@Nullable
Activity
getActivity
();
/**
* Returns the {@link Lifecycle} that backs the host {@link Activity} or {@code Fragment}.
*/
@NonNull
Lifecycle
getLifecycle
();
/**
* Returns the {@link FlutterShellArgs} that should be used when initializing Flutter.
*/
@NonNull
FlutterShellArgs
getFlutterShellArgs
();
/**
* Returns the ID of a statically cached {@link FlutterEngine} to use within this
* delegate's host, or {@code null} if this delegate's host does not want to
* use a cached {@link FlutterEngine}.
*/
@Nullable
String
getCachedEngineId
();
/**
* Returns true if the {@link FlutterEngine} used in this delegate should be destroyed
* when the host/delegate are destroyed.
* <p>
* The default value is {@code true} in cases where {@code FlutterFragment} created its own
* {@link FlutterEngine}, and {@code false} in cases where a cached {@link FlutterEngine} was
* provided.
*/
boolean
shouldDestroyEngineWithHost
();
/**
* Returns the Dart entrypoint that should run when a new {@link FlutterEngine} is
* created.
*/
@NonNull
String
getDartEntrypointFunctionName
();
/**
* Returns the path to the app bundle where the Dart code exists.
*/
@NonNull
String
getAppBundlePath
();
/**
* Returns the initial route that Flutter renders.
*/
@Nullable
String
getInitialRoute
();
/**
* Returns the {@link FlutterView.RenderMode} used by the {@link FlutterView} that
* displays the {@link FlutterEngine}'s content.
*/
@NonNull
FlutterView
.
RenderMode
getRenderMode
();
/**
* Returns the {@link FlutterView.TransparencyMode} used by the {@link FlutterView} that
* displays the {@link FlutterEngine}'s content.
*/
@NonNull
FlutterView
.
TransparencyMode
getTransparencyMode
();
@Nullable
SplashScreen
provideSplashScreen
();
/**
* Returns the {@link FlutterEngine} that should be rendered to a {@link FlutterView}.
* <p>
* If {@code null} is returned, a new {@link FlutterEngine} will be created automatically.
*/
@Nullable
FlutterEngine
provideFlutterEngine
(
@NonNull
Context
context
);
/**
* Hook for the host to create/provide a {@link PlatformPlugin} if the associated
* Flutter experience should control system chrome.
*/
@Nullable
PlatformPlugin
providePlatformPlugin
(
@Nullable
Activity
activity
,
@NonNull
FlutterEngine
flutterEngine
);
/**
* Hook for the host to configure the {@link FlutterEngine} as desired.
*/
void
configureFlutterEngine
(
@NonNull
FlutterEngine
flutterEngine
);
/**
* Returns true if the {@link FlutterEngine}'s plugin system should be connected to the
* host {@link Activity}, allowing plugins to interact with it.
*/
boolean
shouldAttachEngineToActivity
();
/**
* Invoked by this delegate when its {@link FlutterView} has rendered its first Flutter
* frame.
*/
void
onFirstFrameRendered
();
}
}
android/src/main/java/com/idlefish/flutterboost/containers/FlutterSplashView.java
0 → 100644
View file @
d9ac3683
package
com.idlefish.flutterboost.containers
;
import
android.content.Context
;
import
android.os.Bundle
;
import
android.os.Parcel
;
import
android.os.Parcelable
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.util.AttributeSet
;
import
android.view.View
;
import
android.widget.FrameLayout
;
import
com.idlefish.flutterboost.*
;
import
com.idlefish.flutterboost.interfaces.IStateListener
;
import
io.flutter.Log
;
import
io.flutter.embedding.android.FlutterView
;
import
io.flutter.embedding.android.SplashScreen
;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener
;
/**
* {@code View} that displays a {@link SplashScreen} until a given {@link FlutterView}
* renders its first frame.
*/
public
class
FlutterSplashView
extends
FrameLayout
{
private
static
String
TAG
=
"FlutterSplashView"
;
private
FlutterEngine
mFlutterEngine
;
@Nullable
private
SplashScreen
splashScreen
;
@Nullable
private
FlutterView
flutterView
;
@Nullable
private
View
splashScreenView
;
@Nullable
private
Bundle
splashScreenState
;
@Nullable
private
String
transitioningIsolateId
;
@Nullable
private
String
previousCompletedSplashIsolate
;
@NonNull
private
final
FlutterView
.
FlutterEngineAttachmentListener
flutterEngineAttachmentListener
=
new
FlutterView
.
FlutterEngineAttachmentListener
()
{
@Override
public
void
onFlutterEngineAttachedToFlutterView
(
@NonNull
FlutterEngine
engine
)
{
flutterView
.
removeFlutterEngineAttachmentListener
(
this
);
displayFlutterViewWithSplash
(
flutterView
,
splashScreen
);
}
@Override
public
void
onFlutterEngineDetachedFromFlutterView
()
{
}
};
@NonNull
private
final
OnFirstFrameRenderedListener
onFirstFrameRenderedListener
=
new
OnFirstFrameRenderedListener
()
{
@Override
public
void
onFirstFrameRendered
()
{
if
(
splashScreen
!=
null
)
{
transitionToFlutter
();
}
}
};
@NonNull
private
final
Runnable
onTransitionComplete
=
new
Runnable
()
{
@Override
public
void
run
()
{
removeView
(
splashScreenView
);
previousCompletedSplashIsolate
=
transitioningIsolateId
;
}
};
public
FlutterSplashView
(
@NonNull
Context
context
)
{
this
(
context
,
null
,
0
);
}
public
FlutterSplashView
(
@NonNull
Context
context
,
@Nullable
AttributeSet
attrs
)
{
this
(
context
,
attrs
,
0
);
}
public
FlutterSplashView
(
@NonNull
Context
context
,
@Nullable
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
setSaveEnabled
(
true
);
if
(
mFlutterEngine
==
null
)
{
mFlutterEngine
=
NewFlutterBoost
.
instance
().
engineProvider
().
provideEngine
(
context
);
}
}
@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.
* <p>
* If no {@code splashScreen} is provided, this {@code FlutterSplashView} displays the
* given {@code flutterView} on its own.
*/
public
void
displayFlutterViewWithSplash
(
@NonNull
FlutterView
flutterView
,
@Nullable
SplashScreen
splashScreen
)
{
// If we were displaying a previous FlutterView, remove it.
if
(
this
.
flutterView
!=
null
)
{
this
.
flutterView
.
removeOnFirstFrameRenderedListener
(
onFirstFrameRenderedListener
);
removeView
(
this
.
flutterView
);
}
// If we were displaying a previous splash screen View, remove it.
if
(
splashScreenView
!=
null
)
{
removeView
(
splashScreenView
);
}
// Display the new FlutterView.
this
.
flutterView
=
flutterView
;
addView
(
flutterView
);
this
.
splashScreen
=
splashScreen
;
// Display the new splash screen, if needed.
if
(
splashScreen
!=
null
)
{
if
(
isSplashScreenNeededNow
())
{
Log
.
v
(
TAG
,
"Showing splash screen UI."
);
// This is the typical case. A FlutterEngine is attached to the FlutterView and we're
// waiting for the first frame to render. Show a splash UI until that happens.
splashScreenView
=
splashScreen
.
createSplashView
(
getContext
(),
splashScreenState
);
addView
(
this
.
splashScreenView
);
flutterView
.
addOnFirstFrameRenderedListener
(
onFirstFrameRenderedListener
);
}
else
if
(
isSplashScreenTransitionNeededNow
())
{
Log
.
v
(
TAG
,
"Showing an immediate splash transition to Flutter due to previously interrupted transition."
);
splashScreenView
=
splashScreen
.
createSplashView
(
getContext
(),
splashScreenState
);
addView
(
splashScreenView
);
transitionToFlutter
();
}
else
if
(!
flutterView
.
isAttachedToFlutterEngine
())
{
Log
.
v
(
TAG
,
"FlutterView is not yet attached to a FlutterEngine. Showing nothing until a FlutterEngine is attached."
);
flutterView
.
addFlutterEngineAttachmentListener
(
flutterEngineAttachmentListener
);
}
}
}
/**
* Returns true if current conditions require a splash UI to be displayed.
* <p>
* This method does not evaluate whether a previously interrupted splash transition needs
* to resume. See {@link #isSplashScreenTransitionNeededNow()} to answer that question.
*/
private
boolean
isSplashScreenNeededNow
()
{
return
flutterView
!=
null
&&
flutterView
.
isAttachedToFlutterEngine
()
&&
!
flutterView
.
hasRenderedFirstFrame
()
&&
!
hasSplashCompleted
();
}
/**
* Returns true if a previous splash transition was interrupted by recreation, e.g., an
* orientation change, and that previous transition should be resumed.
* <p>
* Not all splash screens are capable of remembering their transition progress. In those
* cases, this method will return false even if a previous visual transition was
* interrupted.
*/
private
boolean
isSplashScreenTransitionNeededNow
()
{
return
flutterView
!=
null
&&
flutterView
.
isAttachedToFlutterEngine
()
&&
splashScreen
!=
null
&&
splashScreen
.
doesSplashViewRememberItsTransition
()
&&
wasPreviousSplashTransitionInterrupted
();
}
/**
* Returns true if a splash screen was transitioning to a Flutter experience and was then
* interrupted, e.g., by an Android configuration change. Returns false otherwise.
* <p>
* Invoking this method expects that a {@code flutterView} exists and it is attached to a
* {@code FlutterEngine}.
*/
private
boolean
wasPreviousSplashTransitionInterrupted
()
{
if
(
flutterView
==
null
)
{
throw
new
IllegalStateException
(
"Cannot determine if previous splash transition was "
+
"interrupted when no FlutterView is set."
);
}
if
(!
flutterView
.
isAttachedToFlutterEngine
())
{
throw
new
IllegalStateException
(
"Cannot determine if previous splash transition was "
+
"interrupted when no FlutterEngine is attached to our FlutterView. This question "
+
"depends on an isolate ID to differentiate Flutter experiences."
);
}
return
flutterView
.
hasRenderedFirstFrame
()
&&
!
hasSplashCompleted
();
}
/**
* Returns true if a splash UI for a specific Flutter experience has already completed.
* <p>
* A "specific Flutter experience" is defined as any experience with the same Dart isolate
* ID. The purpose of this distinction is to prevent a situation where a user gets past a
* splash UI, rotates the device (or otherwise triggers a recreation) and the splash screen
* reappears.
* <p>
* An isolate ID is deemed reasonable as a key for a completion event because a Dart isolate
* cannot be entered twice. Therefore, a single Dart isolate cannot return to an "un-rendered"
* state after having previously rendered content.
*/
private
boolean
hasSplashCompleted
()
{
if
(
flutterView
==
null
)
{
throw
new
IllegalStateException
(
"Cannot determine if splash has completed when no FlutterView "
+
"is set."
);
}
if
(!
flutterView
.
isAttachedToFlutterEngine
())
{
throw
new
IllegalStateException
(
"Cannot determine if splash has completed when no "
+
"FlutterEngine is attached to our FlutterView. This question depends on an isolate ID "
+
"to differentiate Flutter experiences."
);
}
// A null isolate ID on a non-null FlutterEngine indicates that the Dart isolate has not
// been initialized. Therefore, no frame has been rendered for this engine, which means
// no splash screen could have completed yet.
return
flutterView
.
getAttachedFlutterEngine
().
getDartExecutor
().
getIsolateServiceId
()
!=
null
&&
flutterView
.
getAttachedFlutterEngine
().
getDartExecutor
().
getIsolateServiceId
().
equals
(
previousCompletedSplashIsolate
);
}
/**
* Transitions a splash screen to the Flutter UI.
* <p>
* This method requires that our FlutterView be attached to an engine, and that engine have
* a Dart isolate ID. It also requires that a {@code splashScreen} exist.
*/
private
void
transitionToFlutter
()
{
transitioningIsolateId
=
flutterView
.
getAttachedFlutterEngine
().
getDartExecutor
().
getIsolateServiceId
();
Log
.
v
(
TAG
,
"Transitioning splash screen to a Flutter UI. Isolate: "
+
transitioningIsolateId
);
splashScreen
.
transitionToFlutter
(
onTransitionComplete
);
}
public
static
class
SavedState
extends
BaseSavedState
{
public
static
Creator
CREATOR
=
new
Creator
()
{
@Override
public
SavedState
createFromParcel
(
Parcel
source
)
{
return
new
SavedState
(
source
);
}
@Override
public
SavedState
[]
newArray
(
int
size
)
{
return
new
SavedState
[
size
];
}
};
private
String
previousCompletedSplashIsolate
;
private
Bundle
splashScreenState
;
SavedState
(
Parcelable
superState
)
{
super
(
superState
);
}
SavedState
(
Parcel
source
)
{
super
(
source
);
previousCompletedSplashIsolate
=
source
.
readString
();
splashScreenState
=
source
.
readBundle
(
getClass
().
getClassLoader
());
}
@Override
public
void
writeToParcel
(
Parcel
out
,
int
flags
)
{
super
.
writeToParcel
(
out
,
flags
);
out
.
writeString
(
previousCompletedSplashIsolate
);
out
.
writeBundle
(
splashScreenState
);
}
}
public
void
onAttach
()
{
Debuger
.
log
(
"BoostFlutterView onAttach"
);
flutterView
.
attachToFlutterEngine
(
mFlutterEngine
);
}
public
void
onDetach
()
{
Debuger
.
log
(
"BoostFlutterView onDetach"
);
flutterView
.
detachFromFlutterEngine
();
}
}
\ No newline at end of file
android/src/main/java/com/idlefish/flutterboost/containers/NewBoostFlutterActivity.java
0 → 100644
View file @
d9ac3683
package
com.idlefish.flutterboost.containers
;
import
android.app.Activity
;
import
android.arch.lifecycle.Lifecycle
;
import
android.arch.lifecycle.LifecycleOwner
;
import
android.arch.lifecycle.Lifecycle
;
import
android.arch.lifecycle.LifecycleOwner
;
import
android.arch.lifecycle.LifecycleRegistry
;
import
android.arch.lifecycle.Lifecycle.Event
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.ActivityInfo
;
import
android.content.pm.ApplicationInfo
;
import
android.content.pm.PackageManager
;
import
android.graphics.Color
;
import
android.graphics.drawable.ColorDrawable
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.view.View
;
import
android.view.Window
;
import
android.view.WindowManager
;
import
com.idlefish.flutterboost.FlutterBoost
;
import
com.idlefish.flutterboost.NewFlutterBoost
;
import
com.idlefish.flutterboost.Utils
;
import
io.flutter.Log
;
import
io.flutter.embedding.android.DrawableSplashScreen
;
import
io.flutter.embedding.android.FlutterView
;
import
io.flutter.embedding.android.SplashScreen
;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.embedding.engine.FlutterShellArgs
;
import
io.flutter.plugin.platform.PlatformPlugin
;
import
io.flutter.view.FlutterMain
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
NewBoostFlutterActivity
extends
Activity
implements
FlutterActivityAndFragmentDelegate
.
Host
,
LifecycleOwner
{
private
static
final
String
TAG
=
"NewBoostFlutterActivity"
;
// Meta-data arguments, processed from manifest XML.
protected
static
final
String
DART_ENTRYPOINT_META_DATA_KEY
=
"io.flutter.Entrypoint"
;
protected
static
final
String
INITIAL_ROUTE_META_DATA_KEY
=
"io.flutter.InitialRoute"
;
protected
static
final
String
SPLASH_SCREEN_META_DATA_KEY
=
"io.flutter.embedding.android.SplashScreenDrawable"
;
protected
static
final
String
NORMAL_THEME_META_DATA_KEY
=
"io.flutter.embedding.android.NormalTheme"
;
// Intent extra arguments.
protected
static
final
String
EXTRA_DART_ENTRYPOINT
=
"dart_entrypoint"
;
protected
static
final
String
EXTRA_INITIAL_ROUTE
=
"initial_route"
;
protected
static
final
String
EXTRA_BACKGROUND_MODE
=
"background_mode"
;
protected
static
final
String
EXTRA_CACHED_ENGINE_ID
=
"cached_engine_id"
;
protected
static
final
String
EXTRA_DESTROY_ENGINE_WITH_ACTIVITY
=
"destroy_engine_with_activity"
;
// Default configuration.
protected
static
final
String
DEFAULT_DART_ENTRYPOINT
=
"main"
;
protected
static
final
String
DEFAULT_INITIAL_ROUTE
=
"/"
;
protected
static
final
String
DEFAULT_BACKGROUND_MODE
=
BackgroundMode
.
opaque
.
name
();
public
static
Intent
createDefaultIntent
(
@NonNull
Context
launchContext
)
{
return
withNewEngine
().
build
(
launchContext
);
}
public
static
NewEngineIntentBuilder
withNewEngine
()
{
return
new
NewEngineIntentBuilder
(
NewBoostFlutterActivity
.
class
);
}
public
static
class
NewEngineIntentBuilder
{
private
final
Class
<?
extends
NewBoostFlutterActivity
>
activityClass
;
private
String
dartEntrypoint
=
DEFAULT_DART_ENTRYPOINT
;
private
String
initialRoute
=
DEFAULT_INITIAL_ROUTE
;
private
String
backgroundMode
=
DEFAULT_BACKGROUND_MODE
;
private
String
url
=
""
;
private
Map
params
=
null
;
protected
NewEngineIntentBuilder
(
@NonNull
Class
<?
extends
NewBoostFlutterActivity
>
activityClass
)
{
this
.
activityClass
=
activityClass
;
}
public
NewEngineIntentBuilder
dartEntrypoint
(
@NonNull
String
dartEntrypoint
)
{
this
.
dartEntrypoint
=
dartEntrypoint
;
return
this
;
}
public
NewEngineIntentBuilder
url
(
@NonNull
String
url
)
{
this
.
url
=
url
;
return
this
;
}
public
NewEngineIntentBuilder
params
(
@NonNull
Map
params
)
{
this
.
params
=
params
;
return
this
;
}
public
NewEngineIntentBuilder
initialRoute
(
@NonNull
String
initialRoute
)
{
this
.
initialRoute
=
initialRoute
;
return
this
;
}
public
NewEngineIntentBuilder
backgroundMode
(
@NonNull
BackgroundMode
backgroundMode
)
{
this
.
backgroundMode
=
backgroundMode
.
name
();
return
this
;
}
public
Intent
build
(
@NonNull
Context
context
)
{
return
new
Intent
(
context
,
activityClass
)
.
putExtra
(
EXTRA_DART_ENTRYPOINT
,
dartEntrypoint
)
.
putExtra
(
EXTRA_INITIAL_ROUTE
,
initialRoute
)
.
putExtra
(
EXTRA_BACKGROUND_MODE
,
backgroundMode
)
.
putExtra
(
EXTRA_DESTROY_ENGINE_WITH_ACTIVITY
,
false
)
.
putExtra
(
"url"
,
url
)
.
putExtra
(
"params"
,
(
HashMap
)
params
);
}
}
private
FlutterActivityAndFragmentDelegate
delegate
;
@NonNull
private
LifecycleRegistry
lifecycle
;
public
NewBoostFlutterActivity
()
{
lifecycle
=
new
LifecycleRegistry
(
this
);
}
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
switchLaunchThemeForNormalTheme
();
super
.
onCreate
(
savedInstanceState
);
lifecycle
.
handleLifecycleEvent
(
Lifecycle
.
Event
.
ON_CREATE
);
delegate
=
new
FlutterActivityAndFragmentDelegate
(
this
);
delegate
.
onAttach
(
this
);
configureWindowForTransparency
();
setContentView
(
createFlutterView
());
configureStatusBarForFullscreenFlutterExperience
();
}
private
void
switchLaunchThemeForNormalTheme
()
{
try
{
ActivityInfo
activityInfo
=
getPackageManager
().
getActivityInfo
(
getComponentName
(),
PackageManager
.
GET_META_DATA
);
if
(
activityInfo
.
metaData
!=
null
)
{
int
normalThemeRID
=
activityInfo
.
metaData
.
getInt
(
NORMAL_THEME_META_DATA_KEY
,
-
1
);
if
(
normalThemeRID
!=
-
1
)
{
setTheme
(
normalThemeRID
);
}
}
else
{
Log
.
d
(
TAG
,
"Using the launch theme as normal theme."
);
}
}
catch
(
PackageManager
.
NameNotFoundException
exception
)
{
Log
.
e
(
TAG
,
"Could not read meta-data for FlutterActivity. Using the launch theme as normal theme."
);
}
}
@Nullable
@Override
public
SplashScreen
provideSplashScreen
()
{
Drawable
manifestSplashDrawable
=
getSplashScreenFromManifest
();
if
(
manifestSplashDrawable
!=
null
)
{
return
new
DrawableSplashScreen
(
manifestSplashDrawable
);
}
else
{
return
null
;
}
}
/**
* Returns a {@link Drawable} to be used as a splash screen as requested by meta-data in the
* {@code AndroidManifest.xml} file, or null if no such splash screen is requested.
* <p>
* See {@link #SPLASH_SCREEN_META_DATA_KEY} for the meta-data key to be used in a
* manifest file.
*/
@Nullable
@SuppressWarnings
(
"deprecation"
)
private
Drawable
getSplashScreenFromManifest
()
{
try
{
ActivityInfo
activityInfo
=
getPackageManager
().
getActivityInfo
(
getComponentName
(),
PackageManager
.
GET_META_DATA
|
PackageManager
.
GET_ACTIVITIES
);
Bundle
metadata
=
activityInfo
.
metaData
;
Integer
splashScreenId
=
metadata
!=
null
?
metadata
.
getInt
(
SPLASH_SCREEN_META_DATA_KEY
)
:
null
;
return
splashScreenId
!=
null
?
Build
.
VERSION
.
SDK_INT
>
Build
.
VERSION_CODES
.
LOLLIPOP
?
getResources
().
getDrawable
(
splashScreenId
,
getTheme
())
:
getResources
().
getDrawable
(
splashScreenId
)
:
null
;
}
catch
(
PackageManager
.
NameNotFoundException
e
)
{
// This is never expected to happen.
return
null
;
}
}
/**
* Sets this {@code Activity}'s {@code Window} background to be transparent, and hides the status
* bar, if this {@code Activity}'s desired {@link BackgroundMode} is {@link BackgroundMode#transparent}.
* <p>
* For {@code Activity} transparency to work as expected, the theme applied to this {@code Activity}
* must include {@code <item name="android:windowIsTranslucent">true</item>}.
*/
private
void
configureWindowForTransparency
()
{
BackgroundMode
backgroundMode
=
getBackgroundMode
();
if
(
backgroundMode
==
BackgroundMode
.
transparent
)
{
getWindow
().
setBackgroundDrawable
(
new
ColorDrawable
(
Color
.
TRANSPARENT
));
getWindow
().
setFlags
(
WindowManager
.
LayoutParams
.
FLAG_LAYOUT_NO_LIMITS
,
WindowManager
.
LayoutParams
.
FLAG_LAYOUT_NO_LIMITS
);
}
}
@NonNull
private
View
createFlutterView
()
{
return
delegate
.
onCreateView
(
null
/* inflater */
,
null
/* container */
,
null
/* savedInstanceState */
);
}
private
void
configureStatusBarForFullscreenFlutterExperience
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
Window
window
=
getWindow
();
window
.
addFlags
(
WindowManager
.
LayoutParams
.
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
);
window
.
setStatusBarColor
(
Color
.
TRANSPARENT
);
window
.
getDecorView
().
setSystemUiVisibility
(
PlatformPlugin
.
DEFAULT_SYSTEM_UI
);
}
Utils
.
setStatusBarLightMode
(
this
,
true
);
}
@Override
protected
void
onStart
()
{
super
.
onStart
();
lifecycle
.
handleLifecycleEvent
(
Lifecycle
.
Event
.
ON_START
);
delegate
.
onStart
();
}
@Override
protected
void
onResume
()
{
super
.
onResume
();
lifecycle
.
handleLifecycleEvent
(
Lifecycle
.
Event
.
ON_RESUME
);
delegate
.
onResume
();
}
@Override
public
void
onPostResume
()
{
super
.
onPostResume
();
delegate
.
onPostResume
();
}
@Override
protected
void
onPause
()
{
super
.
onPause
();
delegate
.
onPause
();
lifecycle
.
handleLifecycleEvent
(
Lifecycle
.
Event
.
ON_PAUSE
);
}
@Override
protected
void
onStop
()
{
super
.
onStop
();
delegate
.
onStop
();
// lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
@Override
protected
void
onDestroy
()
{
super
.
onDestroy
();
delegate
.
onDestroyView
();
delegate
.
onDetach
();
// lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
@Override
protected
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
delegate
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
}
@Override
protected
void
onNewIntent
(
@NonNull
Intent
intent
)
{
// TODO(mattcarroll): change G3 lint rule that forces us to call super
super
.
onNewIntent
(
intent
);
delegate
.
onNewIntent
(
intent
);
}
@Override
public
void
onBackPressed
()
{
delegate
.
onBackPressed
();
}
@Override
public
void
onRequestPermissionsResult
(
int
requestCode
,
@NonNull
String
[]
permissions
,
@NonNull
int
[]
grantResults
)
{
delegate
.
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
}
@Override
public
void
onUserLeaveHint
()
{
delegate
.
onUserLeaveHint
();
}
@Override
public
void
onTrimMemory
(
int
level
)
{
super
.
onTrimMemory
(
level
);
delegate
.
onTrimMemory
(
level
);
}
/**
* {@link FlutterActivityAndFragmentDelegate.Host} method that is used by
* {@link FlutterActivityAndFragmentDelegate} to obtain a {@code Context} reference as
* needed.
*/
@Override
@NonNull
public
Context
getContext
()
{
return
this
;
}
/**
* {@link FlutterActivityAndFragmentDelegate.Host} method that is used by
* {@link FlutterActivityAndFragmentDelegate} to obtain an {@code Activity} reference as
* needed. This reference is used by the delegate to instantiate a {@link FlutterView},
* a {@link PlatformPlugin}, and to determine if the {@code Activity} is changing
* configurations.
*/
@Override
@NonNull
public
Activity
getActivity
()
{
return
this
;
}
/**
* {@link FlutterActivityAndFragmentDelegate.Host} method that is used by
* {@link FlutterActivityAndFragmentDelegate} to obtain a {@code Lifecycle} reference as
* needed. This reference is used by the delegate to provide Flutter plugins with access
* to lifecycle events.
*/
@Override
@NonNull
public
Lifecycle
getLifecycle
()
{
return
lifecycle
;
}
/**
* {@link FlutterActivityAndFragmentDelegate.Host} method that is used by
* {@link FlutterActivityAndFragmentDelegate} to obtain Flutter shell arguments when
* initializing Flutter.
*/
@NonNull
@Override
public
FlutterShellArgs
getFlutterShellArgs
()
{
return
FlutterShellArgs
.
fromIntent
(
getIntent
());
}
/**
* Returns the ID of a statically cached {@link FlutterEngine} to use within this
* {@code FlutterActivity}, or {@code null} if this {@code FlutterActivity} does not want to
* use a cached {@link FlutterEngine}.
*/
@Override
@Nullable
public
String
getCachedEngineId
()
{
return
getIntent
().
getStringExtra
(
EXTRA_CACHED_ENGINE_ID
);
}
/**
* Returns false if the {@link FlutterEngine} backing this {@code FlutterActivity} should
* outlive this {@code FlutterActivity}, or true to be destroyed when the {@code FlutterActivity}
* is destroyed.
* <p>
* The default value is {@code true} in cases where {@code FlutterActivity} created its own
* {@link FlutterEngine}, and {@code false} in cases where a cached {@link FlutterEngine} was
* provided.
*/
@Override
public
boolean
shouldDestroyEngineWithHost
()
{
return
getIntent
().
getBooleanExtra
(
EXTRA_DESTROY_ENGINE_WITH_ACTIVITY
,
false
);
}
/**
* The Dart entrypoint that will be executed as soon as the Dart snapshot is loaded.
* <p>
* This preference can be controlled with 2 methods:
* <ol>
* <li>Pass a {@code String} as {@link #EXTRA_DART_ENTRYPOINT} with the launching {@code Intent}, or</li>
* <li>Set a {@code <meta-data>} called {@link #DART_ENTRYPOINT_META_DATA_KEY} for this
* {@code Activity} in the Android manifest.</li>
* </ol>
* If both preferences are set, the {@code Intent} preference takes priority.
* <p>
* The reason that a {@code <meta-data>} preference is supported is because this {@code Activity}
* might be the very first {@code Activity} launched, which means the developer won't have
* control over the incoming {@code Intent}.
* <p>
* Subclasses may override this method to directly control the Dart entrypoint.
*/
@NonNull
public
String
getDartEntrypointFunctionName
()
{
if
(
getIntent
().
hasExtra
(
EXTRA_DART_ENTRYPOINT
))
{
return
getIntent
().
getStringExtra
(
EXTRA_DART_ENTRYPOINT
);
}
try
{
ActivityInfo
activityInfo
=
getPackageManager
().
getActivityInfo
(
getComponentName
(),
PackageManager
.
GET_META_DATA
|
PackageManager
.
GET_ACTIVITIES
);
Bundle
metadata
=
activityInfo
.
metaData
;
String
desiredDartEntrypoint
=
metadata
!=
null
?
metadata
.
getString
(
DART_ENTRYPOINT_META_DATA_KEY
)
:
null
;
return
desiredDartEntrypoint
!=
null
?
desiredDartEntrypoint
:
DEFAULT_DART_ENTRYPOINT
;
}
catch
(
PackageManager
.
NameNotFoundException
e
)
{
return
DEFAULT_DART_ENTRYPOINT
;
}
}
/**
* The initial route that a Flutter app will render upon loading and executing its Dart code.
* <p>
* This preference can be controlled with 2 methods:
* <ol>
* <li>Pass a boolean as {@link #EXTRA_INITIAL_ROUTE} with the launching {@code Intent}, or</li>
* <li>Set a {@code <meta-data>} called {@link #INITIAL_ROUTE_META_DATA_KEY} for this
* {@code Activity} in the Android manifest.</li>
* </ol>
* If both preferences are set, the {@code Intent} preference takes priority.
* <p>
* The reason that a {@code <meta-data>} preference is supported is because this {@code Activity}
* might be the very first {@code Activity} launched, which means the developer won't have
* control over the incoming {@code Intent}.
* <p>
* Subclasses may override this method to directly control the initial route.
*/
@NonNull
public
String
getInitialRoute
()
{
if
(
getIntent
().
hasExtra
(
EXTRA_INITIAL_ROUTE
))
{
return
getIntent
().
getStringExtra
(
EXTRA_INITIAL_ROUTE
);
}
try
{
ActivityInfo
activityInfo
=
getPackageManager
().
getActivityInfo
(
getComponentName
(),
PackageManager
.
GET_META_DATA
|
PackageManager
.
GET_ACTIVITIES
);
Bundle
metadata
=
activityInfo
.
metaData
;
String
desiredInitialRoute
=
metadata
!=
null
?
metadata
.
getString
(
INITIAL_ROUTE_META_DATA_KEY
)
:
null
;
return
desiredInitialRoute
!=
null
?
desiredInitialRoute
:
DEFAULT_INITIAL_ROUTE
;
}
catch
(
PackageManager
.
NameNotFoundException
e
)
{
return
DEFAULT_INITIAL_ROUTE
;
}
}
/**
* The path to the bundle that contains this Flutter app's resources, e.g., Dart code snapshots.
* <p>
* When this {@code FlutterActivity} is run by Flutter tooling and a data String is included
* in the launching {@code Intent}, that data String is interpreted as an app bundle path.
* <p>
* By default, the app bundle path is obtained from {@link FlutterMain#findAppBundlePath()}.
* <p>
* Subclasses may override this method to return a custom app bundle path.
*/
@NonNull
public
String
getAppBundlePath
()
{
// If this Activity was launched from tooling, and the incoming Intent contains
// a custom app bundle path, return that path.
// TODO(mattcarroll): determine if we should have an explicit FlutterTestActivity instead of conflating.
if
(
isDebuggable
()
&&
Intent
.
ACTION_RUN
.
equals
(
getIntent
().
getAction
()))
{
String
appBundlePath
=
getIntent
().
getDataString
();
if
(
appBundlePath
!=
null
)
{
return
appBundlePath
;
}
}
// Return the default app bundle path.
// TODO(mattcarroll): move app bundle resolution into an appropriately named class.
return
FlutterMain
.
findAppBundlePath
();
}
/**
* Returns true if Flutter is running in "debug mode", and false otherwise.
* <p>
* Debug mode allows Flutter to operate with hot reload and hot restart. Release mode does not.
*/
private
boolean
isDebuggable
()
{
return
(
getApplicationInfo
().
flags
&
ApplicationInfo
.
FLAG_DEBUGGABLE
)
!=
0
;
}
/**
* {@link FlutterActivityAndFragmentDelegate.Host} method that is used by
* {@link FlutterActivityAndFragmentDelegate} to obtain the desired {@link FlutterView.RenderMode}
* that should be used when instantiating a {@link FlutterView}.
*/
@NonNull
@Override
public
FlutterView
.
RenderMode
getRenderMode
()
{
return
getBackgroundMode
()
==
BackgroundMode
.
opaque
?
FlutterView
.
RenderMode
.
surface
:
FlutterView
.
RenderMode
.
texture
;
}
/**
* {@link FlutterActivityAndFragmentDelegate.Host} method that is used by
* {@link FlutterActivityAndFragmentDelegate} to obtain the desired
* {@link FlutterView.TransparencyMode} that should be used when instantiating a
* {@link FlutterView}.
*/
@NonNull
@Override
public
FlutterView
.
TransparencyMode
getTransparencyMode
()
{
return
getBackgroundMode
()
==
BackgroundMode
.
opaque
?
FlutterView
.
TransparencyMode
.
opaque
:
FlutterView
.
TransparencyMode
.
transparent
;
}
/**
* The desired window background mode of this {@code Activity}, which defaults to
* {@link BackgroundMode#opaque}.
*/
@NonNull
protected
BackgroundMode
getBackgroundMode
()
{
if
(
getIntent
().
hasExtra
(
EXTRA_BACKGROUND_MODE
))
{
return
BackgroundMode
.
valueOf
(
getIntent
().
getStringExtra
(
EXTRA_BACKGROUND_MODE
));
}
else
{
return
BackgroundMode
.
opaque
;
}
}
/**
* Hook for subclasses to easily provide a custom {@link FlutterEngine}.
* <p>
* This hook is where a cached {@link FlutterEngine} should be provided, if a cached
* {@link FlutterEngine} is desired.
*/
@Nullable
@Override
public
FlutterEngine
provideFlutterEngine
(
@NonNull
Context
context
)
{
// No-op. Hook for subclasses.
return
NewFlutterBoost
.
instance
().
engineProvider
().
provideEngine
(
this
);
}
/**
* Hook for subclasses to obtain a reference to the {@link FlutterEngine} that is owned
* by this {@code FlutterActivity}.
*/
@Nullable
protected
FlutterEngine
getFlutterEngine
()
{
return
delegate
.
getFlutterEngine
();
}
@Nullable
@Override
public
PlatformPlugin
providePlatformPlugin
(
@Nullable
Activity
activity
,
@NonNull
FlutterEngine
flutterEngine
)
{
if
(
activity
!=
null
)
{
return
new
PlatformPlugin
(
getActivity
(),
flutterEngine
.
getPlatformChannel
());
}
else
{
return
null
;
}
}
/**
* Hook for subclasses to easily configure a {@code FlutterEngine}, e.g., register
* plugins.
* <p>
* This method is called after {@link #provideFlutterEngine(Context)}.
*/
@Override
public
void
configureFlutterEngine
(
@NonNull
FlutterEngine
flutterEngine
)
{
// No-op. Hook for subclasses.
}
@Override
public
boolean
shouldAttachEngineToActivity
()
{
return
true
;
}
@Override
public
void
onFirstFrameRendered
()
{
}
/**
* The mode of the background of a {@code FlutterActivity}, either opaque or transparent.
*/
public
enum
BackgroundMode
{
/**
* Indicates a FlutterActivity with an opaque background. This is the default.
*/
opaque
,
/**
* Indicates a FlutterActivity with a transparent background.
*/
transparent
}
}
android/src/main/java/com/idlefish/flutterboost/interfaces/IFlutterEngineProvider.java
View file @
d9ac3683
...
...
@@ -26,6 +26,8 @@ package com.idlefish.flutterboost.interfaces;
import
android.content.Context
;
import
com.idlefish.flutterboost.BoostFlutterEngine
;
import
io.flutter.embedding.engine.FlutterEngine
;
/**
* a flutter engine provider
*/
...
...
@@ -36,18 +38,18 @@ public interface IFlutterEngineProvider {
* @param context
* @return
*/
Boost
FlutterEngine
createEngine
(
Context
context
);
FlutterEngine
createEngine
(
Context
context
);
/**
* provide a flutter engine
* @param context
* @return
*/
Boost
FlutterEngine
provideEngine
(
Context
context
);
FlutterEngine
provideEngine
(
Context
context
);
/**
* may return null
* @return
*/
Boost
FlutterEngine
tryGetEngine
();
FlutterEngine
tryGetEngine
();
}
android/src/main/java/com/idlefish/flutterboost/interfaces/IFlutterViewContainer.java
View file @
d9ac3683
...
...
@@ -26,6 +26,7 @@ package com.idlefish.flutterboost.interfaces;
import
android.app.Activity
;
import
com.idlefish.flutterboost.BoostFlutterView
;
import
com.idlefish.flutterboost.containers.FlutterSplashView
;
import
java.util.Map
;
...
...
@@ -41,7 +42,7 @@ public interface IFlutterViewContainer {
* provide a flutter view
* @return
*/
BoostFlutter
View
getBoostFlutterView
();
FlutterSplash
View
getBoostFlutterView
();
/**
* call to destroy the container
...
...
android/src/main/java/com/idlefish/flutterboost/interfaces/INativeRouter.java
0 → 100644
View file @
d9ac3683
package
com.idlefish.flutterboost.interfaces
;
import
android.content.Context
;
import
java.util.Map
;
public
interface
INativeRouter
{
void
openContainer
(
Context
context
,
String
url
,
Map
<
String
,
Object
>
urlParams
,
int
requestCode
,
Map
<
String
,
Object
>
exts
);
void
closeContainer
(
IContainerRecord
record
,
Map
<
String
,
Object
>
result
,
Map
<
String
,
Object
>
exts
);
}
android/src/main/java/com/idlefish/flutterboost/interfaces/IStateListener.java
View file @
d9ac3683
package
com.idlefish.flutterboost.interfaces
;
import
com.idlefish.flutterboost.
BoostChannel
;
import
com.idlefish.flutterboost.
FlutterBoostPlugin
;
import
com.idlefish.flutterboost.BoostFlutterEngine
;
import
com.idlefish.flutterboost.BoostFlutterView
;
...
...
@@ -9,7 +9,7 @@ import io.flutter.plugin.common.PluginRegistry;
public
interface
IStateListener
{
void
onEngineCreated
(
BoostFlutterEngine
engine
);
void
onEngineStarted
(
BoostFlutterEngine
engine
);
void
onChannelRegistered
(
PluginRegistry
.
Registrar
registrar
,
BoostChannel
channel
);
void
onChannelRegistered
(
PluginRegistry
.
Registrar
registrar
,
FlutterBoostPlugin
channel
);
void
onFlutterViewInited
(
BoostFlutterEngine
engine
,
BoostFlutterView
flutterView
);
void
beforeEngineAttach
(
BoostFlutterEngine
engine
,
BoostFlutterView
flutterView
);
void
afterEngineAttached
(
BoostFlutterEngine
engine
,
BoostFlutterView
flutterView
);
...
...
example/android/app/build.gradle
View file @
d9ac3683
...
...
@@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply
from:
"$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android
{
compileSdkVersion
2
6
compileSdkVersion
2
8
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
2
6
targetSdkVersion
2
8
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:26.1
.0'
implementation
'com.android.support:appcompat-v7:26.1.0'
implementation
'com.android.support:
appcompat-v7:28.0
.0'
}
example/android/app/src/main/AndroidManifest.xml
View file @
d9ac3683
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
package=
"com.taobao.idlefish.flutterboostexample"
>
<!-- The INTERNET permission is required for development. Specifically,
...
...
@@ -33,6 +34,10 @@
</intent-filter>
</activity>
<activity
android:name=
".FlutterPageActivity"
android:theme=
"@style/Theme.AppCompat"
...
...
@@ -40,6 +45,15 @@
android:hardwareAccelerated=
"true"
android:windowSoftInputMode=
"adjustResize"
/>
<activity
android:name=
"com.idlefish.flutterboost.containers.NewBoostFlutterActivity"
android:theme=
"@style/Theme.AppCompat"
android:configChanges=
"orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated=
"true"
android:windowSoftInputMode=
"adjustResize"
>
<!--<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/avd_hide_password"/>-->
</activity>
<activity
android:name=
".FlutterFragmentPageActivity"
android:theme=
"@style/Theme.AppCompat"
...
...
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/FlutterFragment.java
View file @
d9ac3683
...
...
@@ -4,6 +4,7 @@ import android.os.Bundle;
import
android.support.annotation.Nullable
;
import
com.idlefish.flutterboost.containers.BoostFlutterFragment
;
import
com.idlefish.flutterboost.containers.FlutterSplashView
;
import
java.util.HashMap
;
import
java.util.Map
;
...
...
@@ -25,6 +26,11 @@ public class FlutterFragment extends BoostFlutterFragment {
super
.
setArguments
(
args
);
}
@Override
public
FlutterSplashView
getBoostFlutterView
()
{
return
null
;
}
@Override
public
String
getContainerUrl
()
{
return
"flutterFragment"
;
...
...
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/FlutterPageActivity.java
View file @
d9ac3683
package
com.taobao.idlefish.flutterboostexample
;
import
com.idlefish.flutterboost.containers.BoostFlutterActivity
;
import
com.idlefish.flutterboost.containers.FlutterSplashView
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
FlutterPageActivity
extends
BoostFlutterActivity
{
@Override
public
FlutterSplashView
getBoostFlutterView
()
{
return
null
;
}
/**
* 该方法返回当前Activity在Flutter层对应的name,
* 混合栈将会在flutter层根据这个名字,在注册的Route表中查找对应的Widget
...
...
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/MyApplication.java
View file @
d9ac3683
...
...
@@ -3,66 +3,74 @@ package com.taobao.idlefish.flutterboostexample;
import
android.app.Application
;
import
android.content.Context
;
import
com.idlefish.flutterboost.BoostChannel
;
import
com.idlefish.flutterboost.BoostEngineProvider
;
import
com.idlefish.flutterboost.BoostFlutterEngine
;
import
com.idlefish.flutterboost.FlutterBoost
;
import
com.idlefish.flutterboost.Platform
;
import
com.idlefish.flutterboost.*
;
import
com.idlefish.flutterboost.interfaces.IContainerRecord
;
import
com.idlefish.flutterboost.interfaces.IFlutterEngineProvider
;
import
java.util.Map
;
import
com.idlefish.flutterboost.interfaces.INativeRouter
;
import
io.flutter.app.FlutterApplication
;
import
io.flutter.embedding.engine.dart.DartExecutor
;
import
io.flutter.view.FlutterMain
;
public
class
MyApplication
extends
FlutterApplication
{
@Override
public
void
onCreate
()
{
super
.
onCreate
();
//
// FlutterBoost.init(new Platform() {
//
// @Override
// public Application getApplication() {
// return MyApplication.this;
// }
//
// @Override
// public boolean isDebug() {
// return true;
// }
//
// @Override
// public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
// PageRouter.openPageByUrl(context, url, urlParams, requestCode);
// }
//
// @Override
// public IFlutterEngineProvider engineProvider() {
// return new BoostEngineProvider() {
// @Override
// public BoostFlutterEngine createEngine(Context context) {
// return new BoostFlutterEngine(context);
// }
// };
// }
//
// @Override
// public int whenEngineStart() {
// return ANY_ACTIVITY_CREATED;
// }
// });
FlutterBoost
.
init
(
new
Platform
()
{
// FlutterBoostPlugin.addActionAfterRegistered(new FlutterBoostPlugin.ActionAfterRegistered() {
// @Override
// public void onChannelRegistered(FlutterBoostPlugin channel) {
// //platform view register should use FlutterPluginRegistry instread of BoostPluginRegistry
// TextPlatformViewPlugin.register(FlutterBoost.singleton().engineProvider().tryGetEngine().getPluginRegistry());
// }
// });
@Override
public
Application
getApplication
()
{
return
MyApplication
.
this
;
}
@Override
public
boolean
isDebug
()
{
return
true
;
}
INativeRouter
router
=
new
INativeRouter
()
{
@Override
public
void
openContainer
(
Context
context
,
String
url
,
Map
<
String
,
Object
>
urlParams
,
int
requestCode
,
Map
<
String
,
Object
>
exts
)
{
PageRouter
.
openPageByUrl
(
context
,
url
,
urlParams
,
requestCode
);
}
@Override
public
IFlutterEngineProvider
engineProvider
()
{
return
new
BoostEngineProvider
()
{
@Override
public
BoostFlutterEngine
createEngine
(
Context
context
)
{
return
new
BoostFlutterEngine
(
context
,
new
DartExecutor
.
DartEntrypoint
(
context
.
getResources
().
getAssets
(),
FlutterMain
.
findAppBundlePath
(
context
),
"main"
),
"/"
);
}
};
PageRouter
.
openPageByUrl
(
context
,
url
,
urlParams
);
}
@Override
public
int
whenEngineStart
()
{
return
ANY_ACTIVITY_CREATED
;
}
});
public
void
closeContainer
(
IContainerRecord
record
,
Map
<
String
,
Object
>
result
,
Map
<
String
,
Object
>
exts
)
{
BoostChannel
.
addActionAfterRegistered
(
new
BoostChannel
.
ActionAfterRegistered
()
{
@Override
public
void
onChannelRegistered
(
BoostChannel
channel
)
{
//platform view register should use FlutterPluginRegistry instread of BoostPluginRegistry
TextPlatformViewPlugin
.
register
(
FlutterBoost
.
singleton
().
engineProvider
().
tryGetEngine
().
getPluginRegistry
());
}
});
};
Platform
platform
=
new
NewFlutterBoost
.
ConfigBuilder
(
this
,
router
).
build
();
NewFlutterBoost
.
instance
().
init
(
platform
);
}
}
example/android/app/src/main/java/com/taobao/idlefish/flutterboostexample/PageRouter.java
View file @
d9ac3683
...
...
@@ -3,6 +3,7 @@ package com.taobao.idlefish.flutterboostexample;
import
android.content.Context
;
import
android.content.Intent
;
import
android.text.TextUtils
;
import
com.idlefish.flutterboost.containers.NewBoostFlutterActivity
;
import
java.util.Map
;
...
...
@@ -19,10 +20,11 @@ public class PageRouter {
public
static
boolean
openPageByUrl
(
Context
context
,
String
url
,
Map
params
,
int
requestCode
)
{
try
{
if
(
url
.
startsWith
(
FLUTTER_PAGE_URL
))
{
context
.
startActivity
(
new
Intent
(
context
,
FlutterPageActivity
.
class
));
context
.
startActivity
(
NewBoostFlutterActivity
.
createDefaultIntent
(
context
));
return
true
;
}
else
if
(
url
.
startsWith
(
FLUTTER_FRAGMENT_PAGE_URL
))
{
context
.
startActivity
(
new
Intent
(
context
,
FlutterFragmentPageActivity
.
class
));
//
context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
return
true
;
}
else
if
(
url
.
startsWith
(
NATIVE_PAGE_URL
))
{
context
.
startActivity
(
new
Intent
(
context
,
NativePageActivity
.
class
));
...
...
example/ios/Runner/GeneratedPluginRegistrant.m
View file @
d9ac3683
...
...
@@ -3,12 +3,12 @@
//
#import "GeneratedPluginRegistrant.h"
#import <flutter_boost/
BoostChannel
.h>
#import <flutter_boost/
FlutterBoostPlugin
.h>
@implementation
GeneratedPluginRegistrant
+
(
void
)
registerWithRegistry
:(
NSObject
<
FlutterPluginRegistry
>*
)
registry
{
[
BoostChannel
registerWithRegistrar
:[
registry
registrarForPlugin
:
@"BoostChannel
"
]];
[
FlutterBoostPlugin
registerWithRegistrar
:[
registry
registrarForPlugin
:
@"FlutterBoostPlugin
"
]];
}
@end
example/lib/main.dart
View file @
d9ac3683
...
...
@@ -36,7 +36,7 @@ class _MyAppState extends State<MyApp> {
return
MaterialApp
(
title:
'Flutter Boost example'
,
builder:
FlutterBoost
.
init
(
postPush:
_onRoutePushed
),
home:
Container
());
home:
FlutterRouteWidget
());
}
void
_onRoutePushed
(
...
...
pubspec.yaml
View file @
d9ac3683
...
...
@@ -19,7 +19,7 @@ dependencies:
flutter
:
plugin
:
androidPackage
:
com.idlefish.flutterboost
pluginClass
:
BoostChannel
pluginClass
:
FlutterBoostPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment