surfaceview - Android app not responding when closed -
i working on game android, , when close app crashes. think because doing render null canvas. when null check, program doesn't crash, doesn't reopen after has been closed. here thread's run:
public void run() { canvas canvas; log.d(tag, "starting game loop"); long begintime; // time when cycle begun long timediff; // time took cycle execute int sleeptime; // ms sleep (<0 if we're behind) int framesskipped; // number of frames being skipped sleeptime = 0; while (running) { canvas = null; // try locking canvas exclusive pixel editing // in surface try { canvas = this.surfaceholder.lockcanvas(); synchronized (surfaceholder) { begintime = system.currenttimemillis(); framesskipped = 0; // resetting frames skipped // update game state this.gamepanel.update(); // render state screen // draws canvas on panel this.gamepanel.render(canvas); // calculate how long did cycle take timediff = system.currenttimemillis() - begintime; // calculate sleep time sleeptime = (int)(frame_period - timediff); if (sleeptime > 0) { // if sleeptime > 0 we're ok try { // send thread sleep short period // useful battery saving thread.sleep(sleeptime); } catch (interruptedexception e) {} } while (sleeptime < 0 && framesskipped < max_frame_skips) { // need catch this.gamepanel.update(); // update without rendering sleeptime += frame_period; // add frame period check if in next frame framesskipped++; } } } { // in case of exception surface not left in // inconsistent state if (canvas != null) { surfaceholder.unlockcanvasandpost(canvas); } } // end } } and here relavent methods in surface class.
@override public void surfacechanged(surfaceholder holder, int format, int width, int height) { } @override public void surfacecreated(surfaceholder holder) { // @ point surface created , // can safely start game loop thread.setrunning(true); thread.start(); } @override public void surfacedestroyed(surfaceholder holder) { log.d(tag, "surface being destroyed"); // tell thread shut down , wait finish // clean shutdown boolean retry = true; while (retry) { try { thread.setrunning(false); thread.join(); retry = false; } catch (interruptedexception e) { // try again shutting down thread } } log.d(tag, "thread shut down cleanly"); } is null check correct , missing methods resume activity?
logcat when nullcheck isn't in place:
03-01 10:37:19.557: e/androidruntime(25129): fatal exception: thread-16380 03-01 10:37:19.557: e/androidruntime(25129): java.lang.nullpointerexception 03-01 10:37:19.557: e/androidruntime(25129): @ org.awesome.androidgame.maingamepanel.render(maingamepanel.java:192) 03-01 10:37:19.557: e/androidruntime(25129): @ org.awesome.androidgame.mainthread.run(mainthread.java:73) 03-01 10:37:23.357: e/bitmapfactory(25280): unable decode stream: java.io.filenotfoundexception: /level_1_1.png: open failed: enoent (no such file or directory) 03-01 10:37:36.097: e/androidruntime(25280): fatal exception: thread-16395 03-01 10:37:36.097: e/androidruntime(25280): java.lang.nullpointerexception 03-01 10:37:36.097: e/androidruntime(25280): @ org.awesome.androidgame.maingamepanel.render(maingamepanel.java:192) 03-01 10:37:36.097: e/androidruntime(25280): @ org.awesome.androidgame.mainthread.run(mainthread.java:73) 03-01 11:02:49.227: e/androidruntime(26150): fatal exception: thread-16425 03-01 11:02:49.227: e/androidruntime(26150): java.lang.nullpointerexception 03-01 11:02:49.227: e/androidruntime(26150): @ org.awesome.androidgame.maingamepanel.render(maingamepanel.java:192) 03-01 11:02:49.227: e/androidruntime(26150): @ org.awesome.androidgame.mainthread.run(mainthread.java:73) 03-01 11:02:53.717: e/androidruntime(26177): fatal exception: thread-16428 03-01 11:02:53.717: e/androidruntime(26177): java.lang.nullpointerexception 03-01 11:02:53.717: e/androidruntime(26177): @ org.awesome.androidgame.maingamepanel.render(maingamepanel.java:192) 03-01 11:02:53.717: e/androidruntime(26177): @ org.awesome.androidgame.mainthread.run(mainthread.java:73) logcat when nullcheck in place:
03-01 11:58:50.297: e/androidruntime(32292): fatal exception: main 03-01 11:58:50.297: e/androidruntime(32292): java.lang.illegalthreadstateexception: thread started. 03-01 11:58:50.297: e/androidruntime(32292): @ java.lang.thread.start(thread.java:1045) 03-01 11:58:50.297: e/androidruntime(32292): @ org.awesome.androidgame.maingamepanel.surfacecreated(maingamepanel.java:83) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.surfaceview.updatewindow(surfaceview.java:569) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.surfaceview.onwindowvisibilitychanged(surfaceview.java:231) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.view.dispatchwindowvisibilitychanged(view.java:7537) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.viewgroup.dispatchwindowvisibilitychanged(viewgroup.java:1039) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.viewgroup.dispatchwindowvisibilitychanged(viewgroup.java:1039) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.viewgroup.dispatchwindowvisibilitychanged(viewgroup.java:1039) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.viewrootimpl.performtraversals(viewrootimpl.java:1211) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.viewrootimpl.dotraversal(viewrootimpl.java:989) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.viewrootimpl$traversalrunnable.run(viewrootimpl.java:4351) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.choreographer$callbackrecord.run(choreographer.java:749) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.choreographer.docallbacks(choreographer.java:562) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.choreographer.doframe(choreographer.java:532) 03-01 11:58:50.297: e/androidruntime(32292): @ android.view.choreographer$framedisplayeventreceiver.run(choreographer.java:735) 03-01 11:58:50.297: e/androidruntime(32292): @ android.os.handler.handlecallback(handler.java:725) 03-01 11:58:50.297: e/androidruntime(32292): @ android.os.handler.dispatchmessage(handler.java:92) 03-01 11:58:50.297: e/androidruntime(32292): @ android.os.looper.loop(looper.java:137) 03-01 11:58:50.297: e/androidruntime(32292): @ android.app.activitythread.main(activitythread.java:5039) 03-01 11:58:50.297: e/androidruntime(32292): @ java.lang.reflect.method.invokenative(native method) 03-01 11:58:50.297: e/androidruntime(32292): @ java.lang.reflect.method.invoke(method.java:511) 03-01 11:58:50.297: e/androidruntime(32292): @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:793) 03-01 11:58:50.297: e/androidruntime(32292): @ com.android.internal.os.zygoteinit.main(zygoteinit.java:560) 03-01 11:58:50.297: e/androidruntime(32292): @ dalvik.system.nativestart.main(native method)
before start thread believe should check see if exists.
it's understanding can't re-start thread in android, should check see if existed , if did, start new 1 so:
if(thread.getstate()==thread.state.terminated){ //exists? thread = new thread(holder, context, handler);} //re-create thread.setrunning(true); thread.start(); as null canvas, if mean check against null in run method (main w'hile loop), in 'finally' section before unlockandpost, yes correct.
however have feeling didn't mean check. had similar problem when if pressed key, reason, null canvas being intermittenty passed ondraw/render method. had encase entire code in method inside check against null canvas render if check came negative! worked , stable after that.
if remember correctly, after lots of research on internet, appears issue few people have had.
Comments
Post a Comment