addView/setContentview后的Android O设备空白屏幕



我最近决定更新我的旧应用程序,并使它们更新一点。在这样做的过程中,我注意到在我的新手机上运行它们时出现了一个奇怪的问题(安卓O/neneneba API 29级(。

我的应用程序本质上是一个使用OpenGL的单一活动。这基本上就是第一次加载应用程序时发生的情况。。。

  • 创建布局,创建初始屏幕视图,创建自定义GLSurfaceView
  • 将GLSurfaceView添加到布局
  • 将初始屏幕添加到布局
  • 启动AsyncTask以加载资源并执行安装操作
  • GLSurfaceView取消启动屏幕以显示渲染器

所以,它在我的旧设备上运行得很好(3部手机,1部平板电脑,都运行不高于棒棒糖的各种版本的Android(。

然而,在我的Android 10手机上,当应用程序启动时,我得到的只是一个空白屏幕。需要明确的是,没有任何错误,应用程序本身运行得非常好。在通常的启动时间之后,空白屏幕被消除,应用程序继续运行,只是"splashscreen"现在变成了一个";blankscreen";。

但Android Studio布局检查器告诉了一个不同的故事

事实上,如果我在Android Studio中打开布局检查器,奇怪的是,它显示的正是我所期望的。。。带有文本/图形的防溅屏,但不在实际设备上。。。

一些测试代码

在下面的测试代码中,我用一个简单的Thread.sleep替换了资源加载/设置,只是为了创建更长的延迟,这样我就可以更容易地在AndroidStudio中检查输出。这个确实仍然存在问题。。。

@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技术,比如使用专用的"活动"。然而,由于应用程序的设置/复杂性,并且它本身不会"破坏"它们,我不想重构整个代码库(无论如何(,任何新的应用程序都会使用不同的系统来进行引人注目的屏幕。我在这里真正想明白的是,为什么现在它不像以前那样工作了。这是一个bug吗?或者是安卓版本中发生的行为变化?或者可能只是我做错了什么。如果有人遇到过它,我真的很想知道一个解决方案。

**我试过的其他东西**

在上面的例子中,如果我只是不添加"myGLView",那么会显示splashscreen,但当然应用程序也不会工作。所以我想把它添加到onPostExecute中,然后用splash.bringToFront((把splashscreen视图放回前面。防溅屏只显示很短的一秒钟,在正确显示的设备上,会出现"故障",因为正确显示的防溅屏覆盖了GL渲染器,然后又被买回了前面。

您正在向当前未在"活动"中设置的对象添加视图。

更好的方法是先调用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();

最新更新