I am trying to make my App, which works perfectly on API<23 devices, to work on an API 23 device.
It crash in the following senario.
The user changes settings via options menu
. If they tap slowly on the menu option (so there is time to see the option being highlighted), everything is fine, but if they tap briefly, the App crashes.
I know it's a quit strange behaviour and I have spend some time trying to understand what fires the error. The error occurs after recreate() which is in onOptionItemSelected
. I put a timeout before recreate() to test if the option is "validated" but that didn't work.
I can only think of some kind of bug in API 23 because it worked before with other APIs.
Here is a snippet of my code (cut down to a minimum):
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_1:
//... some code goes here
recreate();
return true;
// some other options ..
}
return super.onOptionsItemSelected(item);
}
After creating a new project with a blank activity and just adding inside onOptionsItemSelected()
if (id == R.id.action_settings) {
recreate();
return true;
}
the app still crashes.
Here is the logcat:
10-20 23:12:10.062 3217-3245/? E/Surface: getSlotFromBufferLocked: unknown buffer: 0xab3d1b80 10-20 23:12:11.050 3217-3245/? E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb4013030 10-20 23:12:11.075 3217-3245/? E/Surface: queueBuffer: error queuing buffer to SurfaceTexture, -19 10-20 23:12:11.075 3217-3245/? E/EGL_emulation: tid 3245: swapBuffers(324): error 0x3003 (EGL_BAD_ALLOC) 10-20 23:12:11.075 3217-3245/? A/OpenGLRenderer: Encountered EGL error 12291 EGL_BAD_ALLOC during rendering 10-20 23:12:11.075 3217-3245/? A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 3245 (RenderThread)
This was indeed a bug. After I reported, it has been since fixed by Google. It can be followed here: https://code.google.com/p/android/issues/detail?id=195966
Meantime my workaround is to replace recreate()
by:
Intent intent = getIntent();
finish();
startActivity(intent);
But the reload is not as smooth as with recreate() (I can see a little flashing).