I'm writing an android game with OpenGL. Having dabbled a little bit with stuff before some time ago, I started tackling the problem of handling activity pausing/resuming and loss of OpenGL context knowing this is a tricky problem. Until now, if I hit the power button and then brought it back on, my app would restart and have all sorts of problems like empty textures. Since restoring the state of the app from scratch is just too much work in my case (there's a bunch of threads, complex AI states that I didn't design with this in mind, that sort of thing) I figured I would drop Gingerbread compatibility, start at Ice Cream Sandwich (API level 15), add
android:configChanges="orientation|screenSize"
in the manifest and just deal with restoring all things OpenGL. But just looking at how things behaved before pulling up my sleeves, I was surprised to see that everything worked flawlessly with no changes: textures, VBOs... Even the music picks up right where it left off. I've tested this for power off events and the home button. Now I've witnessed this on a Nexus 5 and Nexus 7 (2012) both running Android 4.4.2 and I can't help but feel a little suspicious...
So here are a few questions I was hoping some Android guru could answer:
Is it OK to do this? Is my app hogging up GPU resources in the background and draining the battery or that kind of thing?
Can I expect this to also work on previous Android versions? (I have nothing below 4.4.2)
Can I add calls to the config changes (mcc, mnc <- those are for calls, right?) and it's fine? (I have no way of testing this before a while)
Are there still cases where the GL context will be lost and I will have to recreate my GL stuff?
Thanks and sorry for the not very broad appeal and unfocused nature of the question (expecting downvotes but this stuff is just so hard to investigate)
The way I've seen this work is that the resources actually are recreated after a sleep/wake, without the developer having to do much to make that happen. Assuming that you are using a GLSurfaceView for your OpenGL rendering, and are following roughly this outline:
http://developer.android.com/training/graphics/opengl/environment.html
And then, as documented under "Activity Life-cycle" in the GLSurfaceView documentation, you hook up the onPause() and onResume() handlers in your activity to call the matching methods on the GLSurfaceView.
What I generally see happen after sleep/wake (including under 4.4.2) is that the onSurfaceCreated() method on the GLSurfaceView.Renderer implementation gets called again. Since this is where you normally create your OpenGL resources, they are in fact recreated when the device wakes up with the application running.
You can try setting a breakpoint in your onSurfaceCreated() and see if it stops there after you wake the device from sleep.
Related
I do have a problem and have very little to go on. I'm about to release an App (created with Air for Android As3) on the Samsung App Store and just got a list of issues that have to be resolved after the app has been tested by samsung staff before the app could be released.
I did manage to solve almost all of the issues, but 1 very important one is beyond me. They say the screen turns/stays black, when returning after the device alarm interrupted the app. This issue practivally happend on all their devices, including a group including the phones I own (e.g. Galaxy S3).
I do have "OnDeActivate" and "OnActivate" listeners in place that are there to pause the app, disable sound etc. if it loses focus, gets minimized etc., yet I checked on my devices and I can't reproduce this error. Meaning if the app gets interrupted on my device by the alarm, I can resume it without any problems. no black screens.
So the question is: Is there any way for me to fix that at all? I do have to work within AirForAndroid AS3 so I guess possibilities are limited. Any clues where I can look? Any listeners to set, or is there a way to maybe "force" the app to reinitialize or refresh the display? Or to listen for the system alarm? Help would be much appreciated. Thanks in advance!
I am trying to overcome the same issue, I read somewhere that setting the stage quality to something else on both the activate and deactivate events might solve the issue.
So just set your stage quality to medium or whatever different in the deactivate and set it back to what it needs to be in the activate.
This should make AIR snap out of that black screen for the alarm (I hope)
An app of mine is with this fix is currently undergoing testing on the Samsung App Store.
I hope it fixes it.
Good news, the dirty fix of toggling the stage quality seems to have worked for Samsung, it has not shown up in their latest certification report of my app.
by the way, this is not for a stage3D app, that's different
It's for a GPU app
When the app loses focus on Android (goes into background) it will lose the context, which among other things mean that you lose all the created graphics, cached objects and like.
You didn't specify what kind of app it is. If you're using Stage3D, that means you'll have to recreate all your textures, and if you're on plain old displaylist, you'll have to recreate any bitmaps that were created at runtime, and redraw your screen at least once (so the vector graphics get redrawn too).
Now, if you're using Starling, for example, it can take care of recreating context for you (there's a flag for enabling that), although you'll still have to recreate dynamically created bitmaps.
Is it possible like in topic, I mean start camera intent and before opening that view set screen not to see rotating screen effectc? I was trying to use overridePendingTransition after startingActivityForResult, I tried also to put this overriDePendingTransition while calling onPause and OnResume. Somehow camera uses own animation. I would like to disable that animation. Is is possible? This effect doesn't affect in android 2.3.x. Does it might have connection with touchWiz?
TL:DR
As of KitKat 4.4.2 this still does not seem possible. Tested with AOSP phone app, Nexus 5 experience Phone App, Maps, AOSP Browser and Chrome.
(I would have put this in a comment, not enough rep yet. It's still an answer per-say, though not a solution to the problem)
Only thing I can say about why it's not possible is:
If you could force a transaction on the "external" intent through
your own app code, you would be basically injecting your animation
into another publisher's app, which would be a MAJOR design flaw
in the Android framework.
My guess is this will never be possible unless the OS manages such transactions in a bullet-proof way to both ends. Some AOSP branded-builds and custom Launchers can change default animations for ALL activity starts/resumes though (or even use no animations at all).
I notice in Android Jelly Bean, the buttons are not responsive after a minute of recording on sensor data logger program. Therefore, I set out to build my own.
However, I am running into the same problem as them. My program becomes unresponsive after a minute or so.
Is there anyway to do this properly in Jelly Bean?
I have tried to run things in the background via, Service and Threads but no avail. I might not be using threads properly. I mean how do you define onChangeSensor on the background? Do you spawn threads every time it is called? Seems excessive and probably slow things down more than necessary.
Is there a way to spawn the media recorder and Sensor logger as separate threads to keep the UI responsive and functional?
The first solution was to disable the continuous focus. I found this out by running the same code without the continuous focus on a Nexus S which does not have the continuous focus feature. I had to comment the parameter setting line out or it will return runtimeexception.
The better solution is to set the API to be 16 and run it on Jelly Bean phone. It worked for me on my Galaxy Nexus. I guess just setting the minimum API setting to something higher changes the way it runs in JB?
I'm first time developer for these types of devices, and UI in general, so I could be missing something basic and obvious.
Everything seems to work fine in the emulator, but I don't know how to simulate turning it.
So I tried running the app on my pandigital (white model - lowest of the low it seems), and each time I turn the Android, it freezes up. At least the UI freezes up, I believe the debug messages are still printing.
This is a home project, I don't have other devices to try it on.
Sorry for being so vague, it's an issue I have been a bit neglecting, trying to work on more interesting issues first, but it's an issue that is bothering me in the back of my mind.
Anyway, I have an Activity that starts up a thread, and creates a class which responds to various events, it implements: MainInterface and SurfaceHolder.Callback. Is there something else I should be handling? possibly?
Is there some specific call I get when the tablet is turned? I'd like to put a debug message in there.
My guess is that you state in your AndroidManifest.xml that this activity will handle rotation events itself (perhaps because you copied it from some project where the activity did do this), and that this statement is a lie, your activity actually makes no attempt to handle rotation.
If this is the case, a sound way to solve your problem is simply to remove the lying android:configChanges from your manifest.
I'm quite new to Android programming but familiar with C/C++ and Linux enough to program a few stuff. In my next project, I've to run some native application (Linux applications) under Android.
The executable I'm calling is using the framebuffer device to produce screen output. When I try to just call the program the output of the program is lost because Android is redrawing the screen, thus overwriting the framebuffer.
In order to prevent this, I made a "stubbing" Android program, which actually has no window design (just a black screen) but calls my program. This is working good to some extend; however, whenever I rotate the screen, or some Tattoo notification comes, Android redraws the screen and we're back to frame #1...
Thus, I wondered if there is a "low level" API or something, which can prevent Android from using the screen at all, as long as I release it. Shortly, like a WakeLock preventing phone from sleeping, I want a 'Lock' which will lock the screen (framebuffer device) completely. Does anyone know how can I achieve such functionality?
PS: This might have something to do with SurfaceFlinger, but I've read somewhere that it doesn't publish any API to user-level.
On Android the screen belongs to SurfaceFlinger.
The executable I'm calling is using the framebuffer device to produce screen output.
That's not supported.
Thus, I wondered if there is a "low level" API or something, which can prevent Android from using the screen at all, as long as I release it.
Nothing that is supported at the SDK or NDK levels. You are welcome to create your own custom firmware that does whatever you want, and load that custom firmware on your own device.
Otherwise, please use a supported means for interacting with the screen (e.g., OpenGL natively in C/C++).