如何在纯Java代码中复制Android的AsyncTask

6

我正在尝试在纯Java代码中复制Android的AsyncTask遵循的相同逻辑。

为此,我创建了抽象类AsyncTask来实现我的IAsynTask,基本上调用onPreExecute、doInBackground和onPostExecute,还创建了execute方法,在其中进行操作。

因此,要在我的登录过程中使用它,例如,我创建了扩展AsyncTask的LoginTask类,但与我想象中的不同,onPreExecute、doInBackground和onPostExecute的实现似乎并不是强制性的。我做错了什么?

接口:

public interface IAsyncTask {

    public void onPreExecute();
    public void doInBackground();
    public void onPostExecute();

}

类:

public abstract class AsyncTask implements IAsyncTask{

    public void onPreExecute() {

    }

    public void doInBackground(){

    }

    public void onPostExecute() {

    }

    public void execute() {

        onPreExecute();

        new Thread(new Runnable() {
            @Override
            public void run() {

                doInBackground();

                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        onPostExecute();
                    }
                });
            }
        }).start();
    }
}

[编辑]

在我关于JavaFX的问题中,我注意到许多新开发人员在处理线程方面遇到了问题。我想分享一下我为简化JavaFX线程管理所做的工作。我创建了一个基于Android中的AsyncTask类的AsyncTask类,以一种谦虚但有效的方式完成了与Android相同的任务。您可以在Github项目上找到更多信息。


2
为什么看不到Android的源代码? - azizbekian
Android是开源的,你可以直接复制代码... - Karakuri
2
这是它的链接:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.2.2_r1/android/os/AsyncTask.java/ - Ken Wolf
1
实现看起来不是强制性的是什么意思?我对你的问题感到困惑。一切看起来都被调用了。不确定Platform.runLater在做什么,但其余部分看起来很好。 - William Morrison
你可能需要查看Android中LooperHandler的源代码。据我了解,AsyncTask只是一个Handler的前端,而Handler又依赖于Looper。你的实现很可能基于一个 SynchronousQueue<Runnable>。http://docs.oracle.com/javase/1.6.0/docs/api/java/util/concurrent/SynchronousQueue.html - Philip Couling
显示剩余4条评论
2个回答

3

我很抱歉如果我没能清楚地解释我想要的是什么,但是当你们看到我的代码后,你们就会明白。我只是在我的方法中添加了一个抽象标识符,并得到了我想要的结果。这可能看起来像一个新手问题,但我认为它可以用于简化一些简单的操作而不必直接管理线程。

我用Java和Javafx代码重新创建了一个简单的AsyncTask:

创建一个抽象类AsyncTask:

public abstract class AsyncTask {

    abstract void onPreExecute();

    abstract void doInBackground();

    abstract void onPostExecute();

    public void execute() {

        onPreExecute();

        new Thread(new Runnable() {
            @Override
            public void run() {

                doInBackground();

                //Platform.runLater is a javafx code that executes onPost in Main Thread.
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        onPostExecute();
                    }
                });
            }
        }).start();
    }
}

从我们的worker类中扩展它

public class LoginTask extends AsyncTask {

    @Override
    void onPreExecute() {

        //Some code to preexecute in Main Thread
        System.out.println("OnPreExecute - Main Thread: " + Platform.isFxApplicationThread());
    }

    @Override
    void doInBackground() {

        //Some code to execute in background thread as internet requests
        System.out.println("doInBackground - Main Thread: " + Platform.isFxApplicationThread());
    }

    @Override
    void onPostExecute() {

        //Some code to execute in Main thread after background process has done, like update a view
        System.out.println("onPostExecute - Main Thread: " + Platform.isFxApplicationThread());        
    }

}

你可以这样调用它:

LoginTask taskTest = new LoginTask();
taskTest.execute();

你的日志将会是:

OnPreExecute - Main Thread: true
doInBackground - Main Thread: false
onPostExecute - Main Thread: true

但是,你为什么不能只使用AsyncTask呢?只是出于好奇。 - Shaquil Hansford
1
因为它不是一个安卓项目哈哈哈。 - Victor Laerte
@VictorOliveira AsyncTask只是Java代码。顺便说一句,文章写得很好。 - Jared Burrows
AsyncTask 源代码:https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java。 - Jared Burrows

-1

AsyncTask本质上是一个线程。它是在另一个任意线程(但通常是主线程)中启动的线程,执行其任务,然后将后续任务委托给生成它的线程(如我所说,通常是主线程)。

在开发这个项目时,你会遇到一个问题,那就是处理这个线程委托功能的Handler类。Handler是Android的核心特性,允许从非主线程委托任务到创建它的线程中。为了实现类似于Java AsyncTask的功能,你需要添加一个线程委托API,其本质上与Handler相同。


我应该补充一点,由于Android有自己的进程间通信机制,AsyncTask严重依赖于它,因此您需要在项目中复制整个IPC以实现这一点。 - YankeeWhiskey
线程委托不应该太难。基本原则是,“主”线程只需在循环中处理队列中的Runnable对象上的.run()方法。Java内置了可用于此目的的队列。 - Philip Couling
@YankeeWhiskey,你能参考一下关于异步任务 IPC 能力/要求的文档吗?我原以为它们只能在同一个进程内工作。 - Philip Couling
AsyncTask不是线程。AsyncTask被排队到单个或多线程池中执行。AsyncTask更像是一个Runnable。区别很小,但我想提一下。 - William Morrison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接