Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
23b0e02e
E
engine
项目概览
weixin_43355755
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
23b0e02e
编写于
4月 12, 2019
作者:
M
Matt Carroll
提交者:
GitHub
4月 12, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Android Embedding PR29: Improve FlutterFragment construction API + engine config API. (#8540)
上级
e6c822db
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
136 addition
and
92 deletion
+136
-92
shell/platform/android/io/flutter/embedding/android/FlutterFragment.java
...android/io/flutter/embedding/android/FlutterFragment.java
+136
-92
未找到文件。
shell/platform/android/io/flutter/embedding/android/FlutterFragment.java
浏览文件 @
23b0e02e
...
@@ -60,24 +60,58 @@ import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
...
@@ -60,24 +60,58 @@ import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
public
class
FlutterFragment
extends
Fragment
{
public
class
FlutterFragment
extends
Fragment
{
private
static
final
String
TAG
=
"FlutterFragment"
;
private
static
final
String
TAG
=
"FlutterFragment"
;
pr
ivate
static
final
String
ARG_DART_ENTRYPOINT
=
"dart_entrypoint"
;
pr
otected
static
final
String
ARG_DART_ENTRYPOINT
=
"dart_entrypoint"
;
pr
ivate
static
final
String
ARG_INITIAL_ROUTE
=
"initial_route"
;
pr
otected
static
final
String
ARG_INITIAL_ROUTE
=
"initial_route"
;
pr
ivate
static
final
String
ARG_APP_BUNDLE_PATH
=
"app_bundle_path"
;
pr
otected
static
final
String
ARG_APP_BUNDLE_PATH
=
"app_bundle_path"
;
pr
ivate
static
final
String
ARG_FLUTTER_INITIALIZATION_ARGS
=
"initialization_args"
;
pr
otected
static
final
String
ARG_FLUTTER_INITIALIZATION_ARGS
=
"initialization_args"
;
pr
ivate
static
final
String
ARG_FLUTTERVIEW_RENDER_MODE
=
"flutterview_render_mode"
;
pr
otected
static
final
String
ARG_FLUTTERVIEW_RENDER_MODE
=
"flutterview_render_mode"
;
pr
ivate
static
final
String
ARG_FLUTTERVIEW_TRANSPARENCY_MODE
=
"flutterview_transparency_mode"
;
pr
otected
static
final
String
ARG_FLUTTERVIEW_TRANSPARENCY_MODE
=
"flutterview_transparency_mode"
;
/**
/**
* Builder that creates a new {@code FlutterFragment} with {@code arguments} that correspond
* Builder that creates a new {@code FlutterFragment} with {@code arguments} that correspond
* to the values set on this {@code Builder}.
* to the values set on this {@code Builder}.
* <p>
* <p>
* To create a {@code FlutterFragment} with default {@code arguments}, invoke {@code build()}
* To create a {@code FlutterFragment} with default {@code arguments}, invoke {@code build()}
*
immeidately
:
*
without setting any builder properties
:
* {@code
* {@code
* FlutterFragment fragment = new FlutterFragment.Builder().build();
* FlutterFragment fragment = new FlutterFragment.Builder().build();
* }
* }
* <p>
* Subclasses of {@code FlutterFragment} that do not introduce any new arguments can use this
* {@code Builder} to construct instances of the subclass without subclassing this {@code Builder}.
* {@code
* MyFlutterFragment f = new FlutterFragment.Builder(MyFlutterFragment.class)
* .someProperty(...)
* .someOtherProperty(...)
* .build<MyFlutterFragment>();
* }
* <p>
* Subclasses of {@code FlutterFragment} that introduce new arguments should subclass this
* {@code Builder} to add the new properties:
* <ol>
* <li>Ensure the {@code FlutterFragment} subclass has a no-arg constructor.</li>
* <li>Subclass this {@code Builder}.</li>
* <li>Override the new {@code Builder}'s no-arg constructor and invoke the super constructor
* to set the {@code FlutterFragment} subclass: {@code
* public MyBuilder() {
* super(MyFlutterFragment.class);
* }
* }</li>
* <li>Add appropriate property methods for the new properties.</li>
* <li>Override {@link Builder#createArgs()}, call through to the super method, then add
* the new properties as arguments in the {@link Bundle}.</li>
* </ol>
* Once a {@code Builder} subclass is defined, the {@code FlutterFragment} subclass can be
* instantiated as follows.
* {@code
* MyFlutterFragment f = new MyBuilder()
* .someExistingProperty(...)
* .someNewProperty(...)
* .build<MyFlutterFragment>();
* }
*/
*/
public
static
class
Builder
{
public
static
class
Builder
{
private
final
Class
<?
extends
FlutterFragment
>
fragmentClass
;
private
String
dartEntrypoint
=
"main"
;
private
String
dartEntrypoint
=
"main"
;
private
String
initialRoute
=
"/"
;
private
String
initialRoute
=
"/"
;
private
String
appBundlePath
=
null
;
private
String
appBundlePath
=
null
;
...
@@ -85,6 +119,22 @@ public class FlutterFragment extends Fragment {
...
@@ -85,6 +119,22 @@ public class FlutterFragment extends Fragment {
private
FlutterView
.
RenderMode
renderMode
=
FlutterView
.
RenderMode
.
surface
;
private
FlutterView
.
RenderMode
renderMode
=
FlutterView
.
RenderMode
.
surface
;
private
FlutterView
.
TransparencyMode
transparencyMode
=
FlutterView
.
TransparencyMode
.
transparent
;
private
FlutterView
.
TransparencyMode
transparencyMode
=
FlutterView
.
TransparencyMode
.
transparent
;
/**
* Constructs a {@code Builder} that is configured to construct an instance of
* {@code FlutterFragment}.
*/
public
Builder
()
{
fragmentClass
=
FlutterFragment
.
class
;
}
/**
* Constructs a {@code Builder} that is configured to construct an instance of
* {@code subclass}, which extends {@code FlutterFragment}.
*/
public
Builder
(
@NonNull
Class
<?
extends
FlutterFragment
>
subclass
)
{
fragmentClass
=
subclass
;
}
/**
/**
* The name of the initial Dart method to invoke, defaults to "main".
* The name of the initial Dart method to invoke, defaults to "main".
*/
*/
...
@@ -149,79 +199,49 @@ public class FlutterFragment extends Fragment {
...
@@ -149,79 +199,49 @@ public class FlutterFragment extends Fragment {
return
this
;
return
this
;
}
}
/**
* Creates a {@link Bundle} of arguments that are assigned to the new {@code FlutterFragment}.
* <p>
* Subclasses should override this method to add new properties to the {@link Bundle}. Subclasses
* must call through to the super method to collect all existing property values.
*/
@NonNull
@NonNull
public
FlutterFragment
build
()
{
protected
Bundle
createArgs
()
{
FlutterFragment
frag
=
new
FlutterFragment
();
Bundle
args
=
new
Bundle
();
args
.
putString
(
ARG_INITIAL_ROUTE
,
initialRoute
);
Bundle
args
=
createArgsBundle
(
args
.
putString
(
ARG_APP_BUNDLE_PATH
,
appBundlePath
);
dartEntrypoint
,
args
.
putString
(
ARG_DART_ENTRYPOINT
,
dartEntrypoint
);
initialRoute
,
// TODO(mattcarroll): determine if we should have an explicit FlutterTestFragment instead of conflating.
appBundlePath
,
if
(
null
!=
shellArgs
)
{
shellArgs
,
args
.
putStringArray
(
ARG_FLUTTER_INITIALIZATION_ARGS
,
shellArgs
.
toArray
());
renderMode
,
}
transparencyMode
args
.
putString
(
ARG_FLUTTERVIEW_RENDER_MODE
,
renderMode
!=
null
?
renderMode
.
name
()
:
FlutterView
.
RenderMode
.
surface
.
name
());
);
args
.
putString
(
ARG_FLUTTERVIEW_TRANSPARENCY_MODE
,
transparencyMode
!=
null
?
transparencyMode
.
name
()
:
FlutterView
.
TransparencyMode
.
transparent
.
name
());
frag
.
setArguments
(
args
);
return
args
;
return
frag
;
}
}
}
/**
/**
* Creates a {@link Bundle} of arguments that can be used to configure a {@link FlutterFragment}.
* Constructs a new {@code FlutterFragment} (or a subclass) that is configured based on
* This method is exposed so that developers can create subclasses of {@link FlutterFragment}.
* properties set on this {@code Builder}.
* Subclasses should declare static factories that use this method to create arguments that will
*/
* be understood by the base class, and then the subclass can add any additional arguments it
@NonNull
* wants to this {@link Bundle}. Example:
public
<
T
extends
FlutterFragment
>
T
build
()
{
* <pre>{@code
try
{
* public static MyFlutterFragment newInstance(String myNewArg) {
@SuppressWarnings
(
"unchecked"
)
* // Create an instance of your subclass Fragment.
T
frag
=
(
T
)
fragmentClass
.
newInstance
();
* MyFlutterFragment myFrag = new MyFlutterFragment();
if
(
frag
==
null
)
{
*
throw
new
RuntimeException
(
"The FlutterFragment subclass sent in the constructor ("
* // Create the Bundle or args that FlutterFragment understands.
+
fragmentClass
.
getCanonicalName
()
+
") does not match the expected return type."
);
* Bundle args = FlutterFragment.createArgsBundle(...);
}
*
* // Add your new args to the bundle.
Bundle
args
=
createArgs
();
* args.putString(ARG_MY_NEW_ARG, myNewArg);
frag
.
setArguments
(
args
);
*
* // Give the args to your subclass Fragment.
return
frag
;
* myFrag.setArguments(args);
}
catch
(
Exception
e
)
{
*
throw
new
RuntimeException
(
"Could not instantiate FlutterFragment subclass ("
+
fragmentClass
.
getName
()
+
")"
,
e
);
* // Return the newly created subclass Fragment.
}
* return myFrag;
* }
* }</pre>
*
* @param dartEntrypoint the name of the initial Dart method to invoke, defaults to "main"
* @param initialRoute the first route that a Flutter app will render in this {@link FlutterFragment}, defaults to "/"
* @param appBundlePath the path to the app bundle which contains the Dart app to execute
* @param flutterShellArgs any special configuration arguments for the Flutter engine
* @param renderMode render Flutter either as a {@link FlutterView.RenderMode#surface} or a
* {@link FlutterView.RenderMode#texture}. You should use {@code surface} unless
* you have a specific reason to use {@code texture}. {@code texture} comes with
* a significant performance impact, but {@code texture} can be displayed
* beneath other Android {@code View}s and animated, whereas {@code surface}
* cannot.
*
* @return Bundle of arguments that configure a {@link FlutterFragment}
*/
protected
static
Bundle
createArgsBundle
(
@Nullable
String
dartEntrypoint
,
@Nullable
String
initialRoute
,
@Nullable
String
appBundlePath
,
@Nullable
FlutterShellArgs
flutterShellArgs
,
@Nullable
FlutterView
.
RenderMode
renderMode
,
@Nullable
FlutterView
.
TransparencyMode
transparencyMode
)
{
Bundle
args
=
new
Bundle
();
args
.
putString
(
ARG_INITIAL_ROUTE
,
initialRoute
);
args
.
putString
(
ARG_APP_BUNDLE_PATH
,
appBundlePath
);
args
.
putString
(
ARG_DART_ENTRYPOINT
,
dartEntrypoint
);
// TODO(mattcarroll): determine if we should have an explicit FlutterTestFragment instead of conflating.
if
(
null
!=
flutterShellArgs
)
{
args
.
putStringArray
(
ARG_FLUTTER_INITIALIZATION_ARGS
,
flutterShellArgs
.
toArray
());
}
}
args
.
putString
(
ARG_FLUTTERVIEW_RENDER_MODE
,
renderMode
!=
null
?
renderMode
.
name
()
:
FlutterView
.
RenderMode
.
surface
.
name
());
args
.
putString
(
ARG_FLUTTERVIEW_TRANSPARENCY_MODE
,
transparencyMode
!=
null
?
transparencyMode
.
name
()
:
FlutterView
.
TransparencyMode
.
transparent
.
name
());
return
args
;
}
}
@Nullable
@Nullable
...
@@ -296,15 +316,24 @@ public class FlutterFragment extends Fragment {
...
@@ -296,15 +316,24 @@ public class FlutterFragment extends Fragment {
/**
/**
* Obtains a reference to a FlutterEngine to back this {@code FlutterFragment}.
* Obtains a reference to a FlutterEngine to back this {@code FlutterFragment}.
* <p>
* <p>
* First, the {@link FragmentActivity} that owns this {@code FlutterFragment} is
* First, {@code FlutterFragment} subclasses are given an opportunity to provide a
* {@link FlutterEngine} by overriding {@link #createFlutterEngine(Context)}.
* <p>
* Second, the {@link FragmentActivity} that owns this {@code FlutterFragment} is
* given the opportunity to provide a {@link FlutterEngine} as a {@link FlutterEngineProvider}.
* given the opportunity to provide a {@link FlutterEngine} as a {@link FlutterEngineProvider}.
* <p>
* <p>
* If
the owning {@link FragmentActivity} does not implement {@link FlutterEngineProvider}, or
* If
subclasses do not provide a {@link FlutterEngine}, and the owning {@link FragmentActivity}
*
chooses to return {@code null}, then a new {@link FlutterEngine} is instantiated. Subclasses
*
does not implement {@link FlutterEngineProvider} or chooses to return {@code null}, then a new
*
may override this method to provide a {@link FlutterEngine} of choice
.
*
{@link FlutterEngine} is instantiated
.
*/
*/
protected
void
setupFlutterEngine
()
{
private
void
setupFlutterEngine
()
{
// First, defer to the FragmentActivity that owns us to see if it wants to provide a
// First, defer to subclasses for a custom FlutterEngine.
flutterEngine
=
createFlutterEngine
(
getContextCompat
());
if
(
flutterEngine
!=
null
)
{
return
;
}
// Second, defer to the FragmentActivity that owns us to see if it wants to provide a
// FlutterEngine.
// FlutterEngine.
FragmentActivity
attachedActivity
=
getActivity
();
FragmentActivity
attachedActivity
=
getActivity
();
if
(
attachedActivity
instanceof
FlutterEngineProvider
)
{
if
(
attachedActivity
instanceof
FlutterEngineProvider
)
{
...
@@ -315,18 +344,33 @@ public class FlutterFragment extends Fragment {
...
@@ -315,18 +344,33 @@ public class FlutterFragment extends Fragment {
if
(
flutterEngine
!=
null
)
{
if
(
flutterEngine
!=
null
)
{
isFlutterEngineFromActivity
=
true
;
isFlutterEngineFromActivity
=
true
;
}
}
return
;
}
}
// If flutterEngine is null then either our Activity is not a FlutterEngineProvider,
// Neither our subclass, nor our owning Activity wanted to provide a custom FlutterEngine.
// or our Activity decided that it didn't want to provide a FlutterEngine. Either way,
// Create a FlutterEngine to back our FlutterView.
// we will now create a FlutterEngine for this FlutterFragment.
Log
.
d
(
TAG
,
"No subclass or our attached Activity provided a custom FlutterEngine. Creating a "
if
(
flutterEngine
==
null
)
{
+
"new FlutterEngine for this FlutterFragment."
);
// Create a FlutterEngine to back our FlutterView.
flutterEngine
=
new
FlutterEngine
(
getContext
());
Log
.
d
(
TAG
,
"Our attached Activity did not want to provide a FlutterEngine. Creating a "
isFlutterEngineFromActivity
=
false
;
+
"new FlutterEngine for this FlutterFragment."
);
}
flutterEngine
=
new
FlutterEngine
(
getContext
());
isFlutterEngineFromActivity
=
false
;
/**
}
* Hook for subclasses to return a {@link FlutterEngine} with whatever configuration
* is desired.
* <p>
* This method takes precedence for creation of a {@link FlutterEngine} over any owning
* {@code Activity} that may implement {@link FlutterEngineProvider}.
* <p>
* Consider returning a cached {@link FlutterEngine} instance from this method to avoid the
* typical warm-up time that a new {@link FlutterEngine} instance requires.
* <p>
* If null is returned then a new default {@link FlutterEngine} will be created to back this
* {@code FlutterFragment}.
*/
@Nullable
protected
FlutterEngine
createFlutterEngine
(
@NonNull
Context
context
)
{
return
null
;
}
}
@Nullable
@Nullable
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录