I have an async task. It runs a sql query.It should go to the onPostExecute automatically, but it does not always go there. THere is no exception.The logs are also fine.
class QueryDbTask extends AsyncTask<String, Void, Cursor> {
protected Cursor doInBackground(String... params) {
....
//sql query
try {
cur=activityObject.execSQL(Query);
}catch (Exception e) {
e.printstacktrace
}
return cur;}
protected void onPostExecute(Cursor result) {
}
Under what conditions onPostExecute would not be called?
i debugged and found that it was not reaching onPost Execute
Can two async task simulataneoulsy?
onPostExecute() would not be called if doInBackground() never finished or if the task was interrupted/cancelled in which case onCancelled() would be called.
You have to put an #Override annotation to onPostExecute() to be called
#Override
protected void onPostExecute(Cursor result) {
....
}
Related
I want to wait for a specific operation to complete before continuing the code flow.
Something like this:
protected void onCreate(Bundle savedInstanceState) {
downloadSomeFiles(); // I want to wait for this operation to finish
Log.d("Download", "Download Complete") //This should run After downloading completed
}
However downloading takes some time and I always end up getting NullPointerException because downloading wasn't completed.
Assume we don't know how long we must wait.
Long running operations on the main thread are never a good idea, as they block the User Interface.
If you want to do this while the application is running, consider using methods from java.util.concurrent package (or coroutines if you want to switch to Kotlin). AsyncTask became deprecated.
Here is a guide: https://www.baeldung.com/java-concurrency
If you want your download to execute in the background even if your application is closed, consider using a Service: https://developer.android.com/guide/components/services
I could only suggest using Asyntask<>
Here's a sample approach for you to understand.
I just wanna comment this but I don't have enough reputation to do it.
AsyncTask<String, String, String> asyncTask = new AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// ... Show a Progress Dialog or anything you want just to indicate that you
// ... are downloading ...
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected String doInBackground(String... strings) {
// ... Do Downloading or anything
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// Post any codes to be followed here ...
Log.d("Download", "Download Complete")
}
}
asynTask.execute();
Create a response callback like so:
public interface ResponseCallback {
void onDownload();
}
Then in your method
downloadSomeFiles(ResponseCallback responsecallback) {
//Download files
responsecallback.onDownload(); //Trigger it
}
Then call it
protected void onCreate(Bundle savedInstanceState) {
downloadSomeFiles(new ResponseCallback() {
#Override
public void onDownload() {
Log.d("Download", "Download Complete");
}
});
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.
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 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
I have an AsyncTask that downloads files in doInBackground() method. I am testing my app before releasing it. When I manually force quit the app and relaunch it, the doInBackground() seems to be invoked, but not onProgressUpdate() and onPostExecute(). My onPostExecute() call methods that cause UI changes.
How can I make sure the onPostExecute and onProgressUpdate() get called? I also see the following warning:
Activity stop timeout for ActivityRecord or Activity destroy timeout for ActivityRecord or Activity idle timeout for ActivityRecord
Code:
public void OnCreate(){
new RefreshMyDashboardTask().execute();
}
private class RefreshMyDashboardTask extends AsyncTask<Void, Void, Long> {
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... params) {
super.onProgressUpdate(params);
}
#Override
protected Long doInBackground(Void... params) {
// my server calls are called here.
}
#Override
protected void onPostExecute(Long result) {
}
}
If you kill your app, or if the system kills it, then AsyncTask threads for your app get killed. They're all part of your app's process; threads can't survive outside the process that started them.
Even an IntentService might not survive a force quit. That's why task killers are such a bad idea.
In short, what you're seeing is expected behavior.