如何在不使用 runOnUiThread() 的情况下在服务中创建/运行 AsyncTask

发布于 2024-09-14 07:39:36 字数 233 浏览 9 评论 0原文

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

I have a Service that creates AsyncTasks for downloading files. In activities, we create Runnables or Threads that we pass to Activity.runOnUiThread(). I can't access that method from a service, so how do I use AsyncTask correctly, (do heavy work without blocking the UI Thread)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

记忆で 2024-09-21 07:39:36

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

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,服务仍然不知道 UI 的外观)。

If your service is only called from your application, and you can make it a singleton, then try this:

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

Now you can directly call methods on your service. So just call downloadFile() to put the service to work.

About your real question of how to update the UI. Notice that this method receives a ProgressListener instance. It could look like this:

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

Now you just update the UI from the activity (not from the service, which remains unaware of how the UI looks like).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文