【问题标题】:Long Running Tasks in AndroidAndroid 中长时间运行的任务
【发布时间】:2014-09-10 12:37:11
【问题描述】:

我也想ZIP 大的文件,在500MB 附近或在1GB 以上。我用过AsyncTask,但它不适用于这么大的文件。

我应该怎么做才能处理这么长的任务?我还想用 progress bar 更新UI,我该怎么做?

【问题讨论】:

    标签: android file task long-integer


    【解决方案1】:

    为什么不使用Executor? AsyncTask 不是长时间工作的正确方法。你应该基本上使用 java.util.concurrent 包,例如 Executor、ThreadPoolExecutor 和 FutureTask。关于AsyncTask,请参考Android SDK文档。

    AsyncTask 被设计为围绕 Thread 和 Handler 的辅助类,并不构成通用的线程框架。 AsyncTasks 最好用于短时间的操作(最多几秒钟)。如果您需要保持线程长时间运行,强烈建议您使用 java.util.concurrent 包提供的各种 API,例如Executor、ThreadPoolExecutor 和 FutureTask。

    【讨论】:

    • 如果我使用 Executor 类,有什么办法可以在 UI 中显示我长时间运行的任务的进度吗?我的意思是传达任务的进度并在 UI 中进行更新。
    • 当然可以在activity中使用runOnUiThread方法或者制作Handler和post方法。在这两种方法中,它与 AsyncTask 中的 publishProgress 相同。这个链接提到了关于 post 方法。 stackoverflow.com/questions/15136199/…
    【解决方案2】:

    我想压缩大的文件,大约 500MB 或超过 1GB。一世 用过AsyncTask,但对这么大的文件就不行了。

    AsyncTask 不是为长时间任务指定的,而是为只能持续几秒钟的任务指定的。

    我应该怎么做才能处理这么长的任务?我也想更新 带有进度条的 UI,我该怎么做?

    对于长任务通常使用IntentService,它也是直接指定用于此目的,但它无法通过其原生实现方式提供如何与UI Thread通信。

    要解决这个问题,你可以使用ResultReceiver,你可以通过 Intent 传递给 IntentService,然后它应该可以工作了。

    快速基础教程:

    如何创建IntentService

    public class Worker extends IntentService {
    
        public static final int PROGRESS_UPDATE = 324;
        public static final String PROGRESS = "progress";
    
        @Override
        protected void onHandleIntent(Intent intent) {
    
            // Get data from Intent
            ResultReceiver r = (ResultReceiver) intent.getParcelableExtra("key");
            ...
    
            // do your work
    
            ...
    
            // send update to caller Activity
            Bundle data = new Bundle();
            data.putExtra(Worker.PROGRESS, value);
            r.send(Worker.PROGRESS_UPDATE, data);
            ...
        }
    }
    

    如何创建ResultReceiver(例如在你的调用者Activity中):

    private class WorkerReceiver extends ResultReceiver {
    
        public WorkerReceiver(Handler handler) {
           super(handler);
        }
    
        @Override
        public void onReceiveResult(int resultCode, Bundle resultData) {
           super.onReceiveResult(resultCode, resultData);
           if (resultCode == Worker.PROGRESS_UPDATE) {
    
              int progress = resultData.getInt(Worker.PROGRESS);
              // update your UI with current information from Worker
           }
       }
    }
    

    最后,如何执行IntentService

    Intent i = new Intent(this, Worker.class);
    // put some extra data you want
    i.putExtra("key", new WorkerReceiver(new Handler()));
    ...
    startService(i);
    

    最后别忘了将你的 IntentService 添加到 Manifest.xml1

    <service
       android:name=".Worker"
    >
    // here you can also define intent-filter
    </service>
    

    希望它能帮助您解决问题。


    1否则你的 IntentService 永远不会被执行(即使你会启动它)。

    【讨论】:

    • 相比 Executor 类有什么优势(如上所述)?
    • @Aritra 我认为没有什么特别的优势。我认为这些特殊类通常只使用,没有其他方法可以做到这一点,尤其是在 Android 中。在 Android 中,我尝试尽可能多地仅使用 Android 内置类和组件(不是从 Java 派生的)。
    猜你喜欢
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多