0

我的 android 应用程序实现数据保护和使用云。 应用程序由 UI 和独立服务(在自己的进程中运行)组成。 我正在使用 IPC(消息和处理程序)在 UI 和服务之间进行通信。

我有下一种情况——在处理数据之前,我需要了解数据大小和数据项计数(我必须枚举联系人、照片等并收集进度的总信息)。

关于问题: 当枚举在服务端开始时(它在线程池中使用 4 个运行线程),我的 UI 冻结了几秒钟(取决于总数据大小)。

有没有人知道任何使 UI 工作良好的方法 - 而不会在这一刻冻结?

更新: 这是我的 ThreadPoolExecutor 包装器,我在服务中使用它来执行估计任务(像 new ThreadPoolWorker(4,4,10) 一样创建):

    public class ThreadPoolWorker {

    private Object threadPoolLock = new Object();
        private ThreadPoolExecutor threadPool = null;
        private ArrayBlockingQueue<Runnable> queue = null;
        private List<Future<?>> futures = null;

    public ThreadPoolWorker(int poolSize, int maxPoolSize, int keepAliveTime){
        queue = new ArrayBlockingQueue<Runnable>(5);
        threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
        threadPool.prestartAllCoreThreads();
    }

    public void runTask(Runnable task){
        try{
            synchronized (threadPoolLock) {
                if(futures == null){
                    futures = new ArrayList<Future<?>>();
                }
                futures.add(threadPool.submit(task));
            }
        }catch(Exception e){
            log.error("runTask failed. " + e.getMessage() + " Stack: " + OperationsHelper.StringOperations.getStackToString(e.getStackTrace()));
        }
    }

    public void shutDown()
    {
        synchronized (threadPoolLock) {
           threadPool.shutdown();
        }
    }

    public void joinAll() throws Exception{
        synchronized (threadPoolLock) {
            try {

                if(futures == null || (futures != null && futures.size() <= 0)){
                    return;
                }

                for(Future<?> f : futures){
                    f.get();
                }
            } catch (ExecutionException e){
                log.error("ExecutionException Error: " + e.getMessage() + " Stack: " + OperationsHelper.StringOperations.getStackToString(e.getStackTrace()));
                throw e;
            } catch (InterruptedException e) {
                log.error("InterruptedException Error: " + e.getMessage() + " Stack: " + OperationsHelper.StringOperations.getStackToString(e.getStackTrace()));
                throw e;
            }
        }
    }

}

这是我使用的启动枚举任务的方式:

estimateExecutor.runTask(contactsEstimate);
4

1 回答 1

0

我必须说您没有提供足够的信息(您怀疑是原因的代码部分......)但根据我的知识和经验,我可以做出有根据的猜测 -

您可能正在执行需要一段时间的 UI 线程(主线程)上执行代码。我也可以猜到这段代码是:查询所有数据的 cotacts/gallery 提供程序..

如果您不知道 -Service回调方法也从主线程(UI线程..)执行,除非您明确地从AsyncTask/另一个线程运行它们,并且查询内容提供者并处理它返回的数据游标也可能是繁重的操作需要从另一个线程执行以不阻塞主 UI 线程。

将执行此昂贵查询的代码删除到另一个线程后 - 您没有理由遇到任何冻结。

于 2013-09-20T16:26:10.193 回答