I haven't used an AsyncTask before neither do I understand some tutorials regarding it so I really don't know how to apply it on a HttpClient execution. Please kindly help me on this kind of implementation here's the initial code made:
public void commandModule(String url) {
try {
HttpClient httpClient = new DefaultHttpClient();
httpClient.execute(new HttpGet(url));
} catch (Exception e) {
}
}
#Override
public void onClick(View v) {
if (checkBox1.isChecked()) {
commandModule("http://192.168.1.102/?command1");
} else {
commandModule("http://192.168.1.102/?command2");
}
if (checkBox2.isChecked()) {
commandModule("http://192.168.1.102/?command3");
} else {
commandModule("http://192.168.1.102/?command4");
}
}
If you know about Thread in java, it will be easy for you to understand the working of Async Task in android. Basically, you can not perform any long running task on the main thread in android. It will block the main main thread and you will get ANR (Applicaton not responding) error. To avoid this you can either use thread or Async task.
Thread has one limitation, you can not update UI thread form any other thread. So, to update the UI you need to send message to main/UI thread using handler. You will have to do this every time you are implementing something using thread.
To simplify, android framework provide Async Task.
So, what ever you should put in the run() method of Thread, should go in doInBackground() method.
public void commandModule(String url) {
new RequestTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,url);
}
private class RequestTask extends AsyncTask<String,Void,Void>{
protected void doInBackground(String... args){
String url=args[0];
try {
HttpClient httpClient = new DefaultHttpClient();
httpClient.execute(new HttpGet(url));
} catch (Exception e) {
}
}
}
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
check this tutorial it will give ideas about your queries http://programmerguru.com/android-tutorial/android-asynctask-example/
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
public void commandModule(String url) {
try {
new RequestTask().execute(url);
} catch (Exception e) {
}
}
#Override
public void onClick(View v) {
if (checkBox1.isChecked()) {
commandModule("http://192.168.1.102/?command1");
} else {
commandModule("http://192.168.1.102/?command2");
}
if (checkBox2.isChecked()) {
commandModule("http://192.168.1.102/?command3");
} else {
commandModule("http://192.168.1.102/?command4");
}
}
private class RequestTask extends AsyncTask<String,Void,Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected void doInBackground(String... args){
String url=args[0];
try {
HttpClient httpClient = new DefaultHttpClient();
httpClient.execute(new HttpGet(url));
} catch (Exception e) {
}
}
#Override
protected void onPostExecute() {
}
}
onPreExecute() – Executed when execute() method is called inside commandModule() (In short When AsyncTask is triggered).
doInBackground() – Executed when onPreExecute() completed executing. Al the long task are handled here
onPostExecute() – Background job is finished
Related
I use async task to get data from my database.
i have :
public class BackgroundDatabaseTask extends AsyncTask<String, Void, String> {
String jsonData;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... values) {
String jsonData = Driver.returnJsonDataFromDatabase(values[0]);
return jsonData;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
jsonData = result;
}
}
And in other class i use it like:
private static String returnJsonDataBackgroundTaskExecute(String fromWhichTableGetData) {
try {
return new BackgroundDatabaseTask().execute(fromWhichTableGetData).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return "Error in BackgroundDatabaseTask";
}
But get() block my main thread.
So, how can I get result of my async task in other non activity class?
I want run this in not activity class, so my class don't have onCreate method, but I have activity from my MainActivity class.
UPDATE:
Now i solve this problem using thread but it is a good solution?
Runnable runnable = new Runnable() {
#Override
public void run() {
listOfDataFromDatabase = GetterDataFromDatabase.returnJsonDataBackgroundTaskExecute(tableNameFromWhichIGetData);
}
};
Thread thread = new Thread(runnable);
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
now i have acces to this varaible listOfDataFromDatabase in other method .
An AsyncTask creates a new thread to perform a task that takes a long time. You start this thread by calling execute(). However, you immediately call get() which waits for the task to finish. This completely destroys the whole point of using an AsyncTask in the first place.
Instead, you should remove the call to get() and do the final processing in onPostExecute(). You can do whatever you wish in this method. There is absolutely no requirement that you use the Activity in any way. You can provide data to other classes if that is what you wish.
You can define an interface in your Asynctask class then implement it where ever you want and get the result from that interface callback
MyTask extends AsynTask{
public interface DataListener{
void onDataReceived(String result);
}
/// then on your onPostExecute method , get an instance of the interface then push the result to the interface method
dataListener.onDataReceived(result);
}
maybe this will help
I'm struggling with a network connection class I've created. The result of the Runnable I create returns a JSON object that contains all the information needed from the server. The thread runs, and receives the data perfectly, but of course, the program keeps running in the meantime, which results in a JSONException as being NULL.
I created a class called NetworkManager, which has the following method (jsonResponse is initialized at the beginning of the class)
JSONObject jsonResponse;
public void createNetworkThread(Context context, final String requestURI, final RequestBody formParameters) {
Runnable runnable = new Runnable() {
#Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(requestURI).post(formParameters).build();
Response response = null;
try {
response = client.newCall(request).execute();
String stringResponse = response.body().string();
NetworkManager.this.jsonResponse = new JSONObject(stringResponse);
// This works perfectly, "message" is received and printed to the log //
Log.d("Net", NetworkManager.this.jsonResponse.getString("message"));
} catch (IOException e) {
Log.d("Net", "Failed");
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
The above is called from the Activity, as:
Net.createNetworkThread(SignupActivity.this, requestURI, formVars);
JSONObject jsonResponse = Net.jsonResponse;
The JSON object jsonResponse is returning as NULL because the Thread is still accessing the server for the response.
I need to figure out how to stop the jsonResponse Object from being populated by Net.jsonResponse until the thread completes in order to stop it from returning NULL.
Any help?
I would only agree to the comments on your question and let you know, what you can do here.
If you are creating a thread just to get of the main UI thread to do the Network call you probably want to use OkHttp feature which allows you to get the Network call off the thread and provides you with callbacks to get the result something like this. you can check some example here
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
}
#Override
public void onResponse(Response response) throws IOException {
// this is the callback which tells you the network call was successful, If like to make some changes to UI, you should call `runOnUiThread`.
"YourClassName".this.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
});
or you can use AsyncTask which also gets your job done off the main UI thread and gives you the result in the callbacks.
private class MyTask extends AsyncTask<Void, Void, Void> {
//you can change the Type Void, Void, Void here to something which you want
//First Void belongs to doInBackground(Void... avoid)
//Second Void belongs to onProgressUpdate(Void... progress)
//Third Void belongs to onPostExecute(Void result)
// you may change these as you fit,
//when you want to start this class with your argument you can do something like this.
//new MyTask().execute("your argument to doInBackground");
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// this is the method where you provide your implementation for doing a task off the main UI thread.
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// in this callback you are back in the main UI thread to make changes to UI depending on your response
}
}
here is an example of AsyncTask
If you want to offload the main thread, you should consider that the parallel task could finish it's execution after, generally speaking, any amount of time. Sure, you can wait in the main thread for the child thread to finish (using 'join()'), though this is kind of questionable in terms of speed gain.
Anyway, answering your question:
I need to figure out how to stop the jsonResponse Object from being
populated by Net.jsonResponse until the thread completes in order to
stop it from returning NULL.
I suggest you change
public void createNetworkThread(...
to
public Thread createNetworkThread(...
{
...
Thread thread = new Thread(runnable);
thread.start();
return thread;
}
And consequently
Thread t = Net.createNetworkThread(SignupActivity.this, requestURI, formVars);
t.join(); // Wait until 't' finishes -- try-catch is omitted for the sake of demo.
JSONObject jsonResponse = Net.jsonResponse;
This, apparently, opens question of performance, since main thread will be effectively completely blocked by 't.join()' until the child thread will finish.
Answering the question in the topic: in Java 8 you can use lambda functional interface like this:
package multithreaded;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Multithreaded {
public static void main(String[] args) throws Exception {
Logger logger = LoggerFactory.getLogger("Main");
Worker<String, String> worker = new Worker<String, String>(
(String s) ->
{ // This is actual call-back code.
// It will be called by method 'apply' of interface 'Function' in the 'Worker'.
// It will accept String parameter and pass it in this block as variable 's'
logger.info("Embrace the beauty and power of Java 8! "+s); // yes, we can use local variables of the parent thread.
return "Call-Back "+s;
}
);
logger.info("Application starts new Worker.");
worker.start();
logger.info("Worker is running in background.");
Thread.currentThread().sleep(500); // Simulate some activity here...
logger.info("Result is unpredictable (could be null): "+worker.getResult());
// Wait here until worker is fully finished
worker.join();
logger.info("Result is predictable: "+worker.getResult());
}
}
Worker.java:
package multithreaded;
import java.util.function.Function;
public class Worker<T extends String, R extends String> extends Thread {
private final Function<T, R> callBack;
private volatile R result;
public Worker(Function<T, R> callBack)
{ this.callBack = callBack; }
#Override
public void run()
{
try{
int i = (int)(Math.random()*1000);
// simulate some activity unpredictable in terms of duration
Thread.currentThread().sleep(i);
// After "activity" is finished -- call the call-back function and get result in local variable.
// (Synchronization ommited for the sake of simplicity)
result = this.callBack.apply((T)("Result "+i)); // now let's call the call-back function and save the result in local variable.
}
catch(InterruptedException e)
{e.printStackTrace();}
}
// Getter for the local variable, populated by call-back function.
// (Synchronization ommited for the sake of simplicity)
public R getResult()
{ return this.result; }
}
Running above code multiple times, you will notice that from the parent thread's perspective the result is still unpredictable until the child thread is completely finished.
P.s. I suggest you re-think entire logic of data processing in your app and consider re-factoring towards entirely independent multi-threaded processing (perhaps using producer-consumer logic).
How can I run a function synchronously in another thread, meaning the main UI thread has a function that calls another function that does its work on another thread, waits for the new thread to finish and returns the value:
int mainFunction() //this function is on the main UI thread
{
return doWorkOnNewThread();
}
int doWorkOnNewThread()
{
//do work on new thread
}
You can use Async task for this, even though it's asynchronous. You can use the callbacks onPostExecute and onProgressUpdate to update the values as needed. I should also note you probably don't want to do this synchronized as it will block your UI thread which could cause an application not responding alert depending on how long the calculation takes.
There are few ways of executing code in separate threads.
You can read about this here
I think that AsyncTask will do what you want.
protected void onPreExecute () {
// you can show some ProgressDialog indicating to the user that thread is working
}
protected Type doInBackground(String... args) {
doWorkOnNewThread()
// do your stuff here
}
protected void onPostExecute(Type result) {
// here you can notify your activity that thread finished his job and dismiss ProgressDialog
}
You have two way:
1. Asyntask
2. Handler
public static <T> T runSynchronouslyOnBackgroundThread(final Callable<T> callable) {
T result = new Thread() {
T callResult;
#Override
public void run() {
try {
callResult = callable.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
T startJoinForResult() {
start();
try {
join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return callResult;
}
}.startJoinForResult();
return result;
}
i have one problem with handling the thread in android ,in my class i have to create one thread which create some UI after that thread finish i will get some value ,here i want to wait my Main Process until the thread complete it process but when i put wait() or notify in Main process thread does not show the UI in my application
this is sample code
protected void onCreate(Bundle savedInstanceState) {
downloadThread = new MyThread(this);
downloadThread.start();
synchronized(this){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String test=Recognition.gettemp();
public class MyThread extends Thread {
private Recognition recognition;
public MyThread(Recognition recognition) {
this.recognition = recognition;
// TODO Auto-generated constructor stub
}
#Override
public void run() {
synchronized(this)
{
handler.post(new MyRunnable());
}
notifyAll();
}
}
}
static public class MyRunnable implements Runnable {
public void run() {
settemp(template);
}
}
}
public static String gettemp() {
return template;
}
public static void settemp(String template) {
Recognition.template = template;
}
}
here i will not use AsynTask because i have some other issue that is reason i choose Thread even now the problem is Thread wait do any give the suggestion for this
- Use java.util.CountDownLatch , here you can let some process complete before kick-off some other code.
- countDown() and await() will be of use to you.......
See this example of CountDownLatch:
http://www.javamex.com/tutorials/threads/CountDownLatch.shtml
Use the logic below :-
new Thread(new Runnable()
{
#Override
public void run()
{
//do the code here such as sending request to server
runOnUiThread(new Runnable()
{
#Override
public void run()
{
//do here the code which interact with UI
}
});
}
}).start();
What do you expect to happen if you freeze the main UI thread?
You should be using an ASyncTask to show your gui in the onPreExecute method, do the task in doInBackground then display the result in the onPostExecute method.
As a plus you can update the progress using onProgressUpdate too.
This is not an solution just a advice on how should you structure you activity/app.
You should never block the main thread by calling wait() its a bad user experience and not advised. It would also case a Android Not Responding (ANR) popup.
You can have you thread updating the UI from the background and let the UI to be responsive. Load the static part of your UI in onCreate() and then fire up the background thread to lazy load rest of the component.
My requirement is to have a thread that maintains a socket connection between a BlackBerry device and a server and exchanges commands, similar to request and response.
My problem is that I need to have this thread running in the background all the time and keep the UI available to the user. So, when there is a command from the server, this thread parses it and updates the UI and also if there's an action from the BlackBerry user, it sends it to the server and the server in turn handles it.
I developed the same application in Android using AsyncTask and it's working well. But in BlackBerry, as there's no such class, I used the invokeLater() option. The communication works fine between the server and the BB device, but the UI is frozen on the BlackBerry.
Anyone have any idea how to get this right?
Vishal is on the right track, but a little more is needed to match Android's AsyncTask. Since enums and generics aren't available with Java 1.3 on BlackBerry, you can't match the Android API perfectly.
But, you could do something like this (not tested ... this is just a starting point for you):
import net.rim.device.api.ui.UiApplication;
public abstract class AsyncTask {
public static final int FINISHED = 0;
public static final int PENDING = 1;
public static final int RUNNING = 2;
private int _status = PENDING;
private boolean _cancelled = false;
private Thread _worker;
/** subclasses MUST implement this method */
public abstract Object doInBackground(Object[] params);
protected void onPreExecute() {
// default implementation does nothing
}
protected void onPostExecute(Object result) {
// default implementation does nothing
}
protected void onProgressUpdate(Object[] values) {
// default implementation does nothing
}
protected void onCancelled() {
// default implementation does nothing
}
protected void onCancelled(Object result) {
onCancelled();
}
public final int getStatus() {
return _status;
}
public final boolean isCancelled() {
return _cancelled;
}
public final boolean cancel(boolean mayInterruptIfRunning) {
if (_status == FINISHED || _cancelled) {
return false;
} else {
_cancelled = true;
if (mayInterruptIfRunning && _status == RUNNING) {
// NOTE: calling Thread.interrupt() usually doesn't work
// well, unless you don't care what state the background
// processing is left in. I'm not 100% sure that this is how
// Android's AsyncTask implements cancel(true), but I
// normally just cancel background tasks by letting the
// doInBackground() method check isCancelled() at multiple
// points in its processing.
_worker.interrupt();
}
return true;
}
}
protected final void publishProgress(final Object[] values) {
// call back onProgressUpdate on the UI thread
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
onProgressUpdate(values);
}
});
}
private void completeTask(final Object result) {
// transmit the result back to the UI thread
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
// TODO: not sure if status should be FINISHED before or after onPostExecute()
_status = FINISHED;
}
});
}
public AsyncTask execute(final Object[] params) throws IllegalStateException {
if (getStatus() != PENDING) {
throw new IllegalStateException("An AsyncTask can only be executed once!");
} else {
try {
onPreExecute();
_worker = new Thread(new Runnable() {
public void run() {
try {
// run background work on this worker thread
final Object result = doInBackground(params);
completeTask(result);
} catch (Exception e) {
// I believe if Thread.interrupt() is called, we'll arrive here
completeTask(null);
}
}
});
_status = RUNNING;
_worker.start();
} catch (Exception e) {
// TODO: handle this exception
}
}
return this;
}
}
Also, it's important to keep in mind the Threading Rules for Android's AsyncTask, which apply to the above implementation, too:
Threading rules
There are a few threading rules that must be followed
for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done
automatically as of JELLY_BEAN.
The task instance must be created on
the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result),
doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a
second execution is attempted.)
You can create a Class that extends my implementation of class AsyncTask. Good Luck :)
Here the methods onPreExecute, onPostExecute are executed on UI thread and doInBackground is called on worker thread. Since onPreExecute, onPostExecute are abstract you can override them and provide your implementation like showing and dismissing progress dialog.
The sequence in which methods get's executed is
1) onPreExecute
2) doInBackground
3) onPostExecute
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
public abstract class AsyncTask {
Runnable runnable;
Thread threadToRun;
public abstract void onPreExecute();
public abstract void onPostExecute();
public abstract void doInBackground();
public void execute() {
try {
runnable = new Runnable() {
public void run() {
// TODO Auto-generated method stub
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
// TODO Auto-generated method stub
onPreExecute();
}
});
doInBackground();
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
// TODO Auto-generated method stub
onPostExecute();
}
});
}
};
threadToRun = new Thread(runnable);
threadToRun.start();
} catch (Exception e) {
// TODO: handle exception
Dialog.alert("Async Error Occured. " + e.toString());
}
}
}