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
5 years ago
by
yangwu.jia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Boost 1.9升级
parent
570f4acb
Changes
32
Hide 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
{
...
...
This diff is collapsed.
Click to expand it.
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!");
//
}
}
}
This diff is collapsed.
Click to expand it.
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
);
...
...
@@ -184,7 +176,7 @@ public class BoostFlutterEngine extends FlutterEngine {
}
}
public
class
BoostRegistrar
implements
PluginRegistry
.
Registrar
{
public
class
BoostRegistrar
implements
PluginRegistry
.
Registrar
{
private
final
PluginRegistry
.
Registrar
mRegistrar
;
private
final
FlutterEngine
mEngine
;
...
...
This diff is collapsed.
Click to expand it.
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."
);
}
...
...
This diff is collapsed.
Click to expand it.
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
);
}
}
}
This diff is collapsed.
Click to expand it.
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
);
}
}
...
...
This diff is collapsed.
Click to expand it.
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);
}
}
...
...
This diff is collapsed.
Click to expand it.
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
();
}
}
}
}
}
This diff is collapsed.
Click to expand it.
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
;
}
...
...
This diff is collapsed.
Click to expand it.
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
);
}
}
This diff is collapsed.
Click to expand it.
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"
);
}
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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"
);
...
...
This diff is collapsed.
Click to expand it.
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
)
{
...
...
This diff is collapsed.
Click to expand it.
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
();
}
}
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
}
}
This diff is collapsed.
Click to expand it.
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
();
}
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
);
}
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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"
...
...
@@ -53,11 +53,11 @@ android {
flutter
{
source
'../..'
}
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'
}
This diff is collapsed.
Click to expand it.
example/android/app/src/main/AndroidManifest.xml
View file @
d9ac3683
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"com.taobao.idlefish.flutterboostexample"
>
xmlns:tools=
"http://schemas.android.com/tools"
package=
"com.taobao.idlefish.flutterboostexample"
>
<!-- The INTERNET permission is required for development. Specifically,
flutter needs it to communicate with the running application
...
...
@@ -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"
...
...
This diff is collapsed.
Click to expand it.
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"
;
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
);
PageRouter
.
openPageByUrl
(
context
,
url
,
urlParams
);
}
@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"
),
"/"
);
}
};
}
public
void
closeContainer
(
IContainerRecord
record
,
Map
<
String
,
Object
>
result
,
Map
<
String
,
Object
>
exts
)
{
@Override
public
int
whenEngineStart
()
{
return
ANY_ACTIVITY_CREATED
;
}
});
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
);
}
}
This diff is collapsed.
Click to expand it.
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
));
...
...
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
(
...
...
This diff is collapsed.
Click to expand it.
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:
...
...
This diff is collapsed.
Click to expand it.
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