【问题标题】:Async Task Stops Working, works when debugging with break points - Android异步任务停止工作,在使用断点调试时工作 - Android
【发布时间】:2014-09-17 05:14:23
【问题描述】:

我的 Async 任务正在进行繁重的图像处理,单个 Async 任务可以成功运行,但是如果我尝试执行多个 Async 任务,即在第一个任务完成之前它会停止工作... 虽然当我调试和插入有断点来检查问题时它工作得很好。

我只需要在ActivityResult上有断点

    private class ProcessVideoTask extends AsyncTask<String, Void, Void> {

    int goodPointsLocal;
    int badPointsLocal;
    String videoFileLocal;
    ArrayList<Integer> xposLocal;
    ArrayList<Integer> yposLocal;
    ArrayList<String> markerSelectedLocal;
    int windowXxLocal;
    int windowYyLocal;

    public ProcessVideoTask(int _goodPoints, int _badPoints,
            String _videoFile, ArrayList<Integer> _xpos,
            ArrayList<Integer> _ypos, ArrayList<String> _markerSelected,
            int _windowXx, int _windowYy) {
        // TODO Auto-generated constructor stub

        goodPointsLocal = _goodPoints;
        badPointsLocal = _badPoints;
        videoFileLocal = _videoFile;
        xposLocal = _xpos;
        yposLocal = _ypos;
        markerSelectedLocal = _markerSelected;
        windowXxLocal = _windowXx;
        windowYyLocal = _windowYy;

    }

    // automatically done on worker thread (separate from UI thread)
    protected Void doInBackground(final String... args) {
        notGotoBack = false;
        String path = videoFileLocal;
        ProcessVDOToImages(path);
        try {//get frames from video and edit individually (heavy processing)
            PutMarkersOnImages(xposLocal, yposLocal, markerSelectedLocal,
                    Constants.RT_EVALUATE_TRAINING, windowXxLocal,
                    windowYyLocal);
        } catch (Exception e) {

        }

        mFilePathMarkers = ProcessImagestoVdo();//append audio to frames (heavy)
        SetAudioWithMarkerVDO(mFilePathMarkers, videoFileLocal);

        return null;
    }

    protected void onPostExecute(final Void unused) {
        File savePathWMarker = new File(Environment
                .getExternalStorageDirectory().getPath()
                + "/HumanFocus/MarkerFrame/");

        File savePathWOMarker = new File(Environment
                .getExternalStorageDirectory().getPath()
                + "/HumanFocus/WithoutMarkerFrame/");

        if (savePathWMarker.isDirectory()) {
            String[] children = savePathWMarker.list();
            for (int i = 0; i < children.length; i++) {
                new File(savePathWMarker, children[i]).delete();
            }
        }

        if (savePathWOMarker.isDirectory()) {
            String[] children = savePathWOMarker.list();
            for (int i = 0; i < children.length; i++) {
                new File(savePathWOMarker, children[i]).delete();
            }
        }
        // change this if no Marker Video
        File src = new File("");
        File dst = new File("");
        if (mFilePathMarkers != null) {
            src = new File(mFilePathMarkers);
        }
        if (videoFileLocal != null) {
            dst = new File(videoFileLocal);
        }
        try {
            copyFile(src, dst);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int maxNumber = 0;
        for (int i = 0; i < mCreateTraining.getAttachedFiles().size(); i++) {

            String fileName = mCreateTraining.getAttachedFiles().get(i)
                    .getDisplayName().substring(0, 2);

            if (isNumeric(fileName)) {
                if (Integer.parseInt(fileName) > maxNumber)
                    maxNumber = Integer.parseInt(fileName);
            }
        }

        mCreateTraining.attachFile(saveVideo(videoFileLocal,
                Constants.RT_CREATE_TRAINING, goodPointsLocal,
                badPointsLocal, maxNumber, videoFileLocal));
        updateReportItemsList();
        Toast.makeText(CreateTrainingActivity.this,
                "Video Processing is Successfully Completed",
                Toast.LENGTH_LONG).show();

        notGotoBack = true;
    }
}

为了避免过度处理,我尝试以串行方式而不是并行方式运行它,为了手动执行,我制作了这个计时器。

Timer mTimer = new Timer();
    mTimer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            if (processList.size() > 0) {
                if (processList.get(0).getStatus() == AsyncTask.Status.FINISHED) {

                    processList.remove(0);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    if (processList.size() > 0) {
                        processList.get(0).execute();
                    }
                }
            }
        }
    }, 0, 5000);

根据相机的活动结果,创建异步任务并将其插入processList(AsyncTask的ArrayList)

if (requestCode == REQUEST_CODE_RECORD_VIDEO_ACTIVITY) {
        if (data != null && data.getExtras() != null) {
            Toast.makeText(CreateTrainingActivity.this,
                    "Video is Processing.. Please Wait ...",
                    Toast.LENGTH_LONG).show();


            goodPoints = data.getExtras().getInt("goodPoints", 0);
            badPoints = data.getExtras().getInt("badPoints", 0);
            videoFile = data.getExtras().getString("data");
            Xpos = data.getIntegerArrayListExtra("Xpos");
            Ypos = data.getIntegerArrayListExtra("Ypos");
            MarkerSelected = data.getStringArrayListExtra("MarkerSelected");

            windowXx = data.getExtras().getInt("windowXx");
            windowYy = data.getExtras().getInt("windowYy");

            ///////////////////////////////////////////////// Put tasks into queue

            ProcessVideoTask mTask = new ProcessVideoTask(goodPoints,
                    badPoints, videoFile, Xpos, Ypos, MarkerSelected,
                    windowXx, windowYy);

            processList.add(mTask);

            if (processList.size() == 1) {
                processList.get(0).execute();
            }

        }

这是我的日志

09-17 10:09:23.108: E/sizeee addxxxxxxxxxx(21007): 96
09-17 10:09:23.148: I/dalvikvm-heap(21007): Grow heap (frag case) to 144.206MB for 11059216-byte allocation
09-17 10:09:23.218: I/dalvikvm-heap(21007): Grow heap (frag case) to 151.585MB for 7738604-byte allocation
09-17 10:09:23.248: I/millisUntilFinished:(21007): 1794
09-17 10:09:23.248: E/sizeee addxxxxxxxxxx(21007): 99
09-17 10:09:23.278: I/dalvikvm-heap(21007): Grow heap (frag case) to 144.206MB for 11059216-byte allocation
09-17 10:09:23.368: E/sizeee addxxxxxxxxxx(21007): 102
09-17 10:09:23.418: I/dalvikvm-heap(21007): Grow heap (frag case) to 144.206MB for 11059216-byte allocation
09-17 10:09:23.478: I/dalvikvm-heap(21007): Grow heap (frag case) to 151.585MB for 7738604-byte allocation
09-17 10:09:23.508: E/sizeee addxxxxxxxxxx(21007): 105
09-17 10:09:23.538: I/dalvikvm-heap(21007): Grow heap (frag case) to 144.206MB for 11059216-byte allocation
09-17 10:09:23.608: E/sizeee addxxxxxxxxxx(21007): 108
09-17 10:09:23.668: I/dalvikvm-heap(21007): Grow heap (frag case) to 144.206MB for 11059216-byte allocation
09-17 10:09:23.728: I/dalvikvm-heap(21007): Grow heap (frag case) to 151.585MB for 7738604-byte allocation
09-17 10:09:23.758: E/sizeee addxxxxxxxxxx(21007): 111
09-17 10:09:23.788: I/dalvikvm-heap(21007): Grow heap (frag case) to 144.207MB for 11059216-byte allocation
09-17 10:09:23.838: E/sizeee addxxxxxxxxxx(21007): 114
09-17 10:09:23.868: I/dalvikvm-heap(21007): Grow heap (frag case) to 151.586MB for 11059216-byte allocation
09-17 10:09:23.908: I/dalvikvm-heap(21007): Grow heap (frag case) to 158.966MB for 7738604-byte allocation
09-17 10:09:25.478: D/MediaRecorder(21007): Current Package Name: uk.org.humanfocus.hfi
09-17 10:09:25.488: I/Choreographer(21007): Skipped 98 frames!  The application may be doing too much work on its main thread.
09-17 10:09:25.488: I/millisUntilFinished:(21007): 1791
09-17 10:09:26.498: I/millisUntilFinished:(21007): 1790
09-17 10:09:27.508: I/millisUntilFinished:(21007): 1789
09-17 10:09:28.508: I/millisUntilFinished:(21007): 1788
09-17 10:09:29.508: I/millisUntilFinished:(21007): 1787
09-17 10:09:30.508: I/millisUntilFinished:(21007): 1786
09-17 10:09:30.678: I/user interaction(21007): called
09-17 10:09:30.678: I/millisUntilFinished:(21007): 1799
09-17 10:09:31.698: I/millisUntilFinished:(21007): 1798
09-17 10:09:31.698: I/On Pause :(21007): called
09-17 10:09:32.318: I/Choreographer(21007): Skipped 30 frames!  The application may be doing too much work on its main thread.

【问题讨论】:

  • 使用 Listeners 了解 Async 任务的执行状态查看此链接stackoverflow.com/questions/23534418/…
  • 很抱歉,这个日志没有提到任何崩溃,你能把新的 logact 转储和崩溃日志放到这里吗?

标签: java android asynchronous android-asynctask android-camera


【解决方案1】:

我认为在您的情况下,您应该使用 Android Service 或 Intent Service。 链接:http://developer.android.com/guide/components/services.html

您不应该将 Async 用于长时间的繁重操作。 就我而言,我使用了带有新 Runnables 的 Intent Service,并且它起作用了。 如果您有更多问题,请提出。

【讨论】:

    【解决方案2】:

    看看你的logcat,最后一行很有趣:

    09-17 10:09:32.318: I/Choreographer(21007): Skipped 30 frames!  The application may be doing too much work on its main thread.
    

    它在调试期间工作的事实向我表明了这一点的重要性 - 当断点给它足够的时间来赶上时!

    作为一般规则,@dadecki 可能是正确的:对于 android 上的这么多处理,您可能应该使用后台服务。然而,如果你不想走这条路,问这个问题似乎是明智的:为什么应用程序在主线程上做了太多的工作。几个建议:

    • 尽可能多地从onPostExecute 移到doInBackground - 那里似乎有很多代码!
    • 同时查看应用在主线程中的其他操作:您的代码中是否还有其他真正应该在异步任务(或服务)中执行的操作。

    一旦您处理了这个问题,您就可以更好地确定仍然存在的问题(如果有的话)。

    【讨论】:

      【解决方案3】:

      对于您的情况,建议使用AsyncTaskLoader。因为一次您可以拥有有限数量的 AsynTask。请this answer. 在调试中它可能工作正常,因为在断点处,系统有时间来完成挂起的 AsyncTask,这就是为什么在调试中永远不会达到最大池大小的原因。

      谢谢

      【讨论】:

        【解决方案4】:

        增加线程睡眠时间,现在看到它是 1 秒,使其变为 5 秒或 10 秒..

         try {
                            Thread.sleep(10000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
        

        【讨论】:

          猜你喜欢
          • 2018-10-29
          • 2014-02-09
          • 2023-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多