0

我使用了这个问题的第一个答案的想法来暂停和恢复在画布上绘图。它运行良好,但我面临的一个新问题是,如果我按下主页按钮并重新启动,应用程序不会启动。onResume()当用户触摸屏幕时,我已经调用了 ieMotionEvent.ACTION_DOWNonPause()in MotionEvent.ACTION_UP。这工作得很好,我已经以某种方式证实了这一点。我的问题是如果onResume()现在可以工作,为什么在按 Home 后启动 App 时它不工作?

编辑:这是处理何时绘制和何时不绘制的线程类。

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;
    }

日志猫:

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}
4

1 回答 1

0

我猜你过于复杂的线程/同步代码会让你陷入竞争状态。

我建议你大大简化你的代码,如果可能的话(应该)去掉所有的同步代码。

于 2013-06-03T11:09:17.350 回答