addView / setContentview后Android O设备黑屏
Posted
技术标签:
【中文标题】addView / setContentview后Android O设备黑屏【英文标题】:Android O device blank screen after addView / setContentview 【发布时间】:2021-06-16 02:59:00 【问题描述】:我最近决定更新我的旧应用,让它们更新一点。这样做时,我注意到在我的新手机(android O / API 级别 29)上运行它们时出现了一个奇怪的问题。
我的应用本质上是一个使用 OpenGL 的 Activity。这基本上是应用程序首次加载时发生的情况......
创建布局,创建启动画面视图,创建自定义 GLSurfaceView 将 GLSurfaceView 添加到布局中 在布局中添加启动画面 启动 AsyncTask 以加载资源并进行设置操作 GLSurfaceView 关闭 Splashscreen 以显示渲染器...所以,它在我的旧设备上运行良好(3 台手机、1 台平板电脑都运行不高于 Lollipop 的各种 Android 版本)。
但是,在我的 Android 10 手机上,我得到的只是应用程序启动时的空白屏幕。需要明确的是,没有错误,应用程序本身运行良好。在通常的启动时间之后,空白屏幕被关闭,应用程序继续运行,只是“启动画面”现在变成了“空白屏幕”。
但 Android Studio Layout Inspector 讲述的是不同的故事
确实,如果我在 Android Studio 中打开 Layout Inspector,奇怪的是它显示的正是我所期望的……带有文本/图形的启动画面,但不是在实际设备上……
一些测试代码
在下面的测试代码中,我用一个简单的 Thread.sleep 替换了资源加载/设置,只是为了创建更长的延迟,以便我可以更轻松地检查 Android Studio 中的输出。这确实仍然存在问题...
@Override
protected void onCreate(Bundle savedInstanceState)
int[] deviceResolution = getDeviceResolution();
width = deviceResolution[0];
height = deviceResolution[1];
layout = new RelativeLayout(this);
splash = new Splash(getApplication(), width, height);
myGLView = new CustomGLSurfaceView(this.getApplication());
layout.addView(myGLView);
layout.addView(splash);
setContentView(layout);
loadResource = new LoadResources(newBundle);
loadResources.execute();
super.onCreate(savedInstanceState);
class LoadResources AsyncTask<Void, Void, Void>
Bundle savedBundle;
LoadResources(Bundle savedBundle)
this.savedBundle=savedBundle;
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected Void doInBackground(Void... params)
// Simulate some long-running task here. While this is happening, splashscreen should be visible. And on older devices, it is. Not on Android O handset (but OK in Android Studio Layout Inspector).
try
Thread.sleep(30000);
catch (InterruptedException e)
e.printStackTrace();
// Would typically make my calls here to load resources, and complete other setup tasks here
return null;
@Override
protected void onPostExecute(Void result)
super.onPostExecute(result);
** 其他观察 **
我知道 Async 现在已弃用,并且我还知道其他 Splashscreen 技术,例如使用专用 Activity。然而,由于应用程序的设置/复杂性,并且考虑到它本身并没有“破坏”它们,我不想重构整个代码库(无论如何),任何未来的新应用程序都将使用启动画面的不同系统。我在这里真正想了解的是为什么现在不能像以前那样工作了。这是一个错误吗?还是在某个 Android 版本中发生的行为变化?或者也许只是我做错了什么。如果有人遇到过它,我真的很想知道修复/解决方法。
** 我尝试过的其他方法 **
在上面的示例中,如果我只是不添加“myGLView”,则会显示启动画面,但当然应用程序将无法运行。所以我想将它添加到 onPostExecute 中,然后使用 splash.bringToFront() 将启动画面视图带回前面。这种工作,但很混乱。闪屏只显示一秒钟,在正确显示的设备上会出现“故障”,因为正确显示的闪屏被 GL 渲染器覆盖,然后又被买回了前面。
【问题讨论】:
【参考方案1】:您正在向当前未在 Activity 中设置的对象添加视图。
更好的方法是先调用setContentView()
和 super 方法,然后在其中添加多个视图。
所以在你的情况下,它会像:
super.onCreate(savedInstanceState);
setContentView(layout);
layout = new RelativeLayout(this);
int[] deviceResolution = getDeviceResolution();
width = deviceResolution[0];
height = deviceResolution[1];
layout = new RelativeLayout(this);
splash = new Splash(getApplication(), width, height);
myGLView = new CustomGLSurfaceView(this.getApplication());
layout.addView(myGLView);
layout.addView(splash);
loadResource = new LoadResources(newBundle);
loadResources.execute();
【讨论】:
以上是关于addView / setContentview后Android O设备黑屏的主要内容,如果未能解决你的问题,请参考以下文章
StreetViewPanoramaView下setContentView元素SurfaceView绘制后