Async Task reset the List to null when using runOnUiThread - java

#Override
protected List<String> doInBackground(String... urls) {
JPOSeReprintPreview.this.runOnUiThread(new Runnable() {
#Override
public void run() {
myReceipt reprintReceipt = new myReceipt ();
lstOutput= reprintReceipt.saveReprint(muncID);
if(lstOutput.size()==0 || lstOutput==null){
System.out.println("Failed Sending data");
}
}
});
return lstOutput;
}
#Override
protected void onPostExecute(List<String> response) {
if(response.get(0).equals("SUCCESS")){ } }
My list lstOutput Reset to null when accessing the onPostExecute.. im having invalid index exception at my onPostExecute.. why this is happening?

You post the Runnable to UI Thread in doInBackground() which results in pointless AsyncTask.
lstOutput is retuned before it is updated so it is always null.
if (lstOutput.size() == 0 || lstOutput == null) will crash if it's null when calling size(). Should check for null in first place.
The intention of your code is unclear, but you should probably do it like
private final myReceipt reprintReceipt;
public AsyncTaskName() {
myReceipt reprintReceipt = new myReceipt();
}
#Override
protected List<String> doInBackground(String... urls) {
return reprintReceipt.saveReprint(muncID);
}
#Override
protected void onPostExecute(List<String> response) {
if (response == null || response.isEmpty()){
System.out.println("Failed Sending data");
return;
}
if(response.get(0).equals("SUCCESS")){
}
}
Edit: if the Handler is created in myReceipt() constructor, move it's creation to onPreExecute() or AsyncTasks constructor if it's called from UI thread.
Anyway, myReceipt.saveReprint() method shouldn't use a Handler if it's executed in AsyncTask, so there's something totally wrong with your design.

Related

Debugging an AsyncTask

I have the created the following Async function-
private class CustomAsyncUtil extends AsyncTask<String, Void, String> {
private void CreateDocument(){
try
{
//doing some work
}
catch (Exception ex)
{
String exp = ex.getMessage();
}
}
#Override
protected String doInBackground(String[] params) {
if(android.os.Debug.isDebuggerConnected())
android.os.Debug.waitForDebugger();
CustomAsyncUtil objUtil = new CustomAsyncUtil();
objUtil.CreateDocument();
return "some message";
}
#Override
protected void onPostExecute(String message) {
//process message
}
}
I am calling the function like this-
CustomAsyncUtil objUtil = new CustomAsyncUtil();
objUtil.execute();
To be debug I have added if(android.os.Debug.isDebuggerConnected()) inside doInBackground() but I don't get a break point inside CreateDocument(). Any idea what I am doing wrong?
When you call
CustomAsyncUtil objUtil = new CustomAsyncUtil();
objUtil.CreateDocument();
you are calling CreateDocument() on a different async task object. If you want to call this helper method inside the same async task, then just call it directly:
CreateDocument();
An AsyncTask has a number of lifecycle methods, the most basic of which include:
onPreExecute()
doInBackground()
onProgressUpdate()
onPostExecute()
In general, all the work you do in an async task will originate in one of these entry points, then possibly including helper methods you call from the lifecycle methods.

get result from async task in not activity class

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

Waiting for other AsyncTasks' finish in AsyncTask before processing onPostExecute

I'm getting info from an URL and sending that info to multiple URLs. I'm running it on a "for" in AsyncTask, and at onPostExecute of first AsyncTask, I change a TextView and telling that "All is done" to user.
But the thing is even the children of AsyncTask is continuing to being executed, parent AsyncTask executes its onPostExecute. So I need to wait for them and I'm stuck about it.
So, I have two AsyncTask classes. That's the class I send to websites:
class SendTo extends AsyncTask <Object,Object,String>{
#Override
protected String doInBackground(Object... strings) {
....
}
protected void onPostExecute(String s) {
super.onPostExecute(s);
//update ui for gathered information
}
}
That's the task which I get from websites:
class GetFrom extends AsyncTask <Object,Object,String>{
#Override
protected String doInBackground(Object... strings) {
....
String param = anotherMagicalFunctionThatGivesParamToSend(strings[1]);
for(i = 1; i < websites.length; i++){
publishProgress(websites[i],param);
}
return "";
}
protected void onProgressUpdate(final Object... values) {
super.onProgressUpdate(values);
new SendTo().executeOnExecutor(THREAD_POOL_EXECUTOR, values[1], values[0]);
}
protected void onPostExecute(String s) {
super.onPostExecute(s);
//finish things
}
}
I would recommend use callback in this case.
Create an interface:
public interface MyCallback {
public void readycallback(int index_thread);
}
First class:
class SendTo extends AsyncTask <Object,Object,String>{
private MyCallback cb;
private int i;
public SendTo(int i, MyCallback cb) {
this.cb = cb;
this.i = i;
}
#Override
protected String doInBackground(Object... strings) {
....
}
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (cb != null)
cb.readycallback(i);
//update ui for gathered information
}
}
Second class:
class GetFrom extends AsyncTask <Object,Object,String>{
private boolean[] array_of_completed_tasks = new boolean[websites.length - 1];
#Override
protected String doInBackground(Object... strings) {
....
String param = anotherMagicalFunctionThatGivesParamToSend(strings[1]);
for(i = 1; i < websites.length; i++){
publishProgress(websites[i],param);
}
while(!checkIfAllThreadAreCompleted()) {
//waiting all threads
//you can wait
try {
Thread.sleep(10L);// ten milliseconds
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "";
}
protected void onProgressUpdate(final Object... values) {
super.onProgressUpdate(values);
new SendTo(i, new MyCallback() {
#Override
public void readycallback(int index_thread) {
//this is your ready callback
array_of_completed_tasks[index_thread] = true;
}
}).executeOnExecutor(THREAD_POOL_EXECUTOR, values[1], values[0]);
}
}
private boolean checkIfAllThreadAreCompleted() {
boolean ok = true;
for(i = 0; i < array_of_completed_tasks.length; i++){
ok = ok && array_of_completed_tasks[i];
}
return ok;
protected void onPostExecute(String s) {
super.onPostExecute(s);
//finish things
}
}
Or use Threads for much better coding style. But I really think that using AsyncTask is very ugly methods is real projects.
Run following for loop inside postExecute() of asyncTask as it's anyway not useful running thread inside the thread.
Maintain one global variable which will have count of completed asyncTasks and will be incremented by 1 when each asyncTask will completes it's execution. i.e it will come into postExecute.
In Every postExecute check if that count is equal to number of websites. If that number will be equal to number of websites that basically means all of your data is successfully synced else it's still in process.
It's probably not a good idea to have one AsyncTask simply wait for other AsyncTasks to complete. It makes the code more complex and prevents using that thread in the pool while it's waiting.
If you can, it would be simpler that you launch all AsyncTasks in parallel and have them all call the same method in onPostExecute(). That method would then check if all the results of all the AsyncTasks have been posted and show "All is done" in that case.
If you really want to have one AsyncTask wait in doInBackground() for one or more other AsyncTasks to complete (effectively pausing that background thread), you can use standard Java synchronization mechanisms. I recommend using CountDownLatch.
It's worth noting that synchronizing between background tasks is something that can be achieved quite easily with RxJava rather than using AsyncTask which has been designed for simple use cases.
You can pass you TextView in child asyncTask and update its value in onPost method of child asynchTask .

Android async class returns null

I'm trying to fix this code:
public class Async_Test extends AsyncTask<String, String, String> {
private String Response;
#Override
protected String doInBackground(String... params)
{
String tmp = "something";
return tmp;
}
#Override
protected void onPostExecute(String result) {
Response = result;
}
public String getResponse()
{
return this.Response;
}
}
The problem is the following: The getResponse() method is always null.
The execution code:
public void onClick(View v) {
try{
Async_Test t = new Async_Test();
t.execute("");
showMainText("res: "+t.getResponse());
} catch(Exception e)
{
showMainText(e.toString());
}
}
An async task is asynchronous. More precisely, here is what's going on when you call the execute() method :
a new thread is created.
the doInBackground(...) is executed on this new thread
when doInBackground(...) terminate : onPostExecute is executed on the main thread.
Therefore, when you call showMainText("res: "+t.getResponse()); (it's in the main thread): the onPostExecute didn't run yet and Response is still null.
To see the effect of AsyncTask: you can put a breakpoint on line :
showMainText("res: "+t.getResponse());
and you will see that the displayed text will be "something" (due to the breakpoint : the AsyncTask will have time to be executed.)
To get the result you expect : move the line showMainText("res: "+t.getResponse()); in the onPostExecute

BlackBerry class equivalent to AsyncTask?

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());
}
}
}

Categories

Resources