Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement .get feature with FutureTask or BackgroundTask using android?

I am making one android library. And in my library i want to allow a user to perform a particualar task either in background or in main thread.

I want to do something like this .

1st Scenario

MyLibabry.with(context)
     .performSomeTask(<params>)
     .execute();

When user write the above snippet code. the task should be perform in background. So i will return the result of task using any listeners.

And now consider the below snippet code.

2nd Scenario

Result result = MyLibabry.with(context)
     .performSomeTask(<params>)
     .get();

Now, When user attach the get() at the end of the statement. The task should be execute on main thread and block other threads . That's why result is initialized immediately.

So My Question is how can i implement the feature that if user attached the .get(), that thread in performSomeTask() should run on main thread. otherwise in background.

Note : Don't focus on returning result. I will implement it in Java Generics. What i want to know is how to make code reusable so that when user only attach .get() it will run on main thread. Otherwise that same code should run on background. I don't want to write repeated code.

You can refer the existing library.

  • AsyncTask - Android official for performing background task.
  • ION - for download/upload file

So two library have that same feature, and there are many more library which does the same, and i want to do the same.

It will be great if some one provide me a small example for this.

like image 932
Moinkhan Avatar asked Jun 28 '16 08:06

Moinkhan


People also ask

What is the best way to execute code in the background in a separate thread?

To specify the thread on which to run the action, construct the Handler using a Looper for the thread. A Looper is an object that runs the message loop for an associated thread. Once you've created a Handler , you can then use the post(Runnable) method to run a block of code in the corresponding thread.

How is handler class used for background thread processing?

Purpose of the Handler class. A Handler object registers itself with the thread in which it is created. It provides a channel to send data to this thread, for example the main thread. The data which can be posted via the Handler class can be an instance of the Message or the Runnable class.


2 Answers

(I hope, you clarify with returning values in the examples above) So this is several type of single solution for your task. Look closely to running task in new thread. You need to start you action in background ThreadPool....

Note! (Also I hope you clarify with using background Threads. For example, using your code above with function .execute() - doesn't start new Thread, but just putting new task for executing from BlockingQueue in static ThreadPool)

So what is next? Using function .get() for executing task in MainThread, you need to post this task in current action loop. And you will help Handler and Looper. And answering you question, you should know, that you have only one way for this task. Starting action in background thread using method .execute() and starting new task to Handler using method .get(). That is all!


If you want know about some examples of realization, there are many kinds of solution. I just post single using Handler and HandlerThread for understating work of this example.

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)
    }
}
like image 158
GensaGames Avatar answered Sep 20 '22 12:09

GensaGames


You have to use Future Task class to do task in background.

1st Scenario If the task is in background then, you will return using result interface method.

2nd Scenario If the task is in foreground then, you will return output directly to calling class.

Sample code for execute()

public void execute() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Future future = mExecutorService.submit(mCursorBinderTask);
                Log.d("asd", "onCreate: started ");
                while (true) {
                    if (future.isDone()) {
                        if (mResultListener != null) {
                            try {
                                mResultListener.onResult(future.get());
                            } catch (InterruptedException e) {
                                mResultListener.onResult(null);
                            } catch (ExecutionException e) {
                                mResultListener.onResult(null);
                            }
                        }
                        break;
                    }
                }
            }
        }).start();
    }

Sample code for get()

public ArrayList<T> get() throws ExecutionException, InterruptedException {
        return mCursorBinderTask.call();
    }
like image 27
Kishan S. Rakholiya Avatar answered Sep 20 '22 12:09

Kishan S. Rakholiya