我在第一个回答this问题时使用了一个想法,以便在画布上暂停和恢复绘图。它运作良好,但我面临的一个新问题是,如果我按下Home按钮并重新启动它,app就无法启动。我在用户触摸屏幕时调用了onResume()
,即MotionEvent.ACTION_DOWN
中的onPause()
和MotionEvent.ACTION_UP
。这完全正常,我已经证实了某种方式。我的问题是如果onResume()
现在正在运行,为什么在按Home后启动App时它不起作用?
编辑:这是Thread Class,它处理何时绘制&什么时候没有。
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();
}
}
}
这是扩展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的:
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}
答案 0 :(得分:0)
我猜你过于复杂的线程/同步代码会让你陷入竞争状态。
我建议您大大简化代码,并在可能的情况下删除所有同步代码(应该是这样)。