I have an AsyncTask in a class. I want it to display the progress while it is getting executed. But it is not printing the Logs.
private void registerBackground() {
new AsyncTask<Void, Integer, String>() {
#Override
protected String doInBackground(Void... params) {
Log.v("TAGGG", "IN doInBackground");
msg = "Error: ";
return msg;
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
Log.v("TAGGG", "Progress: " + progress[0] + "%");
}
#Override
protected void onPostExecute(String msg)
{
Log.v("TAGGG", msg);
}
}.execute();
}
You have to use the publishProgress() method: http://developer.android.com/reference/android/os/AsyncTask.html#publishProgress(Progress...)
This method can be invoked from doInBackground(Params...) to publish
updates on the UI thread while the background computation is still
running. Each call to this method will trigger the execution of
onProgressUpdate(Progress...) on the UI thread.
onProgressUpdate(Progress...) will note be called if the task has been
canceled.
#Override
protected String doInBackground(Void... params) {
Log.v("TAGGG", "IN doInBackground");
msg = "Error: ";
int i = 0;
while (i <= 50) {
try {
Thread.sleep(50);
publishProgress(i);
i++;
}
catch (Exception e) {
Log.i(TAGGG, e.getMessage());
}
}
return msg;
}
Related
I have the code that sends requests to REST API in AsyncTask.
Also, I have a ProgressDialog initialization in preExecute() and its dismission in postExecute().
I want ProgressDialog to show an indeterminate spinner (you know, that loading animation), but I need to get a result too. get() blocks the main thread where I'm invoking it in - what's the workaround for that case?
Main thread (main activity)
LoginTask task_login = new LoginTask();
AsyncTask<String, Void, JSONObject> response = task_login.execute(et_username.getText().toString(), et_password.getText().toString());
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
AsyncTask (dummy doInBackground):
public class LoginTask extends AsyncTask<String, Void, JSONObject> {
private LoginTask self = this;
private ProgressDialog progressDialog;
#Override
protected JSONObject doInBackground(String... params) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(MainActivity.context,
"Logging in...", "");
progressDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
MainActivity.context.getResources().getResourceEntryName(R.string.dialog_button_cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
self.cancel(true);
}
});
}
#Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
progressDialog.dismiss();
}
}
You can use AsyncTask's onProgressUpdate() method to perform the actions on the UI thread (such as showing or updating a loading animation) while doInBackGround() does the background work on another thread.
Basically you invoke the publishProgress() method from within doInBackGround(), which in turn calls onProgressUpdate().
Check out the Android reference page on AsyncTask for an example.
Please look at the usage of AsyncTask https://developer.android.com/reference/android/os/AsyncTask#usage
There is a callback function onPostExecute which returns (as parameter) the value you requested:
private class RestTask extends AsyncTask<Object, Object, String> {
protected String doInBackground(Object... args) {
// this happend on background thread
return downloadData();
}
protected void onPreExecute() {
// this happend on UI thread
showSpinner();
}
protected void onPostExecute(String result) {
// this happend on UI thread
hideSpinner();
doSomethingWithDownloadResult(result);
}
}
Usage:
new RestTask().execute()
As you edited the question, this:
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
should be called in previous Tasks onPostExecute method, this way you will not block you UI with get method waiting on login result.
1 - You can use a callback method.
but keep in mind you should call it in your main thread.
2 - you can use LocalBroadcastManager in order to send your result through Intent.
3 - you might want to use in application messaging libraries which are more reliable in my opinion. one example which I use very often is EventBus.
i have an asynctask but if i implement a Thread.Sleep , then my app crashes , i dont know why, in onPreExecute i can see my first message and then after two secs it appears the other one i put in doInBackground , but its not working
private class sendMail extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
dialog.setMessage("Please wait...");
dialog.show();
}
// automatically done on worker thread (separate from UI thread)
#Override
protected Void doInBackground(Void... voids) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
dialog.setMessage("Downloading files...");
new BackgroundTask().execute();
//MY DOWNLOADING METHODS STUFF
And then i dismiss this dialog somewhere else
Log
An error occurred while executing doInBackground()
You cannot access the UI elements from a background thread you can update the progressbar in onProgressUpdate, most importantly you need to publishProgress(value) in doInBackground and update using onProgressUpdate. Read more about the AsyncTask here.
Example code:
class MyTask extends AsyncTask<Integer, Integer, String> {
#Override
protected String doInBackground(Integer... params) {
for (; count <= params[0]; count++) {
try {
Thread.sleep(1000);
publishProgress(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Task Completed.";
}
#Override
protected void onPostExecute(String result) {
progressBar.setVisibility(View.GONE);
txt.setText(result);
btn.setText("Restart");
}
#Override
protected void onPreExecute() {
txt.setText("Task Starting...");
}
#Override
protected void onProgressUpdate(Integer... values) {
txt.setText("Running..."+ values[0]);
progressBar.setMessage("Downloading files...");
progressBar.setProgress(values[0]);
}
}
Use UI thread to show dialog message in doInBackground refer this https://stackoverflow.com/a/15757788/6626966
I'm working on an app that retrieves data from network, stores them to the device and then reads them.
Problem is, I get my data in a Async Task.. And my app doesn't let the task finish before trying to show the data to the user..
I've tried task.get() but without result (it just stops there).
Here is my task:
public GetOptionsTask(XMLPortalGetOptions request) {
super(request);
}
protected void onCancelled(){
// TODO afficher message pas d'options sur le disque
}
#Override
public void handleError(Transaction transaction) {
// TODO afficher message pas d'options sur le disque
}
#Override
public void handleSuccess(Transaction transaction) {
saveOptions(transaction.getResponse());
request = null;
Log.d(OptionsManager.class.getName(), this.getStatus().toString());
}
This task is an instance of my custom Async Task:
protected BaseXMLTransaction request;
public abstract void handleError(Transaction transaction);
public abstract void handleSuccess(Transaction transaction);
public TransactionTask(BaseXMLTransaction request){
this.request = request;
}
#Override
protected Void doInBackground(Void... params) {
try {
Log.i(TransactionTask.class.getName(), "Doing in background");
SocketHandler.sendTransaction(this, request.getRequest());
} catch (SocketHandlerNotConfiguredException e) {
Log.e(TransactionTask.class.getName(), "SocketHandler's parameters were not set.");
}
return null;
}
#Override
public void transactionResult(Transaction transaction) {
switch (transaction.getCode()) {
case ERROR:
Log.e(TransactionTask.class.getName(), "ERROR !!!");
handleError(transaction);
break;
case NO_CLIENT:
Log.e(TransactionTask.class.getName(), "No Client Error");
handleError(transaction);
break;
case NO_SERVER:
Log.e(TransactionTask.class.getName(), "No Server Error");
handleError(transaction);
break;
case OLD_VERSION:
Log.e(TransactionTask.class.getName(), "Old Version");
handleError(transaction);
break;
case TIMEOUT:
Log.e(TransactionTask.class.getName(), "Transaction Timeout");
handleError(transaction);
break;
case SUCCESS:
Log.i(TransactionTask.class.getName(), "Transaction Success");
handleSuccess(transaction);
}
}
I seriously don't know what to do... Execute goes to fast and get doesn't do anything since I'm not returning anything I guess.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
#Override
protected void onPostExecute(String result) {
}
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
and call it like this:
new DownloadFilesTask().execute(url1, url2, url3);
I use an interface as a delegate to do this. Here is an example:
In my main activity I have a onClick listener to trigger my async call and a listener to process once the call is complete.
private void enableLocationButton(){
locationButton = (Button) findViewById(R.id.locationButton);
locationButton.setEnabled(true);
locationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, selectLocationActivity.class);
intent.putExtra("serverURL",server.getWebServerAddressField());
startActivityForResult(intent, 200);
}
});
}
#Override
protected void onActivityResult(int requestCode,int resultCode, Intent data){
if(resultCode == RESULT_OK) {
switch (requestCode){
case 100:
processServerResponse((PmsWebServer) data.getBundleExtra("server").get("server"));
break;
case 200:
processLocationResponse((PmsDataSource)data.getBundleExtra("location").get("location"));
default:processError();
}
}else{
processError();
}
}
Somewhere in the selectLocationActivity I have a call to the Async call and something to process the response, please note that this class implements an interface that is used in the Async call.
public class selectLocationActivity extends ListActivity implements SoapServiceInterface{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_select);
chosenServer = this.removeURLHeader(getIntent().getStringExtra("serverURL"));
this.retrieveLocationOptionsByServer(chosenServer);
}
private void retrieveLocationOptionsByServer(String server) {
Map<String,Object> parms = new HashMap<String,Object>();
parms.put(WEB_SERVER_NAME,server);
SoapServiceObject service = new SoapServiceObject(Services.SERVICE_DETAILS,parms);
callTheService(service);
}
private void callTheService(SoapServiceObject service){
SoapServiceHelper helper = new SoapServiceHelper();
helper.delegate = thisActivity;
helper.execute(service);
}
#Override
public void serviceCallComplete(SoapObject response){
this.createClickableListOnScreen(response);
}
//...more code...//
}
serviceCallComplete is kicked off by the asyncTask. Below is the code for that task
public class SoapServiceHelper extends AsyncTask<SoapServiceObject, Void, SoapObject>{
public SoapServiceInterface delegate = null;
private Integer RETRY_COUNT = 0;
private final Integer MAX_RETRY_COUNT = 2;
protected SoapObject doInBackground(SoapServiceObject... args){
SoapServiceObject service = args[0];
try{
service.callTheService();
}catch(Exception e){
System.out.println("An error occurred calling the service\n" + e.getMessage());
}
return service.getResponse();
//return callDateTimeService();
}
protected void onPostExecute(SoapObject result){
delegate.serviceCallComplete((SoapObject)(result.getProperty(0)));
}
}
And finally here is the interface
public interface SoapServiceInterface {
public void serviceCallComplete(SoapObject response);
}
I know I'm displaying something to the screen directly from my result, just sub that part with a save and read ;)
One thing with that task was that it was saving stuff into a singleton. I managed to call the methods using the information from the network saved in the singleton at the onResume(). When the threads end, it goes to the onResume and everything works fine!
Currently building an Android app and checking it on Genymotion running 4.1.1. I'm using AsyncTask to call the Bing Translate API to translate from text:
class TranslateFacebookText extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... message) {
String translatedText = "";
try {
translatedText = Translate.execute(message[0], Language.AUTO_DETECT, Language.ENGLISH);
} catch (Exception e) {
....
}
return translatedText;
}
#Override
protected void onPostExecute(String translatedText) {
message = translatedText;
confirmTTSData();
}
}
public void onClick(View src) {
TranslateFacebookText translateTask = new TranslateFacebookText();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
translateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message);
}
else {
translateTask.execute(message);
}
}
I'm using this method to start the task after reading this question: Android SDK AsyncTask doInBackground not running (subclass)
I'm doing so, since after about 2-5 minutes from the programs start, the AsyncTask refuses to run. That is, doInBackground does not get called, nor does onPostExecute. the onClick DOES get called, creates the new AsyncTask and runs the execution code, but the doInBackground does not get called.
This is completely random. I'm not doing anything else - just waiting there for a couple of minutes, and afterwards clicking the button again to see this happen. This is also true with a service which runs every specified time using a Handler and postDelayed. Here's an example:
public class MyService extends Service {
private Handler periodicEventHandler;
private final int PERIODIC_EVENT_TIMEOUT = 600000;
#Override
public void onCreate() {
periodicEventHandler = new Handler();
periodicEventHandler.postDelayed(doPeriodicTask, PERIODIC_EVENT_TIMEOUT);
}
private Runnable doPeriodicTask = new Runnable()
{
public void run()
{
TranslateFacebookText translateTask = new TranslateFacebookText();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
translateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, message);
}
else {
translateTask.execute(message);
}
periodicEventHandler.postDelayed(doPeriodicTask, PERIODIC_EVENT_TIMEOUT);
}
};
class TranslateFacebookText extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... message) {
String translatedText = "";
try {
translatedText = Translate.execute(message[0], Language.AUTO_DETECT, Language.ENGLISH);
} catch (Exception e) {
....
}
return translatedText;
}
#Override
protected void onPostExecute(String translatedText) {
message = translatedText;
confirmTTSData();
}
}
}
The doPeriodicTask runs fine, again creating the AsyncTask and calling the execution code, but doInBackground never gets called. If I change PERIODIC_EVENT_TIMEOUT to 8000, for example, doInBackground would get called fine.
Ideas?
i have a question regarding the AsyncTask class in android, and why it is giving me an error. I have defined an inner class here..
class MyTask extends AsyncTask<String,String,Integer>{
Context context;
ProgressDialog dialog;
MyTask(Context c)
{
this.context = c;
}
//#Override
protected void onPreExecute()
{
dialog = new ProgressDialog(context);
dialog.setMessage("Scanning Ports!");
dialog.show();
}
#Override
protected Integer doInBackground(String... params) {
// TODO Auto-generated method stub
for(intBeg = intBeg; intBeg <= intEnd; intBeg++
{
try
{
Socket s = new Socket(strMachine, intBeg);
isConnected += strMachine + " Is Listening On Port: " + intBeg + "\n";
Log.d("PORTSCAN", isConnected);
s.close();
}catch(Exception e){
notConnected += strMachine + " Is Not Listening On Port: " + intBeg + "\n";
//Toast.makeText(getBaseContext(), e.getMessage(), 3000).show();
Log.d("PORTSCAN", notConnected);
}
}
return 1;
}
protected void onPostExecute(Integer... params)
{
}
protected void onProgressUpdate(String... params)
{
}
}
However, when the doInBackground finishes, it supposed to call onPostExecute(), which never happens. And even when i try to use the "#Override" annotation over the onPostExecute(), it gives me an error saying onPostExecute must override a superclass method. I dont get what is happening! any help? Thanks!
onPostExcecute(Integer result) takes a single argument (no ...).
If the arguments don't match, it will not match the super method and will therefore not override it (and be called). Generally if #Override gives you an error something is wrong with your method name/parameters (or the superclass does not have such a method).
protected void onPostExecute(Integer params)//its single Integer object, not array of Integer objects
its java Varargs.and you can't change parameter of overrided method,You just change the Behaviour of override method.And its method of AsyncTask Class.
Just use this onPostExecuteMethod
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
Log.e("LOG", " on Post");
}
Check this code
private class DownloadingProgressTask extends
AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog = new ProgressDialog(ShowDescription.this);
/** progress dialog to show user that the backup is processing. */
/** application context. */
protected void onPreExecute() {
this.dialog.setMessage("Please wait");
this.dialog.show();
}
protected Boolean doInBackground(final String... args) {
try {
downloadFile(b.getString("URL"));
return true;
} catch (Exception e) {
Log.e("tag", "error", e);
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
if (dialog.isShowing()) {
dialog.dismiss();
}
if (success) {
Toast.makeText(ShowDescription.this,
"File successfully downloaded", Toast.LENGTH_LONG)
.show();
imgDownload.setVisibility(8);
} else {
Toast.makeText(ShowDescription.this, "Error", Toast.LENGTH_LONG)
.show();
}
}
}