【问题标题】:How to Create/Run AsyncTask in Service without runOnUiThread()如何在没有 runOnUiThread() 的情况下在服务中创建/运行 AsyncTask
【发布时间】:2010-08-12 02:15:47
【问题描述】:

我有一个Service,它创建AsyncTasks 用于下载文件。在活动中,我们创建Runnables 或Threads 并传递给Activity.runOnUiThread()。我无法从服务访问该方法,那么如何正确使用AsyncTask(在不阻塞 UI 线程的情况下完成繁重的工作)?

【问题讨论】:

    标签: android multithreading blocking android-asynctask android-service


    【解决方案1】:

    如果您的服务仅从您的应用程序中调用,并且您可以将其设为单例,请尝试以下操作:

    public class FileDownloaderService extends Service implements FileDownloader {
        private static FileDownloaderService instance;
    
        public FileDownloaderService () {
            if (instance != null) {
                throw new IllegalStateException("This service is supposed to be a singleton");
            }
        }
    
        public static FileDownloaderService getInstance() {
            // TODO: Make sure instance is not null!
            return instance;
        }
    
        @Override
        public void onCreate() {
            instance = this;
        }
    
        @Override
        public IBinder onBind(@SuppressWarnings("unused") Intent intent) {
            return null;
        }
    
        @Override
        public void downloadFile(URL from, File to, ProgressListener progressListener) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // Perform the file download
                }
            }).start();
        }
    }
    

    现在您可以直接调用服务上的方法。因此,只需致电 downloadFile() 即可让服务正常运行。

    关于如何更新 UI 的真正问题。请注意,此方法接收 ProgressListener 实例。它可能看起来像这样:

    public interface ProgressListener {
        void startDownloading();
        void downloadProgress(int progress);
        void endOfDownload();
        void downloadFailed();
    }
    

    现在您只需从 Activity 更新 UI(而不是从服务,它仍然不知道 UI 的样子)。

    【讨论】:

    • 我认为构造函数public FileDownloaderService () 应该是private。这就是单身人士应该如何工作;-)
    • 几个月前你如何看待自己的代码很有趣,而且对你来说已经很丑了:-O。你是对的,它应该是私人的。但我相信它不会起作用(我的代码在答案中也没有),因为操作系统将使用无参数构造函数来创建服务。对吗?
    • 这只是一个小建议。我是 Android 菜鸟 ;) 但是使用无参数构造函数创建服务有什么问题?据我所知,onProgressUpdate 来自 AsyncTask 可以更新 UI,所以也许它会是一个更好的解决方案。
    • 如果您要直接调用Service 方法,您不妨将其设为通用Java 对象,因为您完全绕过了Service 的要点。您不实例化服务;系统会。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 2012-04-15
    • 2016-06-22
    • 1970-01-01
    • 2020-07-28
    • 2016-12-03
    相关资源
    最近更新 更多