Android: Fix immediately crashing on 2.2

This commit is contained in:
UnknownShadow200 2021-02-24 07:50:27 +11:00
parent e537cc6c09
commit b0e1668fa8

View File

@ -53,15 +53,13 @@ import android.view.inputmethod.InputMethodManager;
// When using Android functionality, always aim to add a comment with the API level that the functionality // When using Android functionality, always aim to add a comment with the API level that the functionality
// was added in, as this will make things easier if the minimum required API level is ever changed again // was added in, as this will make things easier if the minimum required API level is ever changed again
// SurfaceHolder.Callback2 - API level 9
// implements InputQueue.Callback // implements InputQueue.Callback
public class MainActivity extends Activity implements SurfaceHolder.Callback2 { public class MainActivity extends Activity {
CCView curView;
// ====================================== // ======================================
// -------------- COMMANDS -------------- // -------------- COMMANDS --------------
// ====================================== // ======================================
// The UI thread (which receives events) is separate from the game thread (which processes events) // The main thread (which receives events) is separate from the game thread (which processes events)
// Therefore pushing/pulling events must be thread-safe, which is achieved through ConcurrentLinkedQueue // Therefore pushing/pulling events must be thread-safe, which is achieved through ConcurrentLinkedQueue
// Additionally, a cache is used (freeCmds) to avoid constantly allocating NativeCmdArgs instances // Additionally, a cache is used (freeCmds) to avoid constantly allocating NativeCmdArgs instances
class NativeCmdArgs { public int cmd, arg1, arg2, arg3, arg4; public String str; public Surface sur; } class NativeCmdArgs { public int cmd, arg1, arg2, arg3, arg4; public String str; public Surface sur; }
@ -111,12 +109,12 @@ public class MainActivity extends Activity implements SurfaceHolder.Callback2 {
} }
final static int CMD_KEY_DOWN = 0; final static int CMD_KEY_DOWN = 0;
final static int CMD_KEY_UP = 1;
final static int CMD_KEY_CHAR = 2;
final static int CMD_KEY_TEXT = 19;
final static int CMD_POINTER_DOWN = 3; final static int CMD_POINTER_DOWN = 3;
final static int CMD_POINTER_UP = 4; final static int CMD_POINTER_UP = 4;
final static int CMD_KEY_UP = 1;
final static int CMD_KEY_CHAR = 2;
final static int CMD_KEY_TEXT = 19;
final static int CMD_POINTER_MOVE = 5; final static int CMD_POINTER_MOVE = 5;
final static int CMD_WIN_CREATED = 6; final static int CMD_WIN_CREATED = 6;
@ -155,11 +153,23 @@ public class MainActivity extends Activity implements SurfaceHolder.Callback2 {
runGameAsync(); runGameAsync();
} }
void HACK_avoidFileUriExposedErrors() {
// StrictMode - API level 9
// disableDeathOnFileUriExposure - API level 24 ?????
try {
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
} catch (NoClassDefFoundError ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
// requestWindowFeature - API level 1 // requestWindowFeature - API level 1
// setSoftInputMode, SOFT_INPUT_STATE_UNSPECIFIED, SOFT_INPUT_ADJUST_RESIZE - API level 3 // setSoftInputMode, SOFT_INPUT_STATE_UNSPECIFIED, SOFT_INPUT_ADJUST_RESIZE - API level 3
// disableDeathOnFileUriExposure - API level 24 ?????
input = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); input = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
Log.i("CC_WIN", "CREATE EVENT"); Log.i("CC_WIN", "CREATE EVENT");
Window window = getWindow(); Window window = getWindow();
@ -172,13 +182,8 @@ public class MainActivity extends Activity implements SurfaceHolder.Callback2 {
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
// TODO: semaphore for destroyed and surfaceDestroyed // TODO: semaphore for destroyed and surfaceDestroyed
// avoid FileUriExposed exceptions when taking screenshots // avoid FileUriExposed exception when taking screenshots on recent Android versions
try { HACK_avoidFileUriExposedErrors();
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
} catch (Exception ex) {
ex.printStackTrace();
}
if (!gameRunning) startGameAsync(); if (!gameRunning) startGameAsync();
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -372,54 +377,71 @@ public class MainActivity extends Activity implements SurfaceHolder.Callback2 {
// --------------- VIEWS ---------------- // --------------- VIEWS ----------------
// ====================================== // ======================================
volatile boolean fullscreen; volatile boolean fullscreen;
public void surfaceCreated(SurfaceHolder holder) {
// getSurface - API level 1
Log.i("CC_WIN", "win created " + holder.getSurface());
pushCmd(CMD_WIN_CREATED, holder.getSurface());
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// getSurface - API level 1
Log.i("CC_WIN", "win changed " + holder.getSurface());
pushCmd(CMD_WIN_RESIZED, holder.getSurface());
}
final Semaphore winDestroyedSem = new Semaphore(0, true); final Semaphore winDestroyedSem = new Semaphore(0, true);
public void surfaceDestroyed(SurfaceHolder holder) { SurfaceHolder.Callback callback;
// getSurface, removeCallback - API level 1 CCView curView;
Log.i("CC_WIN", "win destroyed " + holder.getSurface());
Log.i("CC_WIN", "cur view " + curView); // SurfaceHolder.Callback - API level 1
holder.removeCallback(this); class CCSurfaceCallback implements SurfaceHolder.Callback {
public void surfaceCreated(SurfaceHolder holder) {
// getSurface - API level 1
Log.i("CC_WIN", "win created " + holder.getSurface());
MainActivity.this.pushCmd(CMD_WIN_CREATED, holder.getSurface());
}
//08-02 21:03:02.967: E/BufferQueueProducer(1350): [SurfaceView - com.classicube.ClassiCube/com.classicube.MainActivity#0] disconnect: not connected (req=2) public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//08-02 21:03:02.968: E/SurfaceFlinger(1350): Failed to find layer (SurfaceView - com.classicube.ClassiCube/com.classicube.MainActivity#0) in layer parent (no-parent). // getSurface - API level 1
Log.i("CC_WIN", "win changed " + holder.getSurface());
pushCmd(CMD_WIN_DESTROYED); MainActivity.this.pushCmd(CMD_WIN_RESIZED, holder.getSurface());
// per the android docs for SurfaceHolder.Callback }
// "If you have a rendering thread that directly accesses the surface, you must ensure
// that thread is no longer touching the Surface before returning from this function." public void surfaceDestroyed(SurfaceHolder holder) {
try { // getSurface, removeCallback - API level 1
winDestroyedSem.acquire(); Log.i("CC_WIN", "win destroyed " + holder.getSurface());
} catch (InterruptedException e) { } Log.i("CC_WIN", "cur view " + curView);
holder.removeCallback(this);
//08-02 21:03:02.967: E/BufferQueueProducer(1350): [SurfaceView - com.classicube.ClassiCube/com.classicube.MainActivity#0] disconnect: not connected (req=2)
//08-02 21:03:02.968: E/SurfaceFlinger(1350): Failed to find layer (SurfaceView - com.classicube.ClassiCube/com.classicube.MainActivity#0) in layer parent (no-parent).
MainActivity.this.pushCmd(CMD_WIN_DESTROYED);
// per the android docs for SurfaceHolder.Callback
// "If you have a rendering thread that directly accesses the surface, you must ensure
// that thread is no longer touching the Surface before returning from this function."
try {
winDestroyedSem.acquire();
} catch (InterruptedException e) { }
}
} }
// Game calls this on its thread to notify the main thread // SurfaceHolder.Callback2 - API level 9
class CCSurfaceCallback2 extends CCSurfaceCallback implements SurfaceHolder.Callback2 {
public void surfaceRedrawNeeded(SurfaceHolder holder) {
// getSurface - API level 1
Log.i("CC_WIN", "win dirty " + holder.getSurface());
MainActivity.this.pushCmd(CMD_WIN_REDRAW);
}
}
// Called by the game thread to notify the main thread
// that it is safe to destroy the window surface now // that it is safe to destroy the window surface now
public void processedSurfaceDestroyed() { public void processedSurfaceDestroyed() { winDestroyedSem.release(); }
winDestroyedSem.release();
}
public void surfaceRedrawNeeded(SurfaceHolder holder) { void createSurfaceCallback() {
// getSurface - API level 1 if (callback != null) return;
Log.i("CC_WIN", "win dirty " + holder.getSurface()); try {
pushCmd(CMD_WIN_REDRAW); callback = new CCSurfaceCallback2();
} catch (NoClassDefFoundError ex) {
ex.printStackTrace();
callback = new CCSurfaceCallback();
}
} }
void attachSurface() { void attachSurface() {
// setContentView, requestFocus, getHolder, addCallback, RGBX_8888 - API level 1 // setContentView, requestFocus, getHolder, addCallback, RGBX_8888 - API level 1
createSurfaceCallback();
curView = new CCView(this); curView = new CCView(this);
curView.getHolder().addCallback(this); curView.getHolder().addCallback(callback);
curView.getHolder().setFormat(PixelFormat.RGBX_8888); curView.getHolder().setFormat(PixelFormat.RGBX_8888);
setContentView(curView); setContentView(curView);