我们在Android上的应用程序中将SDL-2.0.8用于UI。该应用程序完全是一个复杂的实体,我们面临的问题是,只要应用程序失去焦点并恢复,UI就会冻结。用户界面在以下两种情况下均会冻结。
当应用程序恢复到以前的状态时,UI只会冻结并且变得无响应,但是应用程序中的其他线程将在执行。唯一的出路是杀死应用程序。 由于我们移植了使用SDL-1.2的应用程序,因此我们保留了Window&Surface,并且尚未迁移到Renderer。
我们创建了一个新的活动,该活动扩展了SDLActivity,并尝试进行扩展,我还重写了onResume()方法。令人惊讶的是,仅在应用程序启动时才在onResume()处找到断点,而在恢复应用程序时则没有。
我浏览了以下链接并尝试了他们的建议,但没有成功。
在下面的代码段中,我标记了为解决该问题而执行的其他试验。我已将它们评论为// Try-1 // Try-2等。
我还尝试创建一个单独的线程来处理事件,如下面的代码所示。 还尝试在主线程中捕获事件(对事件进行轮询)并尝试在辅助线程中呈现,但是在这种情况下,屏幕只是空白。
由于我们的应用程序很复杂并且广泛使用SDL,因此我共享一个小的代码段,这会造成同样的问题。这是一个很小的应用程序,它仅一个接一个地显示一些彩色图像,并且图像之间会休眠。
//Passing window to new thread doesn't work.
static void _pthread_start( int t ) //SDL_Window *window )
{
//Try-1
while(TRUE)
{
SDL_PumpEvents();
}
//Try-2
/* SDL_Event event;
while (1)
{
SDL_PollEvent(&event);
usleep(10);
switch (event.type)
{
//Event handling here...
}
}*/
//Try-3
// Screen will just be blank, if tried to use window here.
/* SDL_Surface *Bitmap, *B2, *B3, *B4;
B4 = IMG_Load("Green.bmp");
SDL_BlitSurface(B4, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(5);
Bitmap = IMG_Load( "Red.bmp" );
SDL_BlitSurface(Bitmap, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(5);
B2 = IMG_Load( "Blue.bmp" );
SDL_BlitSurface(B2, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(5);
B3 = IMG_Load( "Green.bmp" );
SDL_BlitSurface(B3, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(5);*/
}
int main(int argc, char* argv[]) {
SDL_Event event;
SDL_Rect rect;
SDL_Renderer *renderer;
int pressed, nReturnCode;
int t = 0;
int iRC = 0;
pthread_t tThread; // thread descriptor
pthread_attr_t tAttr; // thread attributes
/////////////////////////////////////////////////////////////////////////////////////////////////////
nReturnCode = SDL_Init( SDL_INIT_VIDEO );
SDL_LogSetOutputFunction(&sdlLog, (void*)"User Info");
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
SDL_Rect gScreenRect = { 0, 0, 0, 0 };
SDL_DisplayMode displayMode;
if( SDL_GetCurrentDisplayMode( 0, &displayMode ) == 0 )
{
gScreenRect.w = displayMode.w;
gScreenRect.h = displayMode.h;
}
window = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 480, 692, SDL_WINDOW_FULLSCREEN);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
surface = SDL_GetWindowSurface(window);
pthread_attr_init( &tAttr );
pthread_attr_setdetachstate( &tAttr, PTHREAD_CREATE_DETACHED );
iRC = pthread_create( &tThread, // thread id
&tAttr, // thread attributes
( void *( * )( void * ) ) _pthread_start, // thread function
( void * ) &t ); // arguments
boolean quit = FALSE;
while (!quit) {
//Try-4
/* SDL_Event event;
while (SDL_PollEvent(&event)) {
*//* handle your event here *//*
//User requests quit
if( event.type == SDL_QUIT )
quit = TRUE;
}*/
/* do some other stuff here -- draw your app, etc. */
SDL_Surface *Bitmap, *B2, *B3, *B4;
B4 = IMG_Load("Green.bmp");
SDL_BlitSurface(B4, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(2);
Bitmap = IMG_Load( "Red.bmp" );
SDL_BlitSurface(Bitmap, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(2);
B2 = IMG_Load( "Blue.bmp" );
SDL_BlitSurface(B2, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(2);
B3 = IMG_Load( "Green.bmp" );
SDL_BlitSurface(B3, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
sleep(2);
}
//Try-5
/* while (1)
{
SDL_PollEvent(&event);
usleep(10);
switch (event.type)
{
//Event handling here...
}
}*/
/////////////////////////////////////////////////////////////////////////////////////////////////////
//SDL_DestroyRenderer(renderer);
SDL_UpdateWindowSurface(window);
//SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
下面是MainActivity.java类文件。
package com.test.sdltest;
import android.content.res.AssetManager;
import android.os.Bundle;
import org.libsdl.app.SDLActivity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MainActivity extends SDLActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
stringFromJNI();
}
@Override
protected void onResume() {
super.onResume();
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
由于我也在记录SDL日志,因此以下是SDL日志文件中的错误。
* SDL2:[消息:窗口表面无效,请调用SDL_GetWindowSurface()以获取新表面],[用户:用户信息],[优先级:2],[猫:1]
SDL2:[消息:窗口表面无效,请调用SDL_GetWindowSurface()以获取新表面],[用户:用户信息],[优先级:2],[猫:1]
SDL2:[消息:窗口表面无效,请调用SDL_GetWindowSurface()以获取新表面],[用户:用户信息],[优先级:2],[猫:1] *
在此先感谢您的帮助:)
答案 0 :(得分:0)
对于那些偶然发现此帖子的人来说只是一个更新。 经过数周的努力,我们才发现必须使用Renderer而不是Surface来解决UI Freeze问题。失去焦点并使用Renderer进行恢复后,上面的示例程序将不会冻结。