【问题标题】:IntentService is hanging UI in androidIntentService 在 android 中挂起 UI
【发布时间】:2013-05-21 08:01:49
【问题描述】:

在 IntentService 中,我使用 ThreadPoolExecutor poolSize 8 和 maxPoolSize 10。无论何时启动 Service,都会影响 UI。在 runTask() 方法中,我将任务添加到线程池。

private ThreadPoolExecutor threadPool = null;
private final LinkedBlockingQueue<Runnable> threadsQueue =
  new LinkedBlockingQueue<Runnable>();
private Collection<Future<?>> futures = new LinkedList<Future<?>>();

public MyService(String name) {
 super(name);
 threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime,
     TimeUnit.SECONDS, threadsQueue);
}

public void runTask(Runnable task) {
  futures.add(threadPool.submit(task));
}

/**
* When ever we call this method it will hold the main thread untill the tasks
* in thread pool are completed.
*/

public void waitForThreadPool() {
 for (Future<?> future : futures) {
   try {
     future.get();
   } catch (InterruptedException e) {
     e.printStackTrace();
   } catch (ExecutionException e) {
     e.printStackTrace();
   } catch (Exception e) {
     e.printStackTrace();
   }
 }
}

【问题讨论】:

  • "在 IntentService 中,我使用 ThreadPoolExecutor poolSize 8 和 maxPoolSize 10。" ——这是一个可怕的想法。永远不要在IntentService 中做超出onHandleIntent() 的事情,例如设置自己的线程池。如果您想在Service 中拥有一个线程池,请使用常规的Service。除此之外,StackOverflow 是用于编程问题的,你还没有问过问题。
  • @CommonsWare 我想,它挂了,正如标题所暗示的那样
  • 我也遇到了同样的问题,但得到了很好的解决方案,请按照我的回答stackoverflow.com/a/44432310/4997704

标签: android performance intentservice threadpoolexecutor


【解决方案1】:

我建议在服务中创建一个单独的线程(服务在 UI 线程中运行),它将等待执行程序完成。我就是这样弄的

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{

    // check what you have to here
    // ...

    if (state == State.IDLE) {
        state = State.IN_PROGRESS;

        new Thread()
        {
            @Override
            public void run()
            {
                performAndWait();
                stopSelf();
            }
        }.start();
    }

}

private void performAndWait() {

    //add tasks to ExecutorService

    for (String key : this.data.keySet()) {
        final Job pending = new Job(this.context, key, this.data.get(key));
        try {
            this.service.submit(pending);
        } catch (RejectedExecutionException e) {
            // all rejected stuff go here for the next attempt when all finishes
            this.rejected.add(pending);
        }
    }

    // wait

    service.shutdown();
    try {
        service.awaitTermination(3600, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

【讨论】:

  • 我正在使用 IntentService,它自己运行一个工作线程,如果我调用 waitForThreadPool() 方法,它将暂停该工作线程。
  • 按照 CommonsWare 的建议,尝试使用服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-08
  • 2014-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多