2017-07-28 37 views
0

因此,我编写了自己的AsyncTask类,像本地运行在ThreadPoolExecutor上的系统。一切都很好,直到我决定实施事情的进展。该进度与AsyncTask非常相似,在UI线程上调用onProgressUpdate函数。我遇到的问题是,无论何时在onProgressUpdate中存在System.out或Log.x行,它都会无限期地挂起,没有任何错误或警告。代码如下:Android AsyncTask进度更新挂起

public abstract class Task<A, B> { 

    private static final Executor EXECUTOR = getExecutor(); 
    private static final int DEFAULT_PRIORITY = Thread.MIN_PRIORITY; 
    private static final int DEFAULT_PROGRESS_INCREMENT = 1; 

    private static final Executor getExecutor() { 
     ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool(); 
     executor.setCorePoolSize(1); 
     executor.allowCoreThreadTimeOut(false); 
     // TODO set rejection handler 
     //executor.setRejectedExecutionHandler(new Handler()); 
     // TODO set thread factory 
     executor.prestartCoreThread(); 
     return executor; 
    } 

    public static class ExecutionListener<B> { 

     public void onPreExecute() { 
      Log.i("TASK", "Pre - Thread: " + Thread.currentThread().getId()); 
     } 

     public void onPostExecute(B output) { 

      Log.i("TASK", "Post - Thread: " + Thread.currentThread().getId() + " - Output: " + output); 
     } 

     public void onProgressUpdate(int progress) { 
      Log.d("TASK", "Hello"); 
     } 
    } 

    private Handler handler; 
    private ExecutionListener<B> executionListener; 
    private volatile int progress = 0; 
    private AtomicBoolean progressPublished = new AtomicBoolean(true); 
    private B output; 

    public Task() { 
     this.handler = new Handler(); 
     this.executionListener = new ExecutionListener(); 
    } 

    public void setExecutionListener(ExecutionListener executionListener) { 
     if(executionListener == null) { 
      this.executionListener = new ExecutionListener(); 
     } 
     else { 
      this.executionListener = executionListener; 
     } 
    } 

    protected void updateProgress(int progressMade) { 
     Log.d("TASK", "Test"); 
     progress += progressMade; 
     if(progressPublished.compareAndSet(true, false)) { 
      if(!handler.post(new Runnable() { 
       @Override 
       public void run() { 
        Log.d("TASK", new Integer(progress).toString() + " - a"); 
        executionListener.onProgressUpdate(progress); 
        // Hangs below 
        progressPublished.lazySet(true); 
        Log.d("TASK", new Integer(progress).toString() + " - b"); 
       } 
      })) { 
       Log.d("TASK", "Failed to post"); 
      } 
     } 
    } 

    protected void updateProgress() { 
     updateProgress(DEFAULT_PROGRESS_INCREMENT); 
    } 

    protected abstract B doTask(A input); 

    public void execute(final A input, final int priority) { 
     EXECUTOR.execute(new Runnable() { 
      @Override 
      public void run() { 
       Thread.currentThread().setPriority(priority); 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         executionListener.onPreExecute(); 
        } 
       }); 
       output = doTask(input); 
       if(!handler.post(new Runnable() { 
        @Override 
        public void run() { 
         Log.d("TASK", "Done"); 
         executionListener.onPostExecute(output); 
        } 
       })) { 
        Log.d("TASK", "Failed to post post"); 
       } 
      } 
     }); 
    } 

    public void execute(final A input) { 
     execute(input, DEFAULT_PRIORITY); 
    } 
} 

ExecutionListener只是覆盖到很像的AsyncTask的方法做同样的UI运行方法的类。该代码使用Runnable对象执行doTask方法,并将更新/结果发送到ExecutionListener中的相应方法。

Thread.currentThread()零件只是为了确保事物在我希望它们的线程上运行。这个问题只在运行一个经常调用的任务时才会显示出来。updateProgress() - 我试图在onProgressUpdate()方法中放置一个线程睡眠,并且这似乎很好解决问题,但显然这不是一个好的解决方案。

它也似乎只有Log.x/System.out有问题 - 我不知道他们中的任何一个的调用频率是否会导致此类问题。我对这个进度特性和记录感到不知所措,所以任何建议都将不胜感激 - 我也发现这很难解释,所以请问你是否需要我澄清任何事情!

回答