简体   繁体   English

安装后运行时,Android App可以完美运行,但是第二次运行时显示白屏吗?

[英]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_DOWNonPause()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.

相关问题 Android应用重新打开后显示白屏 - Android app shows white screen after reopening 当我按 f5 或运行按钮运行应用程序并通过 flutter 运行命令运行正常时,flutter 应用程序显示白屏 - flutter app shows a white screen when I run app by pressing f5 or run button and runs fine by flutter run command 两次退出时,Android应用显示白屏 - Android app shows white screen when twice to exit Android:当我打开应用程序时,它会显示一个白色屏幕几秒钟 - Android : When I open the app it shows a white screen for a few seconds android 的 React Native 应用程序移动到后台时显示白屏? - React Native app for android when moved to background shows white screen? Android OpenGL应用程序第二次启动时显示白屏 - Android OpenGL app display white screen when launch the second time Android应用程序可在模拟器中运行,但在手机上运行时,logcat不会显示此类表 - Android app runs in emulator but when run on phone, logcat shows no such table 模拟器运行正常,但应用程序显示白屏,错误如下 - emulator runs fine but app shows white screen, error is below Android-TV 应用程序显示白屏 - Android-TV app shows white screen 适用于Cordova的React应用显示适用于Android的白屏 - React app for cordova shows white screen for android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM