我有一个片段带有一个GlSurfaceView
和一个按钮,可以导航到第二个片段。第二个片段也有一个GlSurfaceView
和一个按钮,可以让你导航回第一个片段。
两个GlSurfaceView
都使用相同类型的渲染器。这是一个简单的渲染器,只是改变背景颜色。
我的问题是,如果我在第二个片段上切换到另一个应用程序,然后切换回来,整个UI将冻结。这不会发生在第一个片段上,尽管它与第二个片段几乎相同。
为什么会发生这种情况,我能做些什么呢?我猜这是Android中的一个bug。这个bug只发生在Android 13(SDK 33)中,它在Android 12和14中工作正常。
我的渲染器在每一帧上清除帧500000次。如果我只清除一次帧,错误就不会发生。此外,如果我导航到第二帧而没有动画,它似乎也工作得很好。
这里有一个完整的示例项目:https://github.com/pekspro/GLSurfaceViewFreezeSample
这是渲染器的代码:
public final class OpenGLRenderer implements Renderer
{
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
}
float color = 0.2f;
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
color += 0.01f;
if (color > 0.7) {
color = 0.02f;
}
for(int i = 0; i < 500000; i++) {
gl.glClearColor(color * 0.8f, 0.0f, color, 1.0f);
}
}
}
字符串
这是第一个片段的代码:
public class FirstFragment extends Fragment {
private FragmentFirstBinding binding;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentFirstBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.OpenGlGameGraphics.setRenderer(new OpenGLRenderer());
binding.buttonFirstWithAnimation.setOnClickListener(view1 -> {
FragmentManager manager = getParentFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft. Replace(R.id.FragmentMain, new SecondFragment());
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft. Commit();
});
binding.buttonFirstNoAnimation.setOnClickListener(view1 -> {
FragmentManager manager = getParentFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft. Replace(R.id.FragmentMain, new SecondFragment());
ft.addToBackStack(null);
ft. Commit();
});
}
@Override
public void onResume()
{
super.onResume();
binding.OpenGlGameGraphics.onResume();
}
@Override
public void onPause()
{
super.onPause();
binding.OpenGlGameGraphics.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
型
这是第二个片段的代码:
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecondBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.OpenGlGameGraphics.setRenderer(new OpenGLRenderer());
binding.buttonSecond.setOnClickListener(view1 -> {
FragmentManager manager = getParentFragmentManager();
manager.popBackStack();
});
}
@Override
public void onResume()
{
super.onResume();
binding.OpenGlGameGraphics.onResume();
}
@Override
public void onPause()
{
super.onPause();
binding.OpenGlGameGraphics.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
型
1条答案
按热度按时间wpcxdonn1#
有一件事似乎是有效的,那就是在暂停时删除
GlSurfaceView
,然后延迟一段时间,在恢复时添加它。首先,将GlSurfaceView
放入容器中:字符串
然后像这样更新逻辑:
型
我不明白为什么要这么做。但似乎很有效。
更多的人遇到了这个问题:
https://issuetracker.google.com/issues/269158607https://issuetracker.google.com/issues/263307511的数据库