Android应用程序关闭并重新打开时崩溃
我有一个非常简单的android应用程序,只显示一个空白的白屏。当我通过按HOME按钮关闭应用程序时,然后尝试再次打开应用程序,它崩溃,我得到“强制关闭”按钮。在Eclipse中,我收到了这个错误,“ActivityManager:警告:活动未启动,因为当前活动正在为用户保留。”。我如何解决这个崩溃?Android应用程序关闭并重新打开时崩溃
public class HelloAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new Panel(this));
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private TutorialThread _thread;
public Panel(Context context) {
super(context);
// register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
_thread = new TutorialThread(holder, this);
setFocusable(true);
}
@Override
public void onDraw(Canvas canvas) {
// Clear the background
canvas.drawColor(Color.WHITE);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// resize canvas here
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
添加logcat的
03-15 15:36:05.579: INFO/AndroidRuntime(4441): NOTE: attach of thread 'Binder Thread #2' failed
03-15 15:36:05.719: DEBUG/AndroidRuntime(4449): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
03-15 15:36:05.719: DEBUG/AndroidRuntime(4449): CheckJNI is OFF
03-15 15:36:05.719: DEBUG/dalvikvm(4449): creating instr width table
03-15 15:36:05.759: DEBUG/AndroidRuntime(4449): --- registering native functions ---
03-15 15:36:05.969: INFO/ActivityManager(1294): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.helloandroid/.HelloAndroid }
03-15 15:36:05.979: DEBUG/Launcher(1371): onPause+
03-15 15:36:05.979: DEBUG/Launcher.DragController(1371): +endDrag: false
03-15 15:36:05.979: DEBUG/Launcher.DragController(1371): mDragging == false
03-15 15:36:05.979: DEBUG/Launcher.DragController(1371): -endDrag: false
03-15 15:36:05.979: DEBUG/Launcher(1371): onPause-
03-15 15:36:05.999: DEBUG/AndroidRuntime(4428): Shutting down VM
03-15 15:36:05.999: DEBUG/AndroidRuntime(4449): Shutting down VM
03-15 15:36:05.999: WARN/dalvikvm(4428): threadid=1: thread exiting with uncaught exception (group=0x4001d7e0)
03-15 15:36:06.009: DEBUG/dalvikvm(4449): Debugger has detached; object registry had 1 entries
03-15 15:36:06.009: INFO/AndroidRuntime(4449): NOTE: attach of thread 'Binder Thread #3' failed
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): FATAL EXCEPTION: main
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): java.lang.IllegalThreadStateException: Thread already started.
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at java.lang.Thread.start(Thread.java:1322)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at com.example.helloandroid.HelloAndroid$Panel.surfaceCreated(HelloAndroid.java:55)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.view.SurfaceView.updateWindow(SurfaceView.java:538)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:206)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.view.View.dispatchWindowVisibilityChanged(View.java:3888)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:725)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:725)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.view.ViewRoot.performTraversals(ViewRoot.java:748)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.view.ViewRoot.handleMessage(ViewRoot.java:1737)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.os.Handler.dispatchMessage(Handler.java:99)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.os.Looper.loop(Looper.java:123)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at android.app.ActivityThread.main(ActivityThread.java:4627)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at java.lang.reflect.Method.invokeNative(Native Method)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at java.lang.reflect.Method.invoke(Method.java:521)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-15 15:36:06.029: ERROR/AndroidRuntime(4428): at dalvik.system.NativeStart.main(Native Method)
03-15 15:36:06.039: WARN/ActivityManager(1294): Force finishing activity com.example.helloandroid/.HelloAndroid
03-15 15:36:06.541: WARN/ActivityManager(1294): Activity pause timeout for HistoryRecord{450300c0 com.example.helloandroid/.HelloAndroid}
03-15 15:36:06.549: DEBUG/Launcher(1371): onResume+
03-15 15:36:06.549: DEBUG/Launcher.DragController(1371): +endDrag: false
03-15 15:36:06.549: DEBUG/Launcher.DragController(1371): mDragging == false
03-15 15:36:06.549: DEBUG/Launcher.DragController(1371): -endDrag: false
03-15 15:36:06.549: DEBUG/Launcher(1371): onResume-
03-15 15:36:08.645: ERROR/KINETO(1370): KLOG0C3- xmk_QueryOSQueue SDL Queue empty : WAIT_FOREVER
我已经回答了这样here的问题。
您遇到的错误可能是由您的Thread
引起的(没有看到完整的Logcat,但很难说)。您每次启动表面已创建,这会使您的应用程序崩溃,因为您无法两次调用Thread.start()
。看看我上面的链接,以更深入地描述问题以及如何解决问题。
因为我的解释是不够的,我将发布整个解决方案:
内,您的Runnable/Thread
:
private Object mPauseLock = new Object();
private boolean mPaused;
// Constructor stuff.
// This should be after your drawing/update code inside your thread's run() code.
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {
}
}
}
// Two methods for your Runnable/Thread class to manage the thread properly.
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
在你SurfaceView
类:
private boolean mGameIsRunning;
@Override
public void surfaceCreated(SurfaceHolder holder) {
// Your own start method.
start();
}
public void start() {
if (!mGameIsRunning) {
thread.start();
mGameIsRunning = true;
} else {
thread.onResume();
}
}
这里有一个简单的解决方案这在某些情况下可能是可以接受的,比如背景动画屏幕和状态不需要恢复的活动 - 表面vi新闻活动需要暂停时完成。
protected void onPause() {
super.onPause();
finish();
}
更好的解决方案是从构造移动线程的创建插入surfaceCretaed这样的:
@Override
public void surfaceCreated(SurfaceHolder holder) {
_thread = new TutorialThread(holder, this);
_thread.setRunning(true);
_thread.start();
}
然后在线程循环创建一个暂停标记:
if(!pause){
_panel.onDraw(c);
}
终于在onPause和onRestore中为活动设置了暂停标志:
protected void onResume() {
super.onResume();
pause = false;
}
protected void onPause() {
super.onPause();
pause = true;
}
当用户单击主页按钮surfaceDestroyed被调用将关闭当前线程“_thread”。当他返回到应用程序时,surfaceCreated会将引用“_thread”分配给新线程,而旧线程对象将被垃圾收集器删除。
对以下解决方案进行了测试。代码检查线程状态,如果终止则创建一个新状态。 没有崩溃,我能看到的唯一的问题是游戏状态没有保存,所以基本上从HOME键按回来,再次开始游戏。 p.s.记得从Lunarview视图中传递上下文并设置为mContextLunarView。 希望这有助于。这些论坛真棒。保持。
public void surfaceCreated(SurfaceHolder holder) {
// start the thread here so that we don't busy-wait in run()
// waiting for the surface to be created
if(thread.getState() == Thread.State.TERMINATED) {
//LunarView Thread state TERMINATED..make new...under CheckCreateThread
thread = new LunarThread(holder, mContextLunarView, new Handler() {
@Override
public void handleMessage(Message m) {
mStatusText.setVisibility(m.getData().getInt("viz"));
mStatusText.setText(m.getData().getString("text"));
}
});
}
thread.setRunning(true);
thread.start();
}
工作正常!非常感谢! – 2012-06-14 15:22:55
请寄出logcat。 – EboMike 2011-03-15 22:31:11
是的,错误是由你的'Thread'引起的。请看下面的答案。 – Wroclai 2011-03-15 22:46:27
LunarLander和JetBoy在经过HOME之后都会崩溃并重新启动! – Lumis 2011-03-15 23:01:52