[英]Android App runs perfectly when ran after installation, but shows white screen on second run?
I used an idea from first answer to this question in order to pause and resume drawing on canvas. 为了暂停和恢复在画布上的绘画,我从最初回答这个问题开始就使用了一个想法。 It worked well, but a new problem that I'm facing is, app is not starting up if I press Home button and start it again.
它运行良好,但是我面临的一个新问题是,如果我按“主页”按钮并再次启动,则应用程序无法启动。 I've called
onResume()
when user touches the screen ie MotionEvent.ACTION_DOWN
and onPause()
in MotionEvent.ACTION_UP
. 我叫
onResume()
当用户触摸屏幕时即MotionEvent.ACTION_DOWN
和onPause()
在MotionEvent.ACTION_UP
。 This works perfectly fine which I've confirmed somehow. 我已经以某种方式证实了这一点,效果非常好。 My question is if
onResume()
is working now, why isn't it working when App is started after pressing Home? 我的问题是,如果
onResume()
现在可以正常工作,为什么在按Home后启动App时它不能正常工作?
Edit: This is Thread Class which handles when to draw & when not. 编辑:这是线程类,处理何时绘制以及何时不绘制。
package com.example.testsurfaceview;
import android.graphics.Canvas;
import android.view.SurfaceHolder;
public class CanvasThread extends Thread {
private SurfaceHolder _surfaceHolder;
private SurfaceTest _surfaceTest;
private Object mPauseLock;
private boolean mPaused;
private boolean mRun;
// private boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder, SurfaceTest surfaceTest) {
_surfaceHolder = surfaceHolder;
_surfaceTest = surfaceTest;
mPauseLock = new Object();
mPaused = false;
mRun = false;
}
public void setRunning(boolean run) {
mRun = run;
}
@Override
public void run() {
// TODO Auto-generated method stub
// super.run();
Canvas canvas;
while (mRun) {
canvas = null;
try {
canvas = _surfaceHolder.lockCanvas();
synchronized (_surfaceHolder) {
_surfaceTest.letsdraw(canvas);
}
} 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 (canvas != null) {
_surfaceHolder.unlockCanvasAndPost(canvas);
}
}
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {
}
}
}
}
}
/**
* Call this on pause.
*/
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
/**
* Call this on resume.
*/
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
}
And here's a part of code from a class that extends SurfaceView and implements SurfaceHolder.Callback 这是扩展SurfaceView并实现SurfaceHolder.Callback的类的代码的一部分
public SurfaceTest(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
canvasThread = new CanvasThread(getHolder(), this);
setFocusable(true);
}
public SurfaceTest(Context context) {
super(context);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
canvasThread = new CanvasThread(getHolder(), this);
setFocusable(true);
}
public SurfaceTest(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
canvasThread = new CanvasThread(getHolder(), this);
setFocusable(true);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
//getHolder().addCallback(this);
canvasThread = new CanvasThread(getHolder(), this);
setFocusable(true);
canvasThread.setRunning(true);
canvasThread.start();
initializer(); //its a method where I'm only initializing Paint() objects
this.setOnTouchListener(this);
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
canvasThread.setRunning(true);
canvasThread.start();
initializer();
this.setOnTouchListener(this);
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
canvasThread.setRunning(false);
while (true) {
try {
canvasThread.join();
break;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
canvasThread.onResume();
sx = event.getX();
sy = event.getY();
fx = 0;
fy = 0;
break;
case MotionEvent.ACTION_MOVE:
x = event.getX();
y = event.getY();
break;
case MotionEvent.ACTION_UP:
fx = event.getX();
fy = event.getY();
x = 0;
y = 0;
canvasThread.onPause();
break;
}
return true;
}
LogCat: LogCat:
06-03 10:54:28.203: D/AndroidRuntime(322): CheckJNI is ON
06-03 10:54:28.494: D/AndroidRuntime(322): --- registering native functions ---
06-03 10:54:29.734: D/dalvikvm(251): GC_EXPLICIT freed 160 objects / 8248 bytes in 116ms
06-03 10:54:37.143: D/PackageParser(59): Scanning package: /data/app/vmdl26358.tmp
06-03 10:54:43.624: D/dalvikvm(251): GC_EXPLICIT freed 126 objects / 10296 bytes in 1260ms
06-03 10:54:47.654: I/PackageManager(59): Removing non-system package:com.example.testsurfaceview
06-03 10:54:47.654: I/ActivityManager(59): Force stopping package com.example.testsurfaceview uid=10038
06-03 10:54:47.654: I/Process(59): Sending signal. PID: 311 SIG: 9
06-03 10:54:47.684: I/UsageStats(59): Unexpected resume of com.android.launcher while already resumed in com.example.testsurfaceview
06-03 10:54:47.724: I/WindowManager(59): WIN DEATH: Window{43fe9438 SurfaceView paused=false}
06-03 10:54:47.733: I/WindowManager(59): WIN DEATH: Window{44034690 com.example.testsurfaceview/com.example.testsurfaceview.MainActivity paused=false}
06-03 10:54:47.853: W/InputManagerService(59): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@4408bf18
06-03 10:54:47.883: W/KeyCharacterMap(118): No keyboard for id 0
06-03 10:54:47.883: W/KeyCharacterMap(118): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
06-03 10:54:49.123: D/dalvikvm(59): GC_FOR_MALLOC freed 9620 objects / 514768 bytes in 94ms
06-03 10:54:49.163: D/PackageManager(59): Scanning package com.example.testsurfaceview
06-03 10:54:49.163: I/PackageManager(59): Package com.example.testsurfaceview codePath changed from /data/app/com.example.testsurfaceview-1.apk to /data/app/com.example.testsurfaceview-2.apk; Retaining data and using new
06-03 10:54:49.163: I/PackageManager(59): /data/app/com.example.testsurfaceview-2.apk changed; unpacking
06-03 10:54:49.183: D/installd(35): DexInv: --- BEGIN '/data/app/com.example.testsurfaceview-2.apk' ---
06-03 10:54:50.093: D/dalvikvm(330): DexOpt: load 114ms, verify 476ms, opt 22ms
06-03 10:54:50.133: D/installd(35): DexInv: --- END '/data/app/com.example.testsurfaceview-2.apk' (success) ---
06-03 10:54:50.143: W/PackageManager(59): Code path for pkg : com.example.testsurfaceview changing from /data/app/com.example.testsurfaceview-1.apk to /data/app/com.example.testsurfaceview-2.apk
06-03 10:54:50.143: W/PackageManager(59): Resource path for pkg : com.example.testsurfaceview changing from /data/app/com.example.testsurfaceview-1.apk to /data/app/com.example.testsurfaceview-2.apk
06-03 10:54:50.143: D/PackageManager(59): Activities: com.example.testsurfaceview.MainActivity
06-03 10:54:50.163: I/ActivityManager(59): Force stopping package com.example.testsurfaceview uid=10038
06-03 10:54:50.253: I/installd(35): move /data/dalvik-cache/data@app@com.example.testsurfaceview-2.apk@classes.dex -> /data/dalvik-cache/data@app@com.example.testsurfaceview-2.apk@classes.dex
06-03 10:54:50.253: D/PackageManager(59): New package installed in /data/app/com.example.testsurfaceview-2.apk
06-03 10:54:50.384: I/ActivityManager(59): Force stopping package com.example.testsurfaceview uid=10038
06-03 10:54:50.454: D/dalvikvm(118): GC_EXPLICIT freed 628 objects / 39856 bytes in 58ms
06-03 10:54:50.664: W/RecognitionManagerService(59): no available voice recognition services found
06-03 10:54:50.753: D/dalvikvm(150): GC_EXPLICIT freed 1808 objects / 92712 bytes in 282ms
06-03 10:54:50.873: D/dalvikvm(59): GC_EXPLICIT freed 7350 objects / 467208 bytes in 109ms
06-03 10:54:50.873: I/installd(35): unlink /data/dalvik-cache/data@app@com.example.testsurfaceview-1.apk@classes.dex
06-03 10:54:50.883: D/AndroidRuntime(322): Shutting down VM
06-03 10:54:50.893: D/dalvikvm(322): Debugger has detached; object registry had 1 entries
06-03 10:54:51.344: D/AndroidRuntime(336): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
06-03 10:54:51.344: D/AndroidRuntime(336): CheckJNI is ON
06-03 10:54:51.483: D/AndroidRuntime(336): --- registering native functions ---
06-03 10:54:52.093: I/ActivityManager(59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.example.testsurfaceview/.MainActivity }
06-03 10:54:52.173: D/AndroidRuntime(336): Shutting down VM
06-03 10:54:52.183: I/ActivityManager(59): Start proc com.example.testsurfaceview for activity com.example.testsurfaceview/.MainActivity: pid=342 uid=10038 gids={}
06-03 10:54:52.193: D/jdwp(336): Got wake-up signal, bailing out of select
06-03 10:54:52.193: D/dalvikvm(336): Debugger has detached; object registry had 1 entries
06-03 10:54:52.263: I/AndroidRuntime(336): NOTE: attach of thread 'Binder Thread #3' failed
06-03 10:54:53.093: I/ActivityManager(59): Displayed activity com.example.testsurfaceview/.MainActivity: 922 ms (total 1729005 ms)
06-03 10:54:58.213: D/dalvikvm(262): GC_EXPLICIT freed 249 objects / 11920 bytes in 101ms
06-03 10:55:05.213: D/dalvikvm(118): GC_EXPLICIT freed 903 objects / 49928 bytes in 169ms
06-03 10:55:20.704: W/KeyCharacterMap(342): No keyboard for id 0
06-03 10:55:20.704: W/KeyCharacterMap(342): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
06-03 10:55:29.574: D/dalvikvm(118): GC_EXTERNAL_ALLOC freed 303 objects / 16096 bytes in 54ms
06-03 10:55:29.783: D/SntpClient(59): request time failed: java.net.SocketException: Address family not supported by protocol
06-03 10:55:30.993: W/ActivityManager(59): Activity destroy timeout for HistoryRecord{43ee3770 com.example.testsurfaceview/.MainActivity}
06-03 10:55:33.983: I/ActivityManager(59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.testsurfaceview/.MainActivity }
06-03 10:55:34.133: W/WindowManager(59): Rebuild removed 4 windows but added 2
06-03 10:55:43.993: W/ActivityManager(59): Launch timeout has expired, giving up wake lock!
06-03 10:55:44.083: W/ActivityManager(59): Activity idle timeout for HistoryRecord{43fb3800 com.example.testsurfaceview/.MainActivity}
I'm guessing that your overly-complex threading / synchronization code is getting you into a race condition. 我猜想您过于复杂的线程/同步代码使您陷入竞争状态。
I suggest that you simplify your code greatly, and get rid of all synchronization code if possible (it should be). 我建议您极大地简化代码,并尽可能删除所有同步代码(应该这样做)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.