Update TextView via Async Task - android

I'm trying to dismiss dialog in AsyncTask's onPostExecute() and also set text in textview, but textview doesn't change and I get the "Window already focused, ignoring focus gain of...".
Here's the code:
protected void onPreExecute() {
dialog = ProgressDialog.show(mContext, "","Loading...", true);
}
protected void onPostExecute(Object result) {
dialog.dismiss();
tv.setText("some text");
}
Progress dialog is shown and when my background work is complete, it is dismissed but there's no change to textview. Without progress dialog, text view is updated.
Any idea, solution to this problem?
Thanks!

Try this code snippet after you have called dialog.dismiss().
if (!dialog.isShowing())
{
TextView tv = (TextView) findViewById(R.id.textView);
tv.setText("some text");
}

public class MyActivity extends Activity
{
/**
* Called when the activity is first created.
*/
ProgressBar progressBar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
progressBar = (ProgressBar) findViewById(R.id.pb);
TextView view=(TextView) findViewById(R.id.myt);
new Task(view).execute();
}
by passing TextView instance in constructor we can use in progressbar
private class Task extends AsyncTask<Void, Integer, Void> {
TextView view;
private Task(TextView textView) {
this.view= textView;
}
int myProgress;
#Override
protected void onPreExecute() {
myProgress = 0;
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
Toast.makeText(MyActivity.this,
"onPostExecute", Toast.LENGTH_LONG).show();
super.onPostExecute(aVoid);
}
#Override
protected void onProgressUpdate(Integer... values) {
progressBar.setProgress(values[0]);
view.setText("Value"+myProgress);
super.onProgressUpdate(values);
}
#Override
protected void onCancelled() {
super.onCancelled(); //To change body of overridden methods use File | Settings | File Templates.
}
#Override
protected Void doInBackground(Void... voids) {
while (myProgress < 100) {
myProgress++;
publishProgress(myProgress);
SystemClock.sleep(100);
}
return null;
}
}
}

Related

Get a TextView in an AsyncTask - Android

I want to publish the result of my AsyncTask (a string) in a textView.
Here is my Main:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ReadRss readRss=new ReadRss(this);
readRss.execute();
......
}
Here is my AsyncTask:
public class ReadRss extends AsyncTask<Void,Void,Void> {
public ReadRss(Context context){
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(Void aVoid) {
}
#Override
protected Void doInBackground(Void... params) {
ProcessXml();
return null;
}
private void ProcessXml() {
//HERE CREATE MY STRING
String myresult="example";
TextView txt_ris = (TextView)findViewById(R.id.txt_ris); <---HOW CAN I DO THIS?
txt_ris.setText(myresult);
}
}
}
}
FindViewById don't work in the AsyncTask so how can i get the TextView in here?
Maybe i can pass it as a paramiter in the AsyncTask, What is the syntax?
You need to place UI work in onPostExecute method, since doInBackground executes in not UI thread
public class ReadRss extends AsyncTask<Void,Void,String> {
public ReadRss(Context context){
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String string) {
TextView txt_ris = (TextView)findViewById(R.id.txt_ris);
txt_ris.setText(myresult);
}
#Override
protected String doInBackground(Void... params) {
return ProcessXml();
}
private String ProcessXml() {
//HERE CREATE MY STRING
return "example";
}
}
For your TextView to be correctly referenced you need a context and you already have a reference to your starting Activity in your AsyncTask constructor, so you can do something like:
public class ReadRss extends AsyncTask<Void,Void,Void> {
private TextView tv;
private YourStartingActivity activity;
public ReadRss(Context context){
activity = (YourStartingActivity)context;
tv = (TextView)activity.findViewById(R.id.txt_ris)
}
#Override
protected void onPreExecute() {
...
}
#Override
protected void onPostExecute(Void aVoid) {
(follow Michael Spitsin instructions here)
}
#Override
protected Void doInBackground(Void... params) {
...
}
}

cannot show Dialog in onClick

I have a function for copy file in storage. When I click to copy Button, the method copy action will execute. This method below:
public void actionCopy() {
Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.progress_layout);
TextView progressTitle = (TextView) dialog.findViewById(R.id.progress_title);
progressTitle.setText("Copying...");
final ProgressBar progressBar = (ProgressBar) dialog.findViewById(R.id.progress_bar);
progressBar.setMax(listData.size());
progressBar.setProgress(0);
dialog.show();
for(int i = 0; i < listData.size(); i++) {
String value = new CopyDataUtils(listData.get(i)).execute().get();
progressBar.setProgress(i + 1);
Log.i(TAG, value);
}
}
And the CopyDataUtils AsyncTask:
public class CopyDataUtils extends AsyncTask<Void, Void, String> {
private DataItem item;
public CopyDataUtils(DataItem item) {
this.item = item;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
//...code copy file here
return ...;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
So My problem is: When actionCopy execute, I want dialog show display. But did not happen. After for(..) executed, the dialog was show.
What something wrong?. Is there any suggestion for show dialog before execute multi thread copy data?.
Sorry my bad english!
**UPDATE:
I tried put dialog to AsyncTask and show it in to method onPreExecute. But nothing change.
Problem is new CopyDataUtils(listData.get(i)).execute().get();. It blocks the UI thread and waits if necessary for the computation to complete, and then retrieves its result.
The way you are using AsyncTask and dialog is completly wrong. You should move these code to AsynTask. On onPreexecute you should show dialog. doInbackground do you task and at onPostexecute hide dialog.
u should show the progress bar in onPreEcecute() of Asynctask
public void onPreExecute()
{
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("your content");
progressDialog.setMax(listData.size());
progressDialog.setProgress(0);
for(int i = 0; i < listData.size(); i++) {
String value = new CopyDataUtils(listData.get(i)).execute().get();
Log.i(TAG, value);
progressDialog.show();
}
#Override
protected String doInBackground(Void... params) {
return ...;
}
#Override
public void onPostExecute(String s)
{
progressBar.setProgress(i + 1);
}
You should make your ProgressBar as a global variable, then update the progress in onPostExcute() of AsyncTask
public void YouActiviy() {
ProgressBar progressBar;
int i = 0;
public onCreate(){
....
}
public void actionCopy() {
...
progressBar = (ProgressBar) dialog.findViewById(R.id.progress_bar);
...
dialog.show();
for(int i = 0; i < listData.size(); i++) {
new CopyDataUtils(listData.get(i)).execute();
//progressBar.setProgress(i + 1);
}
}
public class CopyDataUtils extends AsyncTask<Void, Void, String> {
...
#Override
protected void onPostExecute(String s) {
// update your progressbar here
progressBar.setProgress(i++);
super.onPostExecute(s);
}
}
}
For easy way, you follow this tutorial that will give you the correct way to use AsyncTask with ProgressBar
Hope this help
You should set progress in onProgressUpdate(), try this:
protected ProgressDialog mProgressDialog;
private class copyData extends AsyncTask<String, Integer, String> {
protected String doInBackground(Void... params) {
//copy data here
return ...;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgress(progress[0]);
}
protected void onPostExecute(String result) {
try {
if ((mProgressDialog != null) && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} finally {
mProgressDialog = null;
}
}
}

Progress Dialog for AsyncTask - Android

I'm trying to show a progress dialog while the twitter feed is loading up...However the progress dialog remains on screen when the twitter feed appears. Any help is much appreciated.
public class MainActivity extends ListActivity {
final static String twitterScreenName = "CFABUK";
final static String TAG = "MainActivity";
private AsyncTask<Object, Void, ArrayList<TwitterTweet>> tat;
boolean done;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
done=false;
AndroidNetworkUtility androidNetworkUtility = new AndroidNetworkUtility();
if (androidNetworkUtility.isConnected(this)) {
TwitterAsyncTask syn=new TwitterAsyncTask();
syn.execute(twitterScreenName,this);
ProgressDialog pd = new ProgressDialog(MainActivity.this);
pd.setMessage("loading");
pd.show();
do {
if(!(syn.getStatus()==AsyncTask.Status.RUNNING)) {
pd.dismiss();
pd.cancel();
done=true;
}
} while(done=false);
} else {
Log.v(TAG, "Network not Available!");
}
}
}
You must call ProgressDialog show() method on AsyncTasks onPreExecute(). For example:
class MyTask extends AsyncTask<Void, Void, Void> {
ProgressDialog pd;
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("loading");
pd.show();
}
#Override
protected Void doInBackground(Void... params) {
// Do your request
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (pd != null)
{
pd.dismiss();
}
}
}
You must use a onPreExecute and onPostExecute of AsyncTask class. For example:
class AsyncData extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
// init progressdialog
}
#Override
protected Void doInBackground(Void... arg0) {
// get data
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// dismiss dialog
}
}
The methods onPreExecute(), doInBackground() and onPostExecute() of AsyncTask are used for purpose that you mentioned -
public class MainActivity extends ListActivity {
final static String twitterScreenName = "CFABUK";
final static String TAG = "MainActivity";
private AsyncTask<Object, Void, ArrayList<TwitterTweet>> tat;
boolean done;
Context context;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
done=false;
context = this;
new NetworkTask().execute();
}
}
class NetworkTask extends AsyncTask<String, String, String>
{
Context ctx = context ;
#Override
protected void onPreExecute()
{
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Working ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args)
{
//Do your background work here and pass the value to onPostExecute
AndroidNetworkUtility androidNetworkUtility = new AndroidNetworkUtility();
if (androidNetworkUtility.isConnected(ctx)) {
TwitterAsyncTask syn=new TwitterAsyncTask();
syn.execute(twitterScreenName,this);
while(done)
{
if(!(syn.getStatus()==AsyncTask.Status.RUNNING))
{
done=true;
}
else
{
Log.v(TAG, "Network not Available!");
}
}
return done + "";
}
protected void onPostExecute(String result)
{
//Do something with result and close the progress dialog
pDialog.dismiss();
}
ProgressBar is best alternative for ProgressDialog. A user interface element that indicates the progress of an operation.
ProgressDialog is deprecated in latest versions.
For more info see android developer official site: https://developer.android.com/reference/android/widget/ProgressBar.html

Horizontal progress bar does not update its status

I am trying to show horizontal progress bar "Not ProgressDialog" on my activity like this
here is what my xml file contains
<ProgressBar
android:id="#+id/pdialog"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
/>
I am trying to update its status using AsyncTask Class by setting pdialog.setProgress() but its not showing any progress, it works with progressdialog but not with horizontal progress bar.
public class MainActivity extends Activity {
private SQLiteDatabase db;
private Cursor cursor;
private ProgressBar pdialog;
private ImageButton btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start);
btn = (ImageButton) findViewById(R.id.startbtn);
pbar = (ProgressBar) findViewById(R.id.progressBar1);
pdialog = (ProgressBar) findViewById(R.id.pdialog);
pdialog.setMax(100);
pdialog.setProgress(20);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pdialog.setVisibility(View.VISIBLE);
new DownloadFilesTask().execute();
}
});
}
private class DownloadFilesTask extends AsyncTask<Void, Integer, Integer> {
int load = 1;
protected Integer doInBackground(Void... params) {
try {
load = 10 * i;
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
pdialog.setProgress(load);
}
});
}
} catch (Exception e) {
}
}
protected void onProgressUpdate(Integer... progress) {
if (progress[0] == 100) {
pdialog.setVisibility(View.INVISIBLE);
}
}
protected void onPostExecute(Integer params) {
}
}
}
If load variable gets changed correctly:
Instead of this:
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
pdialog.setProgress(load);
}
});
You could use:
publishProgress(load);
which would automatically call on UI Thread:
protected void onProgressUpdate(Integer... progress) {
int p = progress[0];
if (p >= 100) {
pdialog.setVisibility(View.INVISIBLE);
}else{
pdialog.setProgress(p);
}
}
UPDATE:
remove android:indeterminate="true" as pointed out in other answer.
In your layout file please remove the following attribute android:indeterminate="true" from ProgressBar element.
I had the same question, but
I found the problem is the interface View.OnClickListener().
When the pbar was put out of the btn.setOnClickListener(new View.OnClickListener() {}), it worked well. Otherwise, it did not update.
Then, I made a constructor which passed the pbar into the OnXXXClickListener.
private class OnXXXClickListener implements View.OnClickListener() {
private ProgressBar bar;
public OnXXXClickListener(ProgressBar bar) {
this.bar = bar;
}
#Override
public void onClick(View v) {
bar.setProgess(50);
new DownloadFilesTask().execute();
}
}
Then the pbar could work well.

ProgressDialog does not disappear in android app

I have an android application which in its main activity, data are adapted from sqlite db and shown in list view. I tried to use Progress dialog to show 'loading' message to user during fetching data from db. But the dialog does not disappear.
Here is the code :
public class BirthdayAlarmActivity extends ListActivity {
List<BirthdayContact> listofAvailableBirthdays;
ProgressDialog pDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.birthday_list);
listofAvailableBirthdays=new ArrayList<BirthdayContact>();
ReinitializeList();
}
#Override
protected void onResume() {
ReinitializeList();
}
void ReinitializeList()
{
new LoadListView().execute();
if(listofAvailableBirthdays.size()>0)
{
//get ready the adapter
ArrayAdapter<BirthdayContact> ara=
new MyArrayAdapter(BirthdayAlarmActivity.this,listofAvailableBirthdays);
//set the adapter
setListAdapter(ara);
}
}
public class LoadListView extends AsyncTask<Void, Void, Void>
{
//ProgressDialog pDialog;
#Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(
BirthdayAlarmActivity.this);
pDialog.setMessage("Please wait..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
}
protected Void doInBackground(Void... unused) {
runOnUiThread(new Runnable() {
public void run() {
// increment current page
listofAvailableBirthdays.clear();
listofAvailableBirthdays=BirthdayHandler.GetTenBirthDays(BirthdayAlarmActivity.this);
}
});
return (null);
}
protected void onPostExecute(Void unused) {
// closing progress dialog
pDialog.dismiss();
}
}
I'm not familiar with the technique you're using, but I'll share what works for me:
final ProgressDialog progress = ProgressDialog.show(activity, "",
activity.getString(R.string.please_wait), true);
new Thread(new Runnable() {
#Override
public void run()
{
try {
--- network activity to retrieve information ---
}
finally {
activity.runOnUiThread(new Runnable() {
#Override
public void run()
{
if ((progress != null) && progress.isShowing())
progress.dismiss();
}
});
}
}
}).start();
I think the problem here is that you're referring to your pDialog and trying to create it in a different class than the one you've declared it in.
You should try using showDialog, dismissDialog and onCreateDialog methods to add a layer of abstraction and that the dialog is being called in the correct class/thread. You can use a Handler aswell as an alternative.
try something like this:
public class BirthdayAlarmActivity extends ListActivity {
List<BirthdayContact> listofAvailableBirthdays;
ProgressDialog pDialog;
static final int LOADING_DIALOG = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.birthday_list);
listofAvailableBirthdays=new ArrayList<BirthdayContact>();
ReinitializeList();
}
#Override
protected void onResume() {
ReinitializeList();
}
void ReinitializeList()
{
new LoadListView().execute();
if(listofAvailableBirthdays.size()>0)
{
//get ready the adapter
ArrayAdapter<BirthdayContact> ara=
new MyArrayAdapter(BirthdayAlarmActivity.this,listofAvailableBirthdays);
//set the adapter
setListAdapter(ara);
}
}
#Override
protected Dialog onCreateDialog(int id)
{
switch(id)
{
case LOADING_DIALOG:
// Showing progress dialog before sending http request
pDialog = new ProgressDialog(
BirthdayAlarmActivity.this);
pDialog.setMessage("Please wait..");
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
return pDialog;
}
}
public class LoadListView extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
showDialog(LOADING_DIALOG);
}
protected Void doInBackground(Void... unused) {
runOnUiThread(new Runnable() {
public void run() {
// increment current page
listofAvailableBirthdays.clear();
listofAvailableBirthdays=BirthdayHandler.GetTenBirthDays(BirthdayAlarmActivity.this);
}
});
return (null);
}
protected void onPostExecute(Void unused) {
dismissDialog(LOADING_DIALOG);
}
}
If this fails, you should look int using messaging via the Handler class.

Categories

Resources