如何在没有runOnUiThread()的情况下在服务中创建/运行AsyncTask

时间:2010-08-12 02:15:48

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

我有Service创建AsyncTask用于下载文件。在活动中,我们会创建传递给Runnable的{​​{1}}或Thread。我无法从服务访问该方法,因此如何正确使用Activity.runOnUiThread(),(在不阻止UI线程的情况下做大量工作)?

1 个答案:

答案 0 :(得分:2)

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

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();
}

现在您只需从活动更新UI(而不是从服务中更新UI,该服务仍然不知道UI的外观)。