I am trying to know how to make the AsyncTask survives the screenOrientation change. So, I created an example for a MainActivity with AsyncTask. As shown in the code below, in
the doInBackground() method I print the incremented value of the variable "i" each second upto 7 seconds, and I publish the value of the variable "i" using publishProgress()
and display it in the TextView. while the value of varibale "i" is being published I changed the orientation of the device and I expected the App will crash, but what happened is,
that the the screenOrientation has changed and the value of the variable "i" was being published and normally displayed in the TextView without crash.
Is the AsyncTask I created not a suitable example to learn how to survive the screenOrientation?
MainActivity
public class MainActivity extends AppCompatActivity {
private final static String TAG = MainActivity.class.getSimpleName();
private TextView mtv11Up = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.mtv11Up = (TextView) findViewById(R.id.tv11_up);
new ATRetain().execute();
}
private class ATRetain extends AsyncTask<Void, Integer, Void> {
private long mStartTime;
private int i = 0;
#Override
protected void onPreExecute() {
super.onPreExecute();
this.mStartTime = TimeUtils.getTSSec();
}
#Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "started");
while((TimeUtils.getTSSec() - this.mStartTime) <= 7) {
Log.i(TAG, "i: " + (++i));
publishProgress(i);
SystemClock.sleep(1000);
}
Log.i(TAG, "finished");
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mtv11Up.setText(String.valueOf(values[0]));
}
}
}
AsyncTask create separate thread from UI Thread when orientation changes it recreated it self but AsyncTask is still running because it separate Background thread.
While doing some important work you can lock the screen orientation for some time until AsyncTask will complete then unlock.
Lock:
protected void onPreExecute() {
// ....
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
Unlock:
protected void onPostExecute(String result) {
// ...
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
Related
I am using an AsyncTask in an activity.
here is my code
public class MyActivity extends AppCompatActivity {
EditText editUserNameLogin;
EditText editPassLogin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
//ButterKnife.bind(this);
editUserNameLogin = (EditText) findViewById(R.id.input_username_login);
editPassLogin = (EditText) findViewById(R.id.input_password_login);
}
public class AsyncTaskClass extends AsyncTask<String, String, String> {
String strUserName = editUserNameLogin.getText().toString();
String passLogin = editPassLogin.getText().toString();
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
Toast.makeText(MyActivity.this, passLogin, Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(String r) {
}
}
but in doInBackground can't get values passLogin or strUserName
(Toast.makeText(MyActivity.this, passLogin,) don't show any text)
Try and execute AsyncTaskClass in onCreate
new AsyncTaskClass().execute(); //use this method and call this in onCreate
Try this one, inside onCreate
String response="checking";
new AsyncTaskClass().execute(response);
then create inner class AsyncTaskClass,
private class AsyncTaskClass extends AsyncTask<String,Void,String > {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
String respose1 = strings[0];
return respose1;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);}
}
You can not perform UI operation inside background AsyncTask doInBackground method because AsyncTask not work with current UI thread, its create new thread while you initialize and execute.
Let me explain you in bref.
While activity start its stay with Activity Thread and when you complete activity operation and destroy its completely remove from operation task.
But while you start AsyncTask on Activity its start with individual operation stat that not depends on activity that you start, so if you perform UI operation in doInBackground method and in case Activity destroyed and you working on UI that already destroyed by activity and UI cannot get reference, its generate an exception. So it's necessary to work with current activity thread not another background thread.
There are many case that you can pass data inside AsyncTask, i'm comfortable with below operation, it can help you also.
// Pass data to AsyncTask comma separated values
new MyBackgroundTask().execute("Hello there!","How are you?");
private class MyBackgroundTask extends AsyncTask<String, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(String... strings) {
String message1 = strings[0];
String message2 = strings[1];
Log.d("_TAG_", "First String: " + message1);
Log.d("_TAG_", "Second String: " + message2);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
For more information read Android Official Documents AsyncTask Developer Guides
You cant show ui operations like toast in doInBackground if you still want to do that then use this code to display toast while in doInBackground
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT).show();
}
});
and also you need to call yourAsyncTaskObject.execute to start asynctask
I have no idea what exactly you want to achieve by such behavior.
But i am pointing out some point here . First of all you can not access any UI element in background thread .
#Override
protected String doInBackground(String... params) {
Toast.makeText(MyActivity.this, passLogin, Toast.LENGTH_SHORT).show();
}
The above code is not going to work as doInBackground runs asynchronously separate from UI thread.
If you want to show a toast on AsyncTask started then do it in onPreExecute or after execution do it in onPostExecute.
#Override
protected void onPreExecute() {
Toast.makeText(MyActivity.this, passLogin, Toast.LENGTH_SHORT).show();
}
And as i see you never execute the AsyncTask then how are you expecting anything from it. Do call execute().
new AsyncTaskClass().execute();
For more on AsyncTask read AsyncTask.
Try the following:
#Override
protected String doInBackground(String... params) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MyActivity.this, passLogin, Toast.LENGTH_SHORT).show();
}
});
}
AsyncTask enables proper and easy use of the UI thread. This class
allows you to perform background operations and publish results on the
UI thread without having to manipulate threads and/or handlers.
new AsyncTaskClass("SEND STRING").execute();
You can pass this Your Value this way
private class AsyncTaskClass extends AsyncTask<String, String, String> {
String strRESPONSE="";
public MyAsyncTask(String str_GET) {
this.strRESPONSE=str_GET; // print "SEND STRING"
}
}
im using asyncTask to showing a download progress , my download will be done by a library named "file-downloader" in my main activity.
it's github page is "https://github.com/wlfcolin/file-downloader"
my custom dialog shows when i click to my specified button , and download task and progressBar starts when i press download button in this custom dialog
all thing is ok and progressBar works fine.
but when i dismiss this dialog and another time i invoke this dialog the progressBar does not work !
i save download status in database using the fileDownloader library listeners and anothe time i invoke custom dialog it read from database
and detect downloadProgress is currently running but we see no changing in custom dialog's progressBar , what is the problem ?
activity code
public class MainActivity extends AppCompatActivity {
/*
/
/ some variables
/
*/
public static int downloadedFile2SizePercent = 0 ; // downloaded file percent
public static int downloadingFileStatus = 0; // downloading status
Button myBtn ;
DownloadDialog dd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
myBtn = (Button)findViewById(R.id.button22);
myBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dd = new DownloadDialog(mContext,1);
dd.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dd.show();
}
});
/*
/ downloadingFileStatus value manages here by file downloader listeners correctly and saves as static variable and also in database
/ downloadedFile2SizePercent value manages here by file downloader listeners correctly and saves as static variable
/
*/
}
}
DownloadDialog Class
public class DownloadDialog extends Dialog implements View.OnClickListener{
public Context c;
public Button download, delete;
private ProgressBar pb;
ProgressTask progressTask;
private int downloadStatus;
private String downloadLink;
private int downloadID
public DownloadDialog(Context a, int downloadId) {
super(a);
this.c = a;
this.downloadId = downloadId
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.download_dialog);
download = (Button) findViewById(R.id.downloaddialot_downloadbtn);
delete = (Button) findViewById(R.id.downloaddialot_deletebtn);
download.setOnClickListener(this);
delete.setOnClickListener(this);
pb = (ProgressBar)findViewById(R.id.progressBar);
pb.setMax(100);
pb.setProgress(0);
//database is opend at mainActivity it's static
downloadStatus=Integer.parseInt(MainActivity.prDb.intSearch(downloadId));// detects download status --> 0 is "notDownloadedYet" and
// 1 is "downloading" and 2 is "downloaded"
downloadLink= MainActivity.puDb.intSearch(downloadId);//detects download link
progressTask = new ProgressTask();
if(downloadStatus==1){
pb.setProgress(MainActivity.downloadedFile2SizePercent);//this code line works every 2nd and after dialog invoking
progressTask.execute(true);
Toast.makeText(c,"test task progress for 2nd started", Toast.LENGTH_SHORT).show();//this code line works every 2nd and afterdialog invoking
}
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.downloaddialot_downloadbtn:
FileDownloader.start(downloadLink); // download task starts here
progressTask.execute(true);
Toast.makeText(c,"download task progress for 1nd started", Toast.LENGTH_SHORT).show();
break;
case R.id.downloaddialot_deletebtn:
if(downloadStatus==2){
// delete codes
}
break;
}
}
public class ProgressTask extends AsyncTask<Boolean, Integer, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Boolean... params) {
while (MainActivity.downloadedFile2SizePercent!=100){
publishProgress(MainActivity.downloadedFile2SizePercent);
}
if(MainActivity.downloadedFile2SizePercent==100){
publishProgress(MainActivity.downloadedFile2SizePercent);
}
return true;
}
#Override
protected void onProgressUpdate(Integer... values) {
pb.setProgress(values[0]);
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
downloadStatus=2; //also saves in database by download listeners in mainActivity
}
}
}
The progress bar just like any other UI element can only be managed or updated from the main UI thread.
It is the time consuming task the part that should be run in a AsyncTask, then this task can save the progress status in a volatile variable and then the UI thread can periodically update the progress bar reading the volatile variable, for example using a timer.
You can read all about AsyncTask here: https://developer.android.com/reference/android/os/AsyncTask.html
But here's my quick example/tutorial:
private class MyAsyncTask extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// prepare your UI for the background task beginning
}
#Override
protected Void doInBackground(Void... params) {
// do some long-running task...
// you can do partial updates like:
publishProgress(25);
/* more hard work */
publishProgress(50);
/* even more hard work */
publishProgress(75);
// and when you're done...
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// update your UI with the current progress (values[0])
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// update your UI now that it's done
}
}
The key concept to understand regarding AsyncTask is that every method except doInBackground() is executed on the UI thread (the main thread). That means you are free to update your UI from these calls.
doInBackground(), however, is executed on a different thread. That means you can do expensive work here without slowing down your app's user interface.
Of course, all the hard work you're doing on that background thread needs to make its way to the UI thread somehow (so that you can use it). That's what publishProgress() and the return statement of doInBackground() are for. When you call publishProgress(someValue), the system will invoke onProgressUpdate(someValue) for you. When you return someValue, the system will invoke onPostExecute(someValue) for you.
I seem to be going round in circles.
I have some code that even on a Galaxy S3 takes a few seconds to run. Drags data from database.
I want to add a progress bar popup (spinning circle) around this to give the user that the app is doing something.
I have tried Asyntasks elsewhere in app and work fine but for this type the main UI is not waiting for the Asyntask to finish before moving on and so the new activity that is called does not have all the data it needs and crashes.
Is AsyncTask the best way round this or is there an easier way to Puase the main Activity, show a progress bar and then move on once the long deley has been completed.
Thanks for time
UPDATE
public class UpdateDetailsAsyncTask extends AsyncTask<Void, Void, Boolean> {
private Context context;
private TaskCallback callback;
private ArrayList<Object> object;
private ProgressDialog progress;
public UpdateDetailsAsyncTask (
Context pContext,
ArrayList<Object> pObject,
TaskCallback pCallback) {
context = pContext;
callback = pCallback;
object = pObject;
}
#Override
protected void onPreExecute() {
Log.i("AsyncTask", "onPreExecuted");
progress = new ProgressDialog(context);
progress.setMessage(context.getResources().getString(R.string.loading));
progress.show();
}
#Override
protected Boolean doInBackground(Void... params) {
Log.i("Archery", "AsyncTask Excuted");
Log.i("Archery Scorepad", "Building Continue Round Details");
// Save Data to Database
return true;
}
protected void onPostExecute(Boolean result) {
Log.i("AsyncTask", "onPostExuted");
progress.dismiss();
callback.startNewActivity();
}
}
Task is called from main Activity
new UpdateDetailsAsyncTask(this, ArrayListOfObjects, this).exute();
UPDATE 2
..
UPDATE 3
The Code that does some work calls an a method within a Util Class which in calls a database class. I have log messages showing for all the rows of data I am saving to the database. It starts correctly and runs through it but the onPostExecute() appears to be called before the database method has completed.
Is my issue that I have nested classes within the activity and the task appears to have completed when the class below it has not?
Thanks
You must change to the next activity in onPostExecute from Asyntask
Yes!
Here is a simple code of AsuncTask
private class LoadImageAction extends AsyncTask<String, String, String>{
private Course course;
private ProgressBar pb;
public LoadImageAction(Course course, ProgressBar pb){
this.course = course;
this.pb = pb;
}
#Override
protected void onPreExecute(){
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
protected void onProgressUpdate(String... string){
}
#Override
protected void onPostExecute(String result){
}
}
You can run the action by
new LoadImageAction().execute();
I made an application for Android that originally targeted a lower version (2.3). After I got my proof-of-concept working, I tried to get it to work on Android 4. That's when I got the NetworkOnMainThread exception.
After doing some research, I quickly found the AsyncTask, which sounded awesome. The problem is, I'm having a hard time wrapping my mind around it. For instance, here's my original code:
public void Refresh(Context c)
{
SummaryModel model = MobileController.FetchSummary(c);
TextView txtCurrentWeight = (TextView)findViewById(R.id.txtCurrentWeight);
TextView txtWeightChange = (TextView)findViewById(R.id.txtWeightChange);
TextView txtAvgPerWeek = (TextView)findViewById(R.id.txtAvgPerWeek);
if(model.ErrorMessage == "")
{
txtCurrentWeight.setText(model.CurrentWeight);
txtWeightChange.setText(model.WeightChange);
txtAvgPerWeek.setText(model.Average);
}
else
{
Toast.makeText(c, model.ErrorMessage, Toast.LENGTH_LONG).show();
txtCurrentWeight.setText("");
txtWeightChange.setText("");
txtAvgPerWeek.setText("");
}
}
I created an AsychTask like this:
public class WebMethodTask extends AsyncTask<Object, Integer, Object> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
SummaryModel model = (SummaryModel)result;
// Can't seem to access UI items here??
}
#Override
protected Object doInBackground(Object... params) {
Context c = (Context)params[0];
return MobileController.FetchSummary(c);
}
}
How do I access the UI items from the onPostExecute method? Or, do I have the wrong idea on how to use AsyncTask?
Thanks!
You should be able to accessUI where you put your comments (in the postExecute method)
Additionally, I would suggest to use more specialized class with for AsyncTask, so that your code looks better :
public class WebMethodTask extends AsyncTask<Object, Integer, SummaryModel> {
private Activity source;
public WebMethodTask(Activity activity) {
this.source=activity;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(SummaryModel model) {
super.onPostExecute(model );
TextView txtCurrentWeight = (TextView)source.findViewById(R.id.txtCurrentWeight);
TextView txtWeightChange = (TextView)source.findViewById(R.id.txtWeightChange);
TextView txtAvgPerWeek = (TextView)source.findViewById(R.id.txtAvgPerWeek);
if(model.ErrorMessage.length()==0)
{
txtCurrentWeight.setText(model.CurrentWeight);
txtWeightChange.setText(model.WeightChange);
txtAvgPerWeek.setText(model.Average);
}
else
{
Toast.makeText(c, model.ErrorMessage, Toast.LENGTH_LONG).show();
txtCurrentWeight.setText("");
txtWeightChange.setText("");
txtAvgPerWeek.setText("");
}
}
#Override
protected SummaryModel doInBackground(Context ... params) {
Context c = params[0];
return MobileController.FetchSummary(c);
}
}
Edit : Added a reference to your activity, to take your last comment into account.
However, if you acynctask can be long, it's maybe not a very good idea to keep a reference on an activity.
It would be a better design to create a listenerclass that will accept some displayModel(CummaryModel) method, and whose responsability is to cal the setText methods if the activity has not been paused / stopped in the meanwhile...
Fill the ui items with the loaded model data in the WebMethodTask#onPostExecute method.
You need a reference to your UI controls. When passing references to your UI controls to the ASyncTask you will create problems.
Assume the following scenario:
show activity (activity instance 1)
call async task with te activity as reference.
rotate your device (by default a device rotation will create a new activity) -> (activity instance 2)
when the sync task is finished, activity instance 1 is used to display the results. However the activity no longer exists causing exceptions.
The conclusion is that the ASyncTask should not be used for network activity related background tasks.
Fortunately there is a solution: RoboSpice.
RoboSpice uses another approach. Look at https://github.com/octo-online/robospice/wiki/Understand-the-basics-of-RoboSpice-in-30-seconds for a good explanation.
More information: https://github.com/octo-online/robospice
create an inner class in refresh method as
enter code herepublic void Refresh(Context c)
{
SummaryModel model = MobileController.FetchSummary(c);
TextView txtCurrentWeight = (TextView)findViewById(R.id.txtCurrentWeight);
TextView txtWeightChange = (TextView)findViewById(R.id.txtWeightChange);
TextView txtAvgPerWeek = (TextView)findViewById(R.id.txtAvgPerWeek);
if(model.ErrorMessage == "")
{
txtCurrentWeight.setText(model.CurrentWeight);
txtWeightChange.setText(model.WeightChange);
txtAvgPerWeek.setText(model.Average);
}
else
{
Toast.makeText(c, model.ErrorMessage, Toast.LENGTH_LONG).show();
txtCurrentWeight.setText("");
txtWeightChange.setText("");
txtAvgPerWeek.setText("");
}
class WebMethodTask extends AsyncTask<Object, Integer, Object> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
SummaryModel model = (SummaryModel)result;
// Can't seem to access UI items here??
}
#Override
protected Object doInBackground(Object... params) {
Context c = (Context)params[0];
return MobileController.FetchSummary(c);
}
}
}
I am writing a board game in Android where the UI consists of textViews for the scores (CPUScore and PlayerScore). The problem I have is that the UI does not update the score from its initial value when onCreate is called. I have looked at similar questions and the solution most suggested is to use AsyncTask to update the UI thread in the background. However I did not find a solution that dealt explicitly with how to use textViews in AsyncTask.
Here is my attempt:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//....
setContentView(R.layout.main_layout);
//.....
//------------ textViews declared here don't refresh -------------------
TextView playerScoreForm = (TextView) findViewById(R.id.PlayerTotalScore);
playerScoreForm.setText(Integer.toString(PlayerTotal));
playerScoreForm.invalidate();
TextView CPUScoreForm = (TextView) findViewById(R.id.CPUTotalScore);
CPUScoreForm.setText(Integer.toString(CPUTotal));
CPUScoreForm.invalidate();
//--------------------------------------------------------------------------
//AsyncTask method:
new updatePlayerScore().execute(PlayerTotal);
new updateCPUScore().execute(CPUScoreForm);
}
The AsyncTask subclasses:
private class updatePlayerScore extends AsyncTask<TextView, Void, Void> {
#Override
protected TextView doInBackground(TextView... params) {
// what to put here??
}
return playerScoreForm;
}
#Override
protected void onProgressUpdate(Integer... values) {
//??
}
protected void onPostExecute(Integer result) {
playerScoreForm.setText(Integer.toString(result));
}
}
private class UpdateCPUScore extends AsyncTask<TextView, Integer, Integer> {
// same syntax as updatePlayerScore
}
Question:
how do I transfer the textViews that I declared in the onCreate method to the AsyncTask method? I am stumped. I am fairly new to Android development.
a) I'm pretty sure you shouldn't need to invalidate the TextViews after you set them; Android should do that automagically.
b) In theory you'd set your TextView references to be member variables and then reference them in onPostExecute instead of passing them into doInBackground. doInBackground in turn will take whichever bits of data enable you to calculate the new score. What you would do on doInBackground is whatever action would cause a new score to be calculated. The return value from doInBackground gets passed into onPostExecute. You would then update the TextView (now a member variable) with this data in onPostExecute. Does that make sense? You haven't actually posted any code here that would update those score values.
See here for a quick example.
private TextView myScoreView; //initialized in onCreate as you do above.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//....
setContentView(R.layout.main_layout);
//.....
myScoreView = (TextView) findViewById(R.id.PlayerTotalScore);
myScoreView.setText(Integer.toString(PlayerTotal));
new updatePlayerScore().execute(1,2); //parameters for calculation
}
private class updatePlayerScore extends AsyncTask<Integer, Integer, Integer> {
#Override
protected TextView doInBackground(Integer... params) {
int score = params[0] + 2 * params[1];
return score;
}
#Override
protected void onProgressUpdate(Integer... values) {
//if you want to provide some indication in the UI that calculation
//is happening, like moving a progress bar, that's what you'd do here.
}
#Override
protected void onPostExecute(Integer scoreCalculationResult) {
myScoreView.setText(Integer.toString(scoreCalculationResult));
}
}
Edit: If you don't want to do the calculation logic in doInBackgroundThread, you probably just want to use:
runOnUiThread(new Runnable(){
#Override
public void run(){
myScoreView.setText(PlayerScoreValue);
}
});
Or:
myScoreView.post(new Runnable(){
#Override
public void run(){
myScoreView.setText(PlayerScoreValue);
}
});
You can pass the TextView in the constructor of the AsyncTask and update it from the onPostExecute method
private class updatePlayerScore extends AsyncTask<Void, Void, Integer> {
private TextView view;
public updatePlayerScore(TextView textView){
this.view = textView;
}
#Override
protected Integer doInBackground(Void... params) {
int score = 0;
//do you calculation the
return score;
}
protected void onPostExecute(Integer result) {
view.setText(Integer.toString(result));
}
}
note: if you Activity configuration change for any reason i.e the user rotate the device and the you AsyncTask hasn't finish it task the update of you TextView will not be updated so you should retain an instance of you AsyncTask and update the the TextView