This question already has answers here:
How to know if other threads have finished?
(12 answers)
Closed 7 years ago.
I have an activity in which i am running a thread to hit the web service.i want to finish the activity only when the thread is finished.
To make your life easier use Android AsyncTask Object. This provides the same background process as a Thread but handles everything for you. This includes callbacks at different stages of the AsyncTask. This includes once it has finished doing what you ask of it in the background via the onPostExecute() function.
From the documentation:
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");
}
}
You can use Thread.join(), which works for all Java programs (not just Android).
You can call isAlive() method of your Thread or getStatus() if you use AsyncTask
Related
i want to implement a login activity. it checks user existance with a webservice.
EditText un=(EditText) findViewById(R.id.txtName);
EditText pass=(EditText) findViewById(R.id.txtPass);
WS ss=new WS();
String str=ss.execute("checkLogin",un.getText().toString(),pass.getText().toString()).get();
Intent in=new Intent(arg0.getContext(), Overview.class);
in.putExtra("username", str);
if(str=="No User")
Toast.makeText(getApplicationContext(), "ss", 300).show();
else
{
startActivity(in);
finish();
}
the problem is in "IF" section. "str" value sets after finishing code lines.
but i want to get "str" value then check for IF to run proper actions.
You need override onPostExecute method see below example
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));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
The whole point of an asynchronous task is to not block synchronously. You have several options if you do want synchronous behavior:
Don't use AsyncTask in the first place (probably not a good idea if it is a long-running network call)
Put the code you want to run after the AsyncTask completes it's background work in the onPostExecute method, which will have access to the result of the data returned from the background method
Provide a callback to the AsyncTask that onPostExecute can call when it is finished (similar in concept to the previous option but more formal and robust to changes)
I prefer the last option, but it also takes more dev time to write than the other options.
Don't forget that an AsyncTask may do it's background work and/or finish after the activity has been finished and shut down, so make sure to check for that state appropriately before you start interacting with the UI.
If you are trying to do a network call you shouldn't use asynctask rather use loopj or google's volley library .
Asynctask is not meant for long network calls , having said that here's an example of asynctask class , code:
class AsyncTaskExample extends AsyncTask<Void, Integer, String> {
private final String TAG = AsyncTaskExample.class.getName();
protected void onPreExecute(){
Log.d(TAG, "On preExceute...");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG, "On doInBackground...");
for(int i = 0; i<5; i++){
Integer in = new Integer(i);
publishProgress(i);
}
return "You are at PostExecute";}
protected void onProgressUpdate(Integer...a){
Log.d(TAG,"You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
Log.d(TAG,result);
}
}
Edit it as you wish and instanciate a new one in your code when you want to do the check up ,
Hope it helps
I can easily get data from the database.. But because Asynctask runs in the background, it has not downloaded the data before i call my update() method.
Example.
MyGetDataFromDatebaseCall();
UpdateSomething();
So here's my question. How can you make the UpdateSomething() method wait until the MyGetDatebaseCall() has downloaded alle the data?
I have made a Dialog window that pops up, so the user have to press okay to proceed and that works. I could also create 2 buttons so they call one method each. But they are such ugly solutions. I have also tried to send an instance of the Activity i was in, and making the AsyncTask class try and update the Activity class in the doInBackground, but apperently it cant be done?
You should call MyGetDataFromDatebaseCall() method in doInBackground() and after downloading all the data, you can call updateSomething() method in onPostExecute().
It will work fine.
Did you ever look at the documentation?
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");
}
}
there are ANR when I play some net clip, and I can't handle the error msg from MediaPlayer.
Can I handle ANR msg from system and change the dialog? the default dialog is not comfort to user.
You cannot handle ANR in your own application. You should try your best to avoid the ANR.
According to Android dev guide pages, the ANR is triggered by the following conditions:
No response to an input event (such as key press or screen touch events) within 5 seconds.
A BroadcastReceiver hasn't finished executing within 10 seconds.
So, you should look cat the logcat traces and the ANR traces to target the position where ANR occurs and check the source code to find any possible 'long-running operations' that might be blocking the main thread.
Try to use AsyncTask to carry the task in the background to avoid ANR, which is recommend by Android official site. Take the downloading for example:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Do the long-running work in here
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;
}
// This is called each time you call publishProgress()
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// This is called when doInBackground() is finished
protected void onPostExecute(Long result) {
showNotification("Downloaded " + result + " bytes");
}
}
To execute this worker thread, simply create an instance and call execute():
new DownloadFilesTask().execute(url1, url2, url3);
I have a table called student which I want to populate from the server. In my activity I show a progress bar and call ContentProvder.requestSync(Content URI of student..). Now if I understand correctly as per Virgil's talk I should add an observer on the ContentURI of the student to be notified later by the ContentProvider when the sync finishes. But what happens if say there was a network error. The student table will never be populated and my progress dialog will never be removed.
I understand the
"broadcast receiver approach"
mentioned in another thread but that deviates from Virgil's approach which I consider ideal.
Also on those lines why doesn't the requestSync allow to pass a ResultReceiver as part of the extras. Isn't that generally a Service talks back to an Activity?
A SyncAdapter is not meant to be used for this kind of scenario. SyncAdapter is meant for background sync of data, invisible to the user.
Your case sounds like perfect for a AsyncTask. With that you can use publishProgress() to update your progress bar while your network task happens in another thread. You can find a lot of information and examples on AsyncTask online.
Example from the link above:
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");
}
}
run it by executing it like so:
new DownloadFilesTask().execute(url1, url2, url3);
Here is another example, with tutorial (simply found by google):
http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/
In the application i called the Thread in the alerdialog click listener.
It shows the Error "Force to close the application" in the Mobile Samsung pro.
but when i execute the same code in the another application then code works correctly...
It's probably because you're doing something wrong in the alerdialog click listener. Do the thing you're doing wrong right and it won't show the Error.
Do this below procedure help full in ur app
Android also provides something called AsyncTask which is specifically designed for running some stuff on a separate thread, and some on the UI thread. This automatically uses Android's threadpool, and if you do not have any reason to use an explicit separate thread, is an easy, clean way to go:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Runs on a ThreadPool thread
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
// Sends data to onProgressUpdate to run on the UI thread
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
// Runs on the UI thread!
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// Runs on the UI thread!
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}