Мы используем SDL-2.0.8 для пользовательского интерфейса в нашем приложении на Android.Приложение представляет собой довольно сложную сущность, и проблема, с которой мы сталкиваемся, заключается в том, что пользовательский интерфейс будет зависать всякий раз, когда приложение теряет фокус и возобновляется.Пользовательский интерфейс зависает в любом из следующих сценариев.
- Если перетащить раскрывающийся список настроек (просто потяните экран настроек сверху).
- Когда кнопка «Домой»нажата и приложение возобновляется.
- Если приложение переключается между другим приложением.
Когда приложение возвращается в предыдущее состояние, пользовательский интерфейс просто зависает и перестает отвечать на запросы.но другие потоки в приложении будут выполняться.Единственный выход - убить приложение.Так как мы портировали приложение, которое использовало SDL-1.2, мы сохраняем Window & Surface и не мигрировали в Renderer.
Мы создали новое действие, которое расширяет SDLActivity и, чтобы попробовать, я также переопределил onResume() метод в моей расширенной деятельности.Удивительно, но точка останова в onResume () достигается только при запуске приложения, а не при его возобновлении.
Я прошел по ссылкам ниже и попробовал то, что они предложили, но безуспешно.
Программа SDL зависает
SDL: окно зависает
В приведенном ниже фрагменте кода я отметил различные испытания, которые я выполнил, пытаясьчтобы исправить проблему.Я прокомментировал их как // 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();
}
Так как я 'm также регистрирует журналы SDL, ниже приведены ошибки в файле журнала SDL.
* SDL2: [Msg: поверхность окна недопустима, пожалуйста, вызовите SDL_GetWindowSurface (), чтобы получить новую поверхность], [Пользователь: ПользовательInfo], [Prio: 2], [Cat: 1]
SDL2: [Msg: поверхность окна недействительна, пожалуйста, вызовите SDL_GetWindowSurface (), чтобы получить новую поверхность], [Пользователь: Информация о пользователе], [Prio: 2], [Cat: 1]
SDL2: [Msg: недопустимая поверхность окна, пожалуйста, вызовите SDL_GetWindowSurface (), чтобы получить новую поверхность], [Пользователь: Информация о пользователе], [Prio: 2], [Cat: 1] *
Заранее спасибо за любую помощь:)