将代码移动到可运行文件后,Android 应用程序在没有 ANR 的情况下卡住

标签 android freeze runnable

我正在实现一个自定义相机,我使用 onPreviewFrame() 进行实时效果。主要效果(fx1)是一个可运行的,似乎还可以,在需要时丢帧。
当 fx1 关闭时,第二个更简单的 fx (fx2) 运行。
当 fx2 在主线程上运行时没问题(它在 2 毫秒内运行),但有时我看到 ANR,所以我决定将它移到第二个可运行的,但现在导致应用程序卡住。

class FX2Runnable implements Runnable {
    private byte[] data;
    FX2Runnable(byte[] _data) {
        data = _data;
    }

    public void run() {
        hview.FX2(data);

        hview.post(new Runnable() {
            public void run() {
                hview.postInvalidate();
                //.invalidate(); caused ANR!!
            }
        });
        FLAG_FX2_PROCESSING = false;
    }
}

我是这样调用它的

private PreviewCallback previewCallback=new PreviewCallback() {
    public void onPreviewFrame(byte[] data, Camera cam) {
        if(FX==1) {
            // FX1
            if(FLAG_FX1_PROCESSING) {
                //skip
            } else {
                FLAG_FX1_PROCESSING = true;
                FX1Thread = new Thread(new FX1Runnable());
                FX1Thread.start();
            }
        } else {
            // FX2
            if(FLAG_FX2_PROCESSING) {
                //skip
            } else {
                FLAG_FX2_PROCESSING = true;
                FX2Thread = new Thread(new FX2Runnable(data));
                FX2Thread.start();
            }
            /* this was the old code and was working fine
               but i needed to solve some spare ANR
            //hview.FX2(data);
            //hview.invalidate();
            */
        }
    }
}

我做错了什么!?

顺便说一句,我似乎无法在模拟器上卡住应用程序,只能在我的设备上卡住。

编辑

尝试使用 runOnUiThread(Runnable) 而不是 hview.post(Runnable),它似乎有效,但我只需要等待几分钟才能再次看到卡住的应用程序!它稍后会发生,但它会再次发生!

这是一个日志猫

08-26 17:32:13.398: I/ActivityManager(250): Displayed it.jcsoft.abbracadabbra/.EnhancedCameraPreviewActivity: +3s576ms
08-26 17:32:13.414: W/IInputConnectionWrapper(459): showStatusIcon on inactive InputConnection
08-26 17:32:13.441: I/GPS(9149): new network location: Location[mProvider=network,mTime=1377531132668,mLatitude=44.1459721,mLongitude=12.4545174,mHasAltitude=false,mAltitude=0.0,mHasSpeed=false,mSpeed=0.0,mHasBearing=false,mBearing=0.0,mHasAccuracy=true,mAccuracy=43.887,mExtras=Bundle[mParcelledData.dataSize=212]]
08-26 17:32:15.441: D/dalvikvm(250): WAIT_FOR_CONCURRENT_GC blocked 0ms
08-26 17:32:15.867: D/dalvikvm(250): GC_EXPLICIT freed 1300K, 23% free 16030K/20615K, paused 3ms+41ms, total 428ms
08-26 17:32:37.707: D/dalvikvm(250): GC_CONCURRENT freed 1878K, 22% free 16105K/20615K, paused 4ms+110ms, total 888ms
08-26 17:32:37.855: D/dalvikvm(9149): null clazz in OP_INSTANCE_OF, single-stepping
08-26 17:32:49.375: D/dalvikvm(834): GC_CONCURRENT freed 512K, 9% free 9179K/9991K, paused 336ms+218ms, total 4454ms
08-26 17:32:49.375: D/dalvikvm(834): WAIT_FOR_CONCURRENT_GC blocked 1740ms
08-26 17:32:58.605: D/dalvikvm(250): GC_CONCURRENT freed 1934K, 22% free 16098K/20615K, paused 5ms+32ms, total 284ms
08-26 17:33:00.070: D/SizeAdaptiveLayout(335): com.android.internal.widget.SizeAdaptiveLayout@422dcb90child view android.widget.FrameLayout@422edb18 measured out of bounds at 95px clamped to 96px
08-26 17:33:00.093: D/SizeAdaptiveLayout(335): com.android.internal.widget.SizeAdaptiveLayout@4231b860child view android.widget.FrameLayout@4231d180 measured out of bounds at 95px clamped to 96px
08-26 17:33:10.257: D/dalvikvm(9149): GC_CONCURRENT freed 455K, 4% free 14709K/15303K, paused 3ms+4ms, total 78ms
08-26 17:33:20.082: D/dalvikvm(250): GC_CONCURRENT freed 1933K, 22% free 16091K/20615K, paused 5ms+30ms, total 282ms
08-26 17:33:23.379: I/InputDispatcher(250): Application is not responding: Window{425f23b0 it.jcsoft.abbracadabbra/it.jcsoft.abbracadabbra.EnhancedCameraPreviewActivity paused=false}.  It has been 5002.6ms since event, 5002.5ms since wait started.  Reason: Waiting because the touched window has not finished processing the input events that were previously delivered to it.
08-26 17:33:23.379: I/WindowManager(250): Input event dispatching timed out sending to it.jcsoft.abbracadabbra/it.jcsoft.abbracadabbra.EnhancedCameraPreviewActivity
08-26 17:33:28.437: I/InputDispatcher(250): Dropped event because it is stale.

请帮忙!

最佳答案

你真的应该使用 Handler 来进行这种操作。

一旦完成操作,让可运行对象发布一条消息,然后执行 hview.postInvalidate();方法调用。

有很多指南如何做到这一点。

一些链接包括: http://developer.android.com/reference/android/os/Handler.html

http://androidexample.com/Thread_With_Handlers_-_Android_Example/index.php?view=article_discription&aid=58&aaid=83

http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html

关于将代码移动到可运行文件后,Android 应用程序在没有 ANR 的情况下卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18443481/

相关文章:

windows-7 - LispCabinet 读行卡住

linux - Linux 进程挂起问题的调试实用程序?

Android 停止可运行 onBackPressed()

android:使用 FFMPEG 将两个音频文件合并为一个

java - 等待然后接收文本字段输入而不卡住 GUI

java - 在 Activity 中设置谷歌分析跟踪器时,方法 getActivity() 未定义类型 Activity

java - ScheduledExecutorService仅使用switch语句执行一次

java - 是否存在通过调用执行程序服务的可运行实例的提交而获得的Future对象上使用get的用例

java - 未显示来自数据库的数据

android - 在 RecyclerView 小部件中使用自定义 View