Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
d3fbaea9
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
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,发现更多精彩内容 >>
未验证
提交
d3fbaea9
编写于
4月 05, 2019
作者:
M
Matt Carroll
提交者:
GitHub
4月 05, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Android Embedding PR25: Prevent black rectangle when launching FlutterActivity (#8460)
上级
99da038d
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
188 addition
and
5 deletion
+188
-5
shell/platform/android/io/flutter/embedding/android/FlutterActivity.java
...android/io/flutter/embedding/android/FlutterActivity.java
+68
-1
shell/platform/android/io/flutter/embedding/android/FlutterFragment.java
...android/io/flutter/embedding/android/FlutterFragment.java
+28
-4
shell/platform/android/io/flutter/embedding/android/FlutterSurfaceView.java
...roid/io/flutter/embedding/android/FlutterSurfaceView.java
+28
-0
shell/platform/android/io/flutter/embedding/android/FlutterTextureView.java
...roid/io/flutter/embedding/android/FlutterTextureView.java
+28
-0
shell/platform/android/io/flutter/embedding/android/FlutterView.java
...orm/android/io/flutter/embedding/android/FlutterView.java
+17
-0
shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java
...io/flutter/embedding/engine/renderer/FlutterRenderer.java
+12
-0
shell/platform/android/io/flutter/view/FlutterNativeView.java
...l/platform/android/io/flutter/view/FlutterNativeView.java
+7
-0
未找到文件。
shell/platform/android/io/flutter/embedding/android/FlutterActivity.java
浏览文件 @
d3fbaea9
...
...
@@ -9,6 +9,8 @@ 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.Drawable
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.support.annotation.NonNull
;
...
...
@@ -16,6 +18,7 @@ import android.support.annotation.Nullable;
import
android.support.v4.app.FragmentActivity
;
import
android.support.v4.app.FragmentManager
;
import
android.util.Log
;
import
android.util.TypedValue
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.view.Window
;
...
...
@@ -24,6 +27,7 @@ import android.widget.FrameLayout;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.embedding.engine.FlutterShellArgs
;
import
io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener
;
import
io.flutter.plugin.platform.PlatformPlugin
;
import
io.flutter.view.FlutterMain
;
...
...
@@ -61,7 +65,7 @@ import io.flutter.view.FlutterMain;
* {@code Fragment}.
*/
// TODO(mattcarroll): explain each call forwarded to Fragment (first requires resolution of PluginRegistry API).
public
class
FlutterActivity
extends
FragmentActivity
{
public
class
FlutterActivity
extends
FragmentActivity
implements
OnFirstFrameRenderedListener
{
private
static
final
String
TAG
=
"FlutterActivity"
;
// Meta-data arguments, processed from manifest XML.
...
...
@@ -82,6 +86,10 @@ public class FlutterActivity extends FragmentActivity {
private
static
final
int
FRAGMENT_CONTAINER_ID
=
609893468
;
// random number
private
FlutterFragment
flutterFragment
;
// Used to cover the Activity until the 1st frame is rendered so as to
// avoid a brief black flicker from a SurfaceView version of FlutterView.
private
View
coverView
;
/**
* Creates an {@link Intent} that launches a {@code FlutterActivity}, which executes
* a {@code main()} Dart entrypoint, and displays the "/" route as Flutter's initial route.
...
...
@@ -147,10 +155,64 @@ public class FlutterActivity extends FragmentActivity {
Log
.
d
(
TAG
,
"onCreate()"
);
super
.
onCreate
(
savedInstanceState
);
setContentView
(
createFragmentContainer
());
showCoverView
();
configureStatusBarForFullscreenFlutterExperience
();
ensureFlutterFragmentCreated
();
}
/**
* Cover all visible {@code Activity} area with a {@code View} that paints everything the same
* color as the {@code Window}.
* <p>
* This cover {@code View} should be displayed at the very beginning of the {@code Activity}'s
* lifespan and then hidden once Flutter renders its first frame. The purpose of this cover is to
* cover {@link FlutterSurfaceView}, which briefly displays a black rectangle before it can make
* itself transparent.
*/
private
void
showCoverView
()
{
// Create the coverView.
if
(
coverView
==
null
)
{
coverView
=
new
View
(
this
);
addContentView
(
coverView
,
new
ViewGroup
.
LayoutParams
(
ViewGroup
.
LayoutParams
.
MATCH_PARENT
,
ViewGroup
.
LayoutParams
.
MATCH_PARENT
));
}
// Pain the coverView with the Window's background.
Drawable
background
=
createCoverViewBackground
();
if
(
background
!=
null
)
{
coverView
.
setBackground
(
background
);
}
else
{
// If we can't obtain a window background to replicate then we'd be guessing as to the least
// intrusive color. But there is no way to make an accurate guess. In this case we don't
// give the coverView any color, which means a brief black rectangle will be visible upon
// Activity launch.
}
}
@Nullable
private
Drawable
createCoverViewBackground
()
{
TypedValue
typedValue
=
new
TypedValue
();
boolean
hasBackgroundColor
=
getTheme
().
resolveAttribute
(
android
.
R
.
attr
.
windowBackground
,
typedValue
,
true
);
if
(
hasBackgroundColor
&&
typedValue
.
resourceId
!=
0
)
{
return
getResources
().
getDrawable
(
typedValue
.
resourceId
,
getTheme
());
}
else
{
return
null
;
}
}
/**
* Hides the cover {@code View}.
* <p>
* This method should be called when Flutter renders its first frame. See {@link #showCoverView()}
* for details.
*/
private
void
hideCoverView
()
{
coverView
.
setVisibility
(
View
.
GONE
);
}
private
void
configureStatusBarForFullscreenFlutterExperience
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
Window
window
=
getWindow
();
...
...
@@ -360,4 +422,9 @@ public class FlutterActivity extends FragmentActivity {
private
boolean
isDebuggable
()
{
return
(
getApplicationInfo
().
flags
&
ApplicationInfo
.
FLAG_DEBUGGABLE
)
!=
0
;
}
@Override
public
void
onFirstFrameRendered
()
{
hideCoverView
();
}
}
shell/platform/android/io/flutter/embedding/android/FlutterFragment.java
浏览文件 @
d3fbaea9
...
...
@@ -21,6 +21,7 @@ import android.view.ViewGroup;
import
io.flutter.embedding.engine.FlutterEngine
;
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
;
...
...
@@ -214,16 +215,27 @@ public class FlutterFragment extends Fragment {
@Nullable
private
PlatformPlugin
platformPlugin
;
private
final
OnFirstFrameRenderedListener
onFirstFrameRenderedListener
=
new
OnFirstFrameRenderedListener
()
{
@Override
public
void
onFirstFrameRendered
()
{
// Notify our subclasses that the first frame has been rendered.
FlutterFragment
.
this
.
onFirstFrameRendered
();
// Notify our owning Activity that the first frame has been rendered.
FragmentActivity
fragmentActivity
=
getActivity
();
if
(
fragmentActivity
!=
null
&&
fragmentActivity
instanceof
OnFirstFrameRenderedListener
)
{
OnFirstFrameRenderedListener
activityAsListener
=
(
OnFirstFrameRenderedListener
)
fragmentActivity
;
activityAsListener
.
onFirstFrameRendered
();
}
}
};
public
FlutterFragment
()
{
// Ensure that we at least have an empty Bundle of arguments so that we don't
// need to continually check for null arguments before grabbing one.
setArguments
(
new
Bundle
());
}
public
void
prepareForNavigation
()
{
flutterView
.
setAlpha
(
0.0f
);
}
/**
* The {@link FlutterEngine} that backs the Flutter content presented by this {@code Fragment}.
*
...
...
@@ -304,6 +316,7 @@ public class FlutterFragment extends Fragment {
@Override
public
View
onCreateView
(
LayoutInflater
inflater
,
@Nullable
ViewGroup
container
,
@Nullable
Bundle
savedInstanceState
)
{
flutterView
=
new
FlutterView
(
getContext
(),
getRenderMode
());
flutterView
.
addOnFirstFrameRenderedListener
(
onFirstFrameRenderedListener
);
// 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
...
...
@@ -433,6 +446,7 @@ public class FlutterFragment extends Fragment {
public
void
onDestroyView
()
{
super
.
onDestroyView
();
Log
.
d
(
TAG
,
"onDestroyView()"
);
flutterView
.
removeOnFirstFrameRenderedListener
(
onFirstFrameRenderedListener
);
flutterView
.
detachFromFlutterEngine
();
}
...
...
@@ -580,6 +594,16 @@ public class FlutterFragment extends Fragment {
:
getActivity
();
}
/**
* Invoked after the {@link FlutterView} within this {@code FlutterFragment} renders its first
* frame.
* <p>
* The owning {@code Activity} is also sent this message, if it implements
* {@link OnFirstFrameRenderedListener}. This method is invoked before the {@code Activity}'s
* version.
*/
protected
void
onFirstFrameRendered
()
{}
/**
* Provides a {@link FlutterEngine} instance to be used by a {@code FlutterFragment}.
* <p>
...
...
shell/platform/android/io/flutter/embedding/android/FlutterSurfaceView.java
浏览文件 @
d3fbaea9
...
...
@@ -12,7 +12,11 @@ import android.util.Log;
import
android.view.SurfaceHolder
;
import
android.view.SurfaceView
;
import
java.util.HashSet
;
import
java.util.Set
;
import
io.flutter.embedding.engine.renderer.FlutterRenderer
;
import
io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener
;
/**
* Paints a Flutter UI on a {@link android.view.Surface}.
...
...
@@ -36,6 +40,8 @@ public class FlutterSurfaceView extends SurfaceView implements FlutterRenderer.R
private
boolean
isAttachedToFlutterRenderer
=
false
;
@Nullable
private
FlutterRenderer
flutterRenderer
;
@NonNull
private
Set
<
OnFirstFrameRenderedListener
>
onFirstFrameRenderedListeners
=
new
HashSet
<>();
// Connects the {@code Surface} beneath this {@code SurfaceView} with Flutter's native code.
// Callbacks are received by this Object and then those messages are forwarded to our
...
...
@@ -177,11 +183,33 @@ public class FlutterSurfaceView extends SurfaceView implements FlutterRenderer.R
flutterRenderer
.
surfaceDestroyed
();
}
/**
* Adds the given {@code listener} to this {@code FlutterSurfaceView}, to be notified upon Flutter's
* first rendered frame.
*/
@Override
public
void
addOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{
onFirstFrameRenderedListeners
.
add
(
listener
);
}
/**
* Removes the given {@code listener}, which was previously added with
* {@link #addOnFirstFrameRenderedListener(OnFirstFrameRenderedListener)}.
*/
@Override
public
void
removeOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{
onFirstFrameRenderedListeners
.
remove
(
listener
);
}
@Override
public
void
onFirstFrameRendered
()
{
// TODO(mattcarroll): decide where this method should live and what it needs to do.
Log
.
d
(
TAG
,
"onFirstFrameRendered()"
);
// Now that a frame is ready to display, take this SurfaceView from transparent to opaque.
setAlpha
(
1.0f
);
for
(
OnFirstFrameRenderedListener
listener
:
onFirstFrameRenderedListeners
)
{
listener
.
onFirstFrameRendered
();
}
}
}
shell/platform/android/io/flutter/embedding/android/FlutterTextureView.java
浏览文件 @
d3fbaea9
...
...
@@ -13,7 +13,11 @@ import android.util.Log;
import
android.view.Surface
;
import
android.view.TextureView
;
import
java.util.HashSet
;
import
java.util.Set
;
import
io.flutter.embedding.engine.renderer.FlutterRenderer
;
import
io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener
;
/**
* Paints a Flutter UI on a {@link SurfaceTexture}.
...
...
@@ -37,6 +41,8 @@ public class FlutterTextureView extends TextureView implements FlutterRenderer.R
private
boolean
isAttachedToFlutterRenderer
=
false
;
@Nullable
private
FlutterRenderer
flutterRenderer
;
@NonNull
private
Set
<
OnFirstFrameRenderedListener
>
onFirstFrameRenderedListeners
=
new
HashSet
<>();
// Connects the {@code SurfaceTexture} beneath this {@code TextureView} with Flutter's native code.
// Callbacks are received by this Object and then those messages are forwarded to our
...
...
@@ -181,9 +187,31 @@ public class FlutterTextureView extends TextureView implements FlutterRenderer.R
flutterRenderer
.
surfaceDestroyed
();
}
/**
* Adds the given {@code listener} to this {@code FlutterTextureView}, to be notified upon Flutter's
* first rendered frame.
*/
@Override
public
void
addOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{
onFirstFrameRenderedListeners
.
add
(
listener
);
}
/**
* Removes the given {@code listener}, which was previously added with
* {@link #addOnFirstFrameRenderedListener(OnFirstFrameRenderedListener)}.
*/
@Override
public
void
removeOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{
onFirstFrameRenderedListeners
.
remove
(
listener
);
}
@Override
public
void
onFirstFrameRendered
()
{
// TODO(mattcarroll): decide where this method should live and what it needs to do.
Log
.
d
(
TAG
,
"onFirstFrameRendered()"
);
for
(
OnFirstFrameRenderedListener
listener
:
onFirstFrameRenderedListeners
)
{
listener
.
onFirstFrameRendered
();
}
}
}
shell/platform/android/io/flutter/embedding/android/FlutterView.java
浏览文件 @
d3fbaea9
...
...
@@ -31,6 +31,7 @@ import java.util.Locale;
import
io.flutter.embedding.engine.FlutterEngine
;
import
io.flutter.embedding.engine.renderer.FlutterRenderer
;
import
io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener
;
import
io.flutter.plugin.editing.TextInputPlugin
;
import
io.flutter.view.AccessibilityBridge
;
...
...
@@ -147,6 +148,22 @@ public class FlutterView extends FrameLayout {
}
}
/**
* Adds the given {@code listener} to this {@code FlutterView}, to be notified upon Flutter's
* first rendered frame.
*/
public
void
addOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{
renderSurface
.
addOnFirstFrameRenderedListener
(
listener
);
}
/**
* Removes the given {@code listener}, which was previously added with
* {@link #addOnFirstFrameRenderedListener(OnFirstFrameRenderedListener)}.
*/
public
void
removeOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{
renderSurface
.
removeOnFirstFrameRenderedListener
(
listener
);
}
//------- Start: Process View configuration that Flutter cares about. ------
/**
* Sends relevant configuration data from Android to Flutter when the Android
...
...
shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java
浏览文件 @
d3fbaea9
...
...
@@ -267,6 +267,18 @@ public class FlutterRenderer implements TextureRegistry {
* never be called.
*/
void
onFirstFrameRendered
();
/**
* Adds the given {@code listener} to this {@code FlutterRenderer}, to be notified upon Flutter's
* first rendered frame.
*/
void
addOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
);
/**
* Removes the given {@code listener}, which was previously added with
* {@link #addOnFirstFrameRenderedListener(OnFirstFrameRenderedListener)}.
*/
void
removeOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
);
}
/**
...
...
shell/platform/android/io/flutter/view/FlutterNativeView.java
浏览文件 @
d3fbaea9
...
...
@@ -14,6 +14,7 @@ import io.flutter.embedding.engine.FlutterEngine.EngineLifecycleListener;
import
io.flutter.embedding.engine.dart.DartExecutor
;
import
io.flutter.embedding.engine.renderer.FlutterRenderer
;
import
io.flutter.embedding.engine.renderer.FlutterRenderer.RenderSurface
;
import
io.flutter.embedding.engine.renderer.OnFirstFrameRenderedListener
;
import
io.flutter.plugin.common.*
;
import
java.nio.ByteBuffer
;
import
java.util.concurrent.atomic.AtomicBoolean
;
...
...
@@ -199,6 +200,12 @@ public class FlutterNativeView implements BinaryMessenger {
}
mFlutterView
.
onFirstFrame
();
}
@Override
public
void
addOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{}
@Override
public
void
removeOnFirstFrameRenderedListener
(
@NonNull
OnFirstFrameRenderedListener
listener
)
{}
}
private
final
class
EngineLifecycleListenerImpl
implements
EngineLifecycleListener
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录