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.
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.
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.
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.
(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)
}
}
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With