The onProgressUpdate() is never called, can you tell me why?
private class LoginMe extends AsyncTask<Context, Void, Boolean> {
#Override
protected Boolean doInBackground(Context... arg0) {
doSomething();
return true;
}
#Override
protected void onProgressUpdate(Void... v) {
super.onProgressUpdate(v);
Log.d("Dev", "Im in onProgressUpdate()");
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
doOne();
} else {
doTwo();
}
}
}
You have to call publishProgress from within doInBackground manually.
doInBackground(Params...), invoked on
the background thread immediately
after onPreExecute() finishes
executing. ... This step can also use
publishProgress(Progress...) to
publish one or more units of progress.
These values are published on the UI
thread, in the
onProgressUpdate(Progress...) step.
http://developer.android.com/reference/android/os/AsyncTask.html
Related
I have two async tasks. Let's say A and B. A is first executed and on the post executed B is called. Now I need to show the progress bar after Task B ends. Like a percentage from 0 starting A and 100 endings of B. How can this be done?
in your onPreExecute and onProgressUpdate from asynctask A :
#Override
protected void onPreExecute() {
super.onPreExecute();
//show progress bar
}
#Override
protected void onProgressUpdate(Integer... progress) {
ProgressBar.setProgress(progress[0]/2)//we will take only 50% of the progress
}
in your onPostExecute and onProgressUpdate in your asynctask B
#Override
protected void onProgressUpdate(Integer... progress) {
ProgressBar.setProgress(progress[0]/2)//we will take the other 50% of the progress
}
#Override
protected void onPostExecute(String result){
//hide progress here
}
please make sure to make your progress bar local so you can access it from both asynctask
Within AsyncTasks you can update the UI on onProgressUpdate or onPostExecute callbacks. These two callbacks run in the main (UI) thread, whereas doInBackground runs in a worker thread.
In order to make the the "B" progress bar showing after the completion of AsynctaskA I would start the AsyncTaskB in the onPostExecute callback of AsyncTaskA, then update the progress bar B in its onProgressUpdate callback
public ProgressBar progressBarA = ProgressBar(this); // init with a progress bar coming from the UI here
public ProgressBar progressBarB = ProgressBar(this); // init with a progress bar coming from the UI here
private class AsyncTaskA extends AsyncTask<Void, Integer, Boolean> {
protected Boolean doInBackground(Void... params) {
// do something in the background here
for (int i = 0; i < 100; i++) {
publishProgress(i);
}
return true;
}
protected void onProgressUpdate(Integer... progress) {
progressBarA.setProgress(progress[0]);
}
protected void onPostExecute(Void result) {
AsyncTaskB taskB = new AsyncTaskB();
taskB.execute();
}
}
private class AsyncTaskB extends AsyncTask<Void, Integer, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBarB.setProgress(0);
}
protected Boolean doInBackground(Void... params) {
// do something in the background here
for (int i = 0; i < 100; i++) {
publishProgress(i);
}
return true;
}
protected void onProgressUpdate(Integer... progress) {
progressBarB.setProgress(progress[0]);
}
protected void onPostExecute(Void result) {
// Toast work complete!
}
}
I have designed an app that gets the network information and updates the UI every 5 seconds.
It is advised to do the background processes on a separate thread than the UI thread, and I did so...but I still get an error that:
"I/Choreographer﹕ Skipped 3730 frames! The application may be doing
too much work on its main thread."
Why is that?
Here's my code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wifiTextView = (TextView)findViewById(R.id.wifi_textView);
ipTextView = (TextView)findViewById(R.id.ip_val_textView);
// and so on
//Updating the UI every mInterval seconds, using a separate thread than UI thread
Thread backgroundThread = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(mInterval);
runOnUiThread(new Runnable() {
#Override
public void run() {
//Log.d(DEBUG_TAG, "run(): Background thread");
MyNetwork network = new MyNetwork(getApplicationContext()); // passing the context
updateUI(network);
}
});
}
} catch (InterruptedException e) {
wifiTextView.setText("Exception: Please Close and Restart the App");
}
}
};
backgroundThread.start();
}
In the same MainActivity class, I have this private function:
private void updateUI(MyNetwork network){
// Handles updating the textviews in the UI
//Log.d(DEBUG_TAG, "updateUI(DeepstreamNetwork)");
if (network.isConnected()){
wifiTextView.setText(R.string.wifi_is_on);
wifiTextView.setTextColor(Color.GREEN);
ipTextView.setText(network.getIpAddress());
else {
wifiTextView.setText(R.string.wifi_is_off);
wifiTextView.setTextColor(Color.RED);
ipTextView.setText("N/A");
}
}
UPDATE
So, I have updated my MainActivity class to have this MyAsyncTask method to handle background work...here's my code:
private class MyAsyncTask extends AsyncTask<Void, Void, MyNetwork> {
#Override
protected void onPostExecute(MyNetwork network) {
updateUI(network);
}
#Override
protected MyNetwork doInBackground(Void... params) {
MyNetwork network = new MyNetwork(getApplicationContext()); // passing the context
return network;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
Two issues:
1) how do I force it to do this background task every 5 seconds. Since the network status changes every few secs (disconnection etc...), so I want it to update the UI respectively.
2) should I call it like this in MainActivity: new MyAsyncTask().execute();
Thanks all
I dont know why you called it Thread backgroundThread = new Thread() because runOnUiThread() is really the main Thread.
You should try this in an asynctask where you only update the UI in onPostExecute()
EDIT:
private class MyAsyncTask extends AsyncTask<Void, Void, String> {
private MyNetwork network;
#Override
protected void onPreExecute() {
this.network = new MyNetwork(getApplicationContext());
}
#Override
protected String doInBackground(Void... params) {
return network.getIpAddress();
}
#Override
protected void onPostExecute(String ipAddress) {
if (this.network.isConnected()){
wifiTextView.setText(R.string.wifi_is_on);
wifiTextView.setTextColor(Color.GREEN);
ipTextView.setText(ipAddress);
else {
wifiTextView.setText(R.string.wifi_is_off);
wifiTextView.setTextColor(Color.RED);
ipTextView.setText("N/A");
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
I have a specific case where I want to run an AsyncTask's doInBackground on UI Thread. How can I do that?
You definitively could, but as #Devrath said, it is pointless. AsyncTask are used for background operation.
Here is a sample that uses the runOnUiThread method:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// WORK on UI thread here
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
I ended up doing the following:
Got all the code from doInBackground and moved it to a method.
In doInBackground I make a call only to this method.
In the cases where I need the asynctask to be executed normally, I call LongOperation().execute()
In the cases where I need the asynctask to be ran on the UI thread, I dont call it but I call the method instead.
Try this
public void commentBuilder() {
new Thread(new Runnable() {
#Override
public void run() {
//Your code
}
}).start();
}
Also, see this for more detail https://stackoverflow.com/a/14038370
As far i know ..... You cannot !
AsyncTask are designed to perform background task which takes
longer time to perform
So they have to be performed in a seperate thread different from the
mainthread
Mainthread takes care of all the UI for your app
If you want ot update a UI while performing a background operation::
Just use onProgressUpdate method of the AsyncTask to update the
UI during the background operation
else use onPre method to update UI before the beckground call is
made
Else finally use onPost method to update after rte async task
completes doInBackground
{SAMPLE}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// might want to change "executed" for the returned string passed
// into onPostExecute() but that is upto you
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
Is there a method I could use in my Main thread, to wait for the result from an AsyncTask (in my case a value from a web-service) ?
I made a workaround without using AsyncTask but I know it's not the correct way:
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Could you help with hints in order to use an AsyncTask?
Thanks.
You are looking for onPostExecute() method.
When all the work in the background is finished, onPostExecute() which is in on your main thread will be called.
#Override
protected void onPostExecute(String result) {
//Do your stuffs here on Main UI thread.
}
onPostExecute() method of AsyncTask runs in the main thread. You can rely on it to wait for a result from AsyncTask from a main thread.
private class AsyncWait extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
//Whatever is done here, will run on main thread
}
#Override
protected Void doInBackground(Void... params) {
//Whatever is done here, will run on background thread
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//Whatever is done here, will run on main thread
}
}
From the main thread:
new AsyncWait().execute();
You can just use the onPostExecute of your asynctask to call the method of your main thread, or just do whatever you need doing.
private class AsyncCaller extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
}
#Override
protected Void doInBackground(Void... params) {
...
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//this method will be running on UI thread
}
}
Anyone know if it possible to kill/stop AsyncTask without loop.
There was many examples with loop but the task which I should do in doInBackground() function only one function which in some cases take long time and I shall stop it for example in onPause. If it possible or I should use another task for example Futuretask.
Thanks in advance.
The code like this:
class ProcessTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... params) {
Log.i(TAG, " ---- ProcessTask -- doInBackground ----");
// Task
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Log.i(TAG, " ---- ProcessTask -- onPostExecute ----");
}
#Override
protected void onCancelled(Boolean result) {
super.onCancelled(result);
Log.i(TAG, " ---- ProcessTask -- onCancelled ----");
}
}
...
ProcessTask myTask;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
myTask = new OCRProcessTask();
myTask.cancel(false);
myTask.execute();
}
#Override
public void onPause() {
myTask.cancel(true);
}
You can cancel the AsyntTask by setting cancel(true) to the task.
new MyAsyncTask().cancel(false);