How to implement a background thread using java.util.concurrent package? - java

This is the code I used first but in latest Android version AsyncTask class is deprecated and
therefore it was not responding and then I used the Thread class but that class is also not working.
I want the same result as I was getting with the AsyncTask class.
I know that I have to use some executor class of java.util.concurrent package but don't know which and how to use it.
Please help me with this thing.
private static final String USGS_REQUEST_URL =
"https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2016-01-01&endtime=2016-05-02&minfelt=50&minmagnitude=5";
EarthquakeAsyncTask task = new EarthquakeAsyncTask();
task.execute(USGS_REQUEST_URL);
private class EarthquakeAsyncTask extends AsyncTask<String, Void, Event> {
#Override
protected Event doInBackground(String... urls) {
// Perform the HTTP request for earthquake data and process the response.
Event result = Utils.fetchEarthquakeData(urls[0]);
return result;
}
#Override
protected void onPostExecute(Event result) {
// Update the information displayed to the user.
updateUi(result);
}
}
private static final String USGS_REQUEST_URL =
"https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2016-01-01&endtime=2016-05-02&minfelt=50&minmagnitude=5";
earthquakeRunnable runnable = new earthquakeRunnable(USGS_REQUEST_URL);
runnable.start();
private class earthquakeRunnable extends Thread{
String urls;
earthquakeRunnable(String url){
this.urls = url;
}
#Override
public void run() {
// Perform the HTTP request for earthquake data and process the response.
Event result = Utils.fetchEarthquakeData(urls);
// Update the information displayed to the user
updateUi(result);
}
}

Here's an example of how you might use an ExecutorService within your Activity/Fragment:
// Create some member variables for the ExecutorService
// and for the Handler that will update the UI from the main thread
ExecutorService mExecutor = Executors.newSingleThreadExecutor();
Handler mHandler = new Handler(Looper.getMainLooper());
// Create an interface to respond with the result after processing
public interface OnProcessedListener {
public void onProcessed(Event result);
}
private void processInBg(final String url, final boolean finished){
final OnProcessedListener listener = new OnProcessedListener(){
#Override
public void onProcessed(Event result){
// Use the handler so we're not trying to update the UI from the bg thread
mHandler.post(new Runnable(){
#Override
public void run(){
// Update the UI here
updateUi(result);
// ...
// If we're done with the ExecutorService, shut it down.
// (If you want to re-use the ExecutorService,
// make sure to shut it down whenever everything's completed
// and you don't need it any more.)
if(finished){
mExecutor.shutdown();
}
}
});
}
};
Runnable backgroundRunnable = new Runnable(){
#Override
public void run(){
// Perform your background operation(s) and set the result(s)
Event result = Utils.fetchEarthquakeData(url);
// ...
// Use the interface to pass along the result
listener.onProcessed(result);
}
};
mExecutor.execute(backgroundRunnable);
}
Then, wherever you need to trigger your background processing:
processInBg("some_url", true);
Depending on your situation, you'll want to customize your implementation of ExecutorService to better suit your needs.

Related

Android: Calling method from thread

I have a handler for a thread in my MainActivity that calls a method named UpdateGUI.
Both the handler/thread declaration and the method are within the MainActivity.
This is the handler Declaration:
Handler handlerData = new Handler();
private Runnable runnableCode2 = new Runnable() {
#Override
public void run() {
Log.d("Handlers","GET TOTAL RX BYTES: "+Long.toString(res) );
//Some code here that doesn't matter/
UpdateGUI();
}
handlerData.postDelayed(runnableCode2, 1*6000);
}
};
And UpdateGUI is as follows:
public void UpdateGUI(){
Log.d("Updater", "STARTING UPDATE");
//Code that doesn't matter here}
}
From the logger I can see that UpdateGUI() is not being called from the thread. Can you explain why this is happening and how it can be fixed?
Just to clarify. The thread is running,but for some reason it doesn't make the call to UpdateGUI().
You need to atleast run handler once then only it will continuously called from the handler runnable method.
so call handler.post(runnableCode2); once in your code and that will be repeated
handlerData.postDelayed(runnableCode2, 1*6000);
hope this will resolved your issue.
I cant see you starting the Runnable.
Handler handlerData = new Handler();
private Runnable runnableCode2 = new Runnable() {
#Override
public void run() {
Log.d("Handlers","GET TOTAL RX BYTES: "+Long.toString(res) );
//Some code here that doesn't matter/
UpdateGUI();
}
handlerData.postDelayed(runnableCode2, 1*6000);
}
};
// This part is missing
handlerData.postDelayed(runnableCode2, 1000);

Wait for an asynchronous task in asynctask in android

I have an AsyncTask in Android that runs an asynchronous task on a different thread (I don't have a hand on the Thread life but i can give a callback to the task). Is there a way to wait for the asynchronous task to finish to call the postExecute function of the Asynctask ?
Thanks,
I think what you should do here is define a Listener interface, pass a reference to an object implementing that listener to your AsyncTask, and call this object's method from your onPostExecute.
// this is your interface
// create it in its own file or as an inner class of your task
public interface OnTaskFinishListener {
public void onTaskFinish();
}
// add the following code to your task's class
private OnTaskFinishListener mOnTaskFinishListener;
public void setOnTaskFinishListener(OnTaskFinishListener listener) {
mOnTaskFinishListener = listener;
}
// in your onPostExecute method call this listener like this
// this will call the implemented method on the listener that you created
if (mOnTaskFinishListener != null) {
mOnTaskFinishListener.onTaskFinish();
}
// suppose this is where you start your task
MyBackgroundTask task = new MyBackgroundTask();
// set new listener to your task - this listener will be called
// when onPostExecutes completed -> that's what you need
task.setOnTaskFinishListener(new OnTaskFinishListener() {
#Override
public void onTaskFinish() {
// implement your code here
}
});
task.execute(); // and start the task
I'd rather not to implement a busy-waiting strategy. Both AsyncTask can share a Semaphore that keeps one stopped while the other finishes
Init your semaphore
private final Semaphore semaphore = new Semaphore(0);
Pass that object to both tasks
public AsyncTask1(Semaphore semaphore){
this.semaphore= semaphore;
}
doInBackground(){
//do something
semaphore.acquire(); // <- Waiting till the other task finises
}
And Task2
public AsyncTask2(Semaphore semaphore){
this.semaphore= semaphore;
}
onPostExecute(){
//do something
semaphore.release();
}
Task1
private final Callback callback;
public AsyncTask1(Callback callback){
this.callback = callback;
}
doInBackground(){
//do something
while(!callback.isFinished()){
Thread.sleep(WAIT_TIME);
}
}
Task2
private final Callback callback;
public AsyncTask2(Callback callback){
this.callback = callback;
}
onPostExecute(){
//do something
callback.setFinished(true);
}
class Callback{
private volatile boolean finished = false;
public void setFinished(boolean finished){
this.finished = finished;
}
}

Is this a convenient way of running code in a background thread and return a result via a callback executed in the calling thread?

In the last days I have found myself using this approach for asynchronously performing some long operation (several seconds), and then return some value via a callback that must execute on the caller thread, which is typically but not necessarily the UI thread.
public abstract class DoSomethingCallback
{
public abstract void done(Object result);
}
public void doSomething(final Object param, final DoSomethingCallback doSomethingCallback)
{
// Instantiate a handler for the calling thread
final Handler handler = new Handler();
// Start running the long operation in another thread
new Thread(new Runnable() {
#Override
public void run() {
// Do a long operation using "param" as input...
Object result = longOperation(param);
// Return result via a callback, which will run in the caller thread
handler.post(new Runnable() {
#Override
public void run() {
doSomethingCallback.done(clearBytes);
}
});
}
}).start();
}
This seems to work pretty well and is very simple to use. However, I somehow suspect it might have some problems I'm not aware of. So the question is, what are the potential issues of this approach? What are better alternatives than manually creating and running a thread? I'm seeking for simplicity and robustness.
The only problem is that such approach breaks encapsulation: the second thread not only computes the result, but also dictates what the caller thread should do with it. So I'd better refactor your code as follows:
public abstract class DoSomethingCallback {
final Handler handler = new Handler();
public void post(final Object result) {
handler.post(new Runnable() {
#Override
public void run() {
doSomethingCallback.done(result);
}
});
}
public abstract void done(Object result);
}
public void doSomething(final Object param, final DoSomethingCallback doSomethingCallback) {
// Instantiate a handler for the calling thread
final DoSomethingCallback handler = new DoSomethingCallback () {
void done(Object result) {
...
}
};
// Start running the long operation in another thread
new Thread(new Runnable() {
#Override
public void run() {
// Do a long operation using "param" as input...
Object result = longOperation(param);
// Return result via a callback, which will run in the caller thread
handler.post(result);
});
}
}).start();
}

Android - Lost my way in this multithreaded approach - pass data and thread execution to higher hierarchy object

I really cannot think anymore, somehow I am almost at the end but now I hope, this will not be a dead-end-street.
I want to pass data from a inherited thread object back to my parent object.
And also return to main thread all in one.
Here is my Parent-Object
public class ControllerBase implements IController , IHandleRequestOnChange, IHandlesCustomTimer{
private QueueWorkerThread _QueueWorker;
// some other vars and methods
// ctor and so on .....
// initializer
public void init(){
// some other code
_QueueWorker = new QueueWorker();
_QueueWorker.SetEventListener(this); // i want to announce this object from _QueueWorker
_QueueWorker.start() // starts the thread
// other initializations
}
#Override
public void OnQueueWorkerReady(DataToPass){
// from IHandleRequestOnChange
// ALL INSIDE THIS CODE SHALL BE PROCESSED IN UI THREAD. BUT HOW ?
DataReceived dataRec = new DataReceived();
dataRec = this.Request(DataToPAss);
this.ApplyDataToUIControls(dataRec);
}
}
Here is my QueueWorkerThread :
public class QueueWorkerThread extends Thread implements IRequestQueueProcessed{
// ctor
public QueueWorkingThread(){
super();
}
// other variables and methods
IHandlesRequestOnChange _Listener;
public void Enque(DataToPass Data){
this.add(Data);
}
public void SetEventListener( IHandlesRequestOnChange pEventListener) {
this._Listener = pEventListener;
#Override
public void run(){
// here a LinkedBlockingQueue is polled
// AND UNDER SOME CONDITIONS I WANT TO PASS THE POLLED DATA BACK TO
// THE PARENT OBJECT AND RETURN TO MAIN THREAD. HOW CAN I ACHIEVE THIS?
if(AcertainConditionIsMet == true){
// I want to return to UI thread
this.OnQueueWorkerReady(the_polled_data)
}
// and this thread shall proceed and do some other stuff......
}
#Override
public void OnQueueWorkerReady(TableToPass Data){
// of interface IRequestQueueProcessed
//
// calling parents callback via interface-casting
((IHandleRequestOnChange)_Listener).OnQueueWorkerReady(null, Data);
// this passes execution AND DATA to my parent object BUT I do not return to main thread
}
}
I think you must share your handler in the application object to be able to pass data back in handler's message. You could have for instance:
public class MyApplication extends Application {
private Handler handler;
public Handler getHandler(){ return handler;}
public void setHandler(Handler handler){ this.handler = handler;}
private static MyApplication instance;
public static MyApplication getMyApplication(){return instance;}
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
}
Notice the static method to be able to retrieve the application object without a context (like in your thread).
I suppose if you want to update your UI you should be inside some activity context, so in your activity, you declare the handler:
private Handler handler;
inside onCreate(), you can instantiate and store the handler in the app object:
handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//In here you can do your UI update using the references to the views
}
};
((MyApplication)getApplication()).setHandler(handler);
EDIT:
You can now get an instance of your app object from your thread using the public static method..
Hope it helps.

How to get the variables out of a new thread?

How can i get the variables out of a new thread created with:
public class ParseJson
{
public static String parsejson(String strHttpGet)
{
Thread thread = new Thread(new Runnable()
{
public String run(String strHttpGet)
{
String decodeJson = "someJson";
return decodeJson;
}
});
thread.start();
}
}
I mean how can i get back the decoded json to my function parseJson and give it back to my function call String decodedJson = ParseJson.parseJson(strHttpGet);?
In android, which you have tagged this question as, it would be simpler to use AsyncTask for this situation, because when you override the onPostEXecute method you can put in all sorts of things:
update the UI
send intents and messages
access variables of the parent class if the AsyncTask class is defined inside it.
class MyClass {
Button b;
boolean flag = false;
// Stuff
class MyAsyncClass extends AsyncTask {
// All the stuff, core work in doInBackground
#Override
void onPostExecute(/*vars*/) {
b.setText("Done");
flag = true;
}
}
}
General principles for using AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html
tutorial: http://samir-mangroliya.blogspot.co.uk/p/android-asynctask-example.html
tutorial: http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/
You can't return a value from a Thread in Java. Actually, run() doesn't have a return type.
You could use a shared custom Object that will hold the result. Declare it as final, so you can access it in the anonymous subclass (that would be equivalent to passing a reference to the subclass), and just call a setter on it when the work is done.
public class ParseJson {
public static String parsejson(final String strHttpGet) {
final StringHolder ob = new MyObject();
Thread thread = new Thread() {
public String run() {
String decodeJson = "someJson";
ob.setResult(decodeJson);
}
};
thread.start();
}
private static class StringHolder (){
private String result;
public String getResult() { return result; }
public void setResult(String r) { result = r; }
}
}
I'm not sure I understood why you said get back the decoded json to my function parseJson and give it back to my function call. Do you mean you'll just wait in that function until the Thread is finished? If that's what you want (again, why start a Thread?), you could use Thread.join().
Although if you want to get notified when the Thread finishes, you should indeed look into another option. Neil and Waqas have given good approaches.
You may even use an Observer/Observable pattern for this.
You could use a Future
public class Json {
private static final ExecutorService executor = Executors.newCachedThreadPool();
public static String parse(final String strHttpGet)
throws TimeoutException, InterruptedException, ExecutionException {
Future<String> jsonTask = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
String decodeJson = decodeJson(strHttpGet);
return decodeJson;
}
private String decodeJson(String strHttpGet) {
// TODO do actual parsing
return null;
}
});
// Allow the parsing to take one second
return jsonTask.get(1, TimeUnit.SECONDS);
}
}

Categories