如何使用android实现带有FutureTask或BackgroundTask的.get功能?

Moi*_*han 16 java multithreading android android-library

我正在制作一个安卓库.在我的库中,我想允许用户在后台或主线程中执行特定任务.

我想做这样的事情.

第一种情景

MyLibabry.with(context)
     .performSomeTask(<params>)
     .execute();
Run Code Online (Sandbox Code Playgroud)

当用户编写上述代码段时.任务应该在后台执行.所以我将使用任何监听器返回任务的结果.

现在考虑下面的代码段.

第二种情景

Result result = MyLibabry.with(context)
     .performSomeTask(<params>)
     .get();
Run Code Online (Sandbox Code Playgroud)

现在,当用户在语句末尾附加get()时.该任务应该在主线程上执行并阻止其他线程.这就是结果立即初始化的原因.

所以我的问题是我如何实现如果用户附加.get()的功能,那个线程performSomeTask()应该在主线程上运行.否则在后台.

注意:不要专注于返回结果.我将在Java Generics中实现它.我想知道的是如何使代码可重用,以便当用户只附加.get()它时将在主线程上运行.否则相同的代码应该在后台运行.我不想写重复的代码.

您可以参考现有的库.

  • AsyncTask - 用于执行后台任务的Android官方.
  • ION - 用于下载/上传文件

所以两个库具有相同的功能,并且还有更多的库可以做同样的事情,我想做同样的事情.

如果有人为我提供一个小例子,那就太好了.

Gen*_*mes 6

(我希望,你在上面的例子中用返回的值来澄清)所以这是你的任务的几种单一解决方案.仔细查看新线程中的运行任务.你需要在后台ThreadPool中开始你的动作....

注意!(我希望你澄清使用后台线程.例如,使用上面的函数.execute() - 不会启动新的线程,只是在静态ThreadPool中将新任务从BlockingQueue执行)

接下来是什么?使用函数.get()在MainThread中执行任务,您需要在当前操作循环中发布此任务.你会帮助Handler和Looper.回答你的问题,你应该知道,你只有一种方法来完成这项任务.使用方法.execute()在后台线程中启动操作,并使用方法.get()将新任务启动到Handler.就这些!


如果你想了解一些实现的例子,有很多种解决方案.我只是使用Handler和HandlerThread发布单一内容来低估这个例子的工作.

public class MyLibrary extend HandlerThread {

    private static Handler backgroundHandler;
    private static Handler foregroundHandler;
    private static MyLibrary myLibrary

    private MyLibrary () {
        super(MyLibrary.class.getSimpleName());
        start();
    }

    public static MyLibrary getInstance() {
        if (myLibrary == null) {
            synchronized (MyLibrary.class) {
                if (myLibrary == null) {
                    myLibrary = new MyLibrary();
                }
            }
        }
        return myLibrary;
    }

    public static WorkingTask with (Context context) {
         //Just update, if there are null
         if (foregroundHandler == null) {
              foregroundHandler = new Handler(context.getMainLooper);
         }

         if (backgroundHandler == null) {
             backgroundHandler = new Handler(getLooper);
         }
         return new WorkingTask();
    }

    public void getBackgroundHandler () {
        return backgroundHandler;
    }
    public void getForegroundHandler () {
        return foregroundHandler;
    }
 }


  // ..........


public class WorkingTask  {
   private Runnable workingRunnable;

   public performTask (Runnable run) {
       this.workingRunnable = run; 
       return this;
   }

    public void execute () {
       MyLibrary.getInstance().getBackgoundHandler()
          .postRunnable(workingRunnable)
    }

    public void get () {
       MyLibrary.getInstance().getForegroundHanlder()
          .postRunnable(workingRunnable)
    }
}
Run Code Online (Sandbox Code Playgroud)