I have to wait some seconds in my Android App and I want to show a progress bar during this time, how can I do this?
for example :
#Override
protected void onCreate(Bundle savedInstanceState) {
timeForShow(5 //second);
}
.
.
.
private void timeForShow(long mytime){
myprogress.setVisibility(View.VISIBLE);
Waiting for mytime...
myprogress.setVisibility(View.GONE);
}
this is my code but it does not work:
Long timerforprogressbar ;
#Override
protected void onCreate(Bundle savedInstanceState) {
timerforprogressbar = (long) 5000 ;
new MyProgressBar().execute((Void)null);
}
.
.
.
class MyProgressBar extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
progressbar.setVisibility(View.VISIBLE);
try {
Thread.sleep(timerforprogressbar);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
progressbar.setVisibility(View.GONE);
}
}
my progress bar :
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:indeterminateDrawable="#drawable/progress" >
</ProgressBar>
progressbar is my progress bar,plz help me,tnx.
For your specific use case it would be simpler to use a Handler:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
progressbar.setVisibility(View.GONE);
}
}, timerforprogressbar);
You did not mention how your progressbar is constructed but if you simply want an indeterminate progress to show, then constructing it programatically would be the most simple thing to do I think.
private ProgressDialog working_dialog;
private void showWorkingDialog() {
working_dialog = ProgressDialog.show(context, "","Working please wait...", true);
}
private void removeWorkingDialog() {
if (working_dialog != null) {
working_dialog.dismiss();
working_dialog = null;
}
}
That would make the code look like:
showWorkingDialog();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
removeWorkingDialog();
}
}, timerforprogressbar);
You can always use the CountDownTimer:
public void timer() {
countDownTimer=new CountDownTimer(20000, 1000) { //display a delay of 20 seconds
public void onTick(long millisUntilFinished) {
if (somethingToBreakTheCount)
countDownTimer.onFinish();
txtDebug.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
txtDebug.setText("Done!");
finish();
}
}.start();
}
// We can achieve this by using Coroutines.
// Simply start a coroutine and change the progress of progressbar by changing the dispatcher context after few milliseconds.
// Here I am showing the progress for 1 second before moving to next fragment.
CoroutineScope(Dispatchers.IO).launch {
for (i in 0..100) {
delay(10)
withContext(Dispatchers.Main) {
binding.progressBar.progress = i
}
}
//Navigate to next fragment using nav contorller or with Intents for next Activity
navController.navigate(R.id.action_startFragment_to_listFragment)
}
Updating progress dialog in Activity from AsyncTask
There re is a method for async tasks for progress updates.
Here is a link to a better post on it
As a simpler solution than an AsyncTask, you can always look into using a CountDownTimer for this action.
If you are performing a task in AsyncTask doInBackground(), then you can initiate your progressBar in onPreExecute() and disable it in onPostExecute().
Related
I am working on an android app in which i want to hide my image view after some interval. i am using this code but it is not hiding. can anybody tell me how i can hide it ???
showtrue1.setBackgroundResource(R.drawable.ticktrue);
showtrue1.setVisibility(View.VISIBLE);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
showtrue1.setVisibility(View.GONE);
Try CountDownTimer:
new CountDownTimer(1000, 100) {
public void onTick(long millisUntilFinished) {
// implement whatever you want for every tick
}
public void onFinish() {
showtrue1.setVisibility(View.GONE);
}
}.start();
You can use async Task also to solve your problem . In its backgound function make a thread sleep for particular second and in the post method make trhe visibility gone for your image viiew.
Call the execute method in your oncreate
new MyAsyncTask().execute();
and make an inner class as defined below:
private class MyAsyncTask extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute(){
// show your progress dialog
showtrue1.setBackgroundResource(R.drawable.ticktrue);
showtrue1.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(Void... voids){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void params)
{
showtrue1.setVisibility(View.GONE);
}
}
Create a separate thread that sleeps for 1 seconds then call runOnUiThread to hide the view.
Thread thread = new Thread() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do some stuff
showtrue1.setVisibility(View.GONE);
}
});
}
};
In my code I have a thread. You can see the code of thread,
public class MainAsyncHome extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return null;
}
#Override
protected void onPostExecute(String xml) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
I run this thread in my main activity onCreate method as following way
new MainAsyncHome().execute(null);
But I want to give time out for this thread. It means when main activity run I want late to run this thread. I know it can do using sleep method. But How I can late for running this thread just like that way.
I'm stuck with this problem.
pls give me answer. Thanks
Use Handler class, and define Runnable handleMyAsyncTask that will contain code executed after 3000 msec delay:
mHandler.postDelayed(MainAsyncHome, 1000*3); //Delay of three seconds
The answer is taken from here.
To put it in the code:
private final static int INTERVAL = 1000 * 3; //3 seconds
Handler m_handler;
Runnable MainAsyncHome = new Runnable()
{
#Override
public void run() {
doSomething();
m_handler.postDelayed(MainAsyncHome, INTERVAL);
}
}
void startRepeatingTask()
{
MainAsyncHome.run();
}
void stopRepeatingTask()
{
mHandler.removeCallback(MainAsyncHome);
}
Hope it works.
I normally use CountDownTimer, suppose a 3 seconds of delay:
CountDownTimer timer = new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
//do things, start your Task
//remember we are still in the main thread!
}
}.start();
Get more info at:
http://developer.android.com/reference/android/os/CountDownTimer.html
Use a CountDownTimer like this.
Start your timer in onCreate.
CountDownTimer timer=new CountDownTimer(Delay,TimeIntervalToCallOnTick) {
#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
//start your asynctask
}
};
CASE: I have a button and list-view in the activity. On click of the button I have added a click listener, which starts a new thread in which I update the progress bar. After the job is done i.e. progress bar is done 100%, I want to update the list-view.
final OnClickListener mStartScan = new OnClickListener() {
#Override
public void onClick(View v) {
// prepare for a progress bar dialog
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(false);
progressBar.setMessage(getString(R.string.text_scanning_inbox));
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(totalSms);
progressBar.show();
progressBarStatus = 0;
Thread progressThread = new Thread(new Runnable() {
public void run() {
while (progressBarStatus < totalSms) {
// process some tasks
progressBarStatus = someStuff();
// Update the progress bar
progressBarHandler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressBarStatus);
}
});
}
if (progressBarStatus >= done) {
// sleep 1 seconds, so that you can see the 100%
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// close the progress bar dialog
progressBar.dismiss();
// this method updates the list
populateList();
}
}
});
progressThread.start();
// try {
// progressThread.join();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } finally {
// populateList();
// }
}
};
PROBLEM: When I update the listview after completion of the task and dismissing progress bar, I get an exception which says that the view can be updated only from the thread in which it is created.
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
WHAT ELSE I TRIED: I tried waiting for the thread which is running progress bar to complete and then update listview from the main thread.
try {
progressThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
populateList();
}
However, this does not work. It does not show the progress bar at all.
I used this:
private ProgressDialog progressBar;
class MyTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar = new ProgressDialog(getApplicationContext());
progressBar.setMessage("please, waiting ...");
progressBar.setCancelable(false);
progressBar.show();
}
#Override
protected String doInBackground(String... params) {
try {
// get info and set them in my model ...
} catch (Exception e) {
e.printStackTrace();
}
return params[0];
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (null != progressBar && progressBar.isShowing()) {
progressBar.dismiss();
}
// do work in UI and set info adapter and refresh list ...
populateList();
myListView.invalidateViews();
}
}
for more information:
http://developer.android.com/reference/android/widget/ArrayAdapter.html#notifyDataSetChanged%28%29
Only the original thread that created a view hierarchy can touch its views.
Here original thread refers to the ui thread. You are attempting to update ui inside a thread which is not possible.
You cannot update ui from the back ground thread. You can use runOnUiThread .
runOnUiThread(new Runnable() //run on ui threa
{
public void run()
{
}
});
I would suggest you to use asynctask
You use use asynctask for this purpose. The onPreExecute(), onPostExecute() are invoked on the ui thread and you can use the same to update ui. You can do your background computation in doInbackground()
http://developer.android.com/reference/android/os/AsyncTask.html
Check the topic under heading The 4 steps.
class TheTask extends AsyncTask<Void,Void,Void>
{
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
// background computation and publish progress
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
// update progress bar
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// cancel the progress bar
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
//display progress bar
}
}
Load asynctask on the ui thread
new TheTask().execute().
The error you are receiving is because of the fact that you are trying to change the UI components on a secondary thread. You should read this for more information on how to use threads on Android.
You can use the Activity method runOnUIThread() to call the populateList() method or whatever makes the updates on the UI(main) thread. If you read the doc mentioned above, you will find out more about this.
In my application when i click on Button it sometimes shows the progressdialog and sometimes not show the progressdialog on click of button.
Asynchronous Task code is:
public class LoadData extends AsyncTask<Void, Void, Void>
{
ProgressDialog pd;
#Override
protected void onPreExecute()
{
pd = ProgressDialog.show(MainActivity.this, "", "Loading...");
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
LoadActivities(); // function to load data from url
}
});
return null;
}
#Override
protected void onPostExecute(Void unused)
{
pd.dismiss();
}
}
and on button click event call this as:
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new LoadMoreData().execute(null);
}
});
the wrong think you are doing is that in doInBackground you use runOnUiThreade . just remove that from your code . It solves your problem.
never use any thread in doInBackground.
Why you have taken run method again in doInBackground, doInBackground method performs computation on a background thread, so no need to take runOnUiThread
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
LoadActivities(); // function to load data from url
}
});
Just write
protected Boolean doInBackground(final String... args) {
try {
LoadActivities();
return true;
} catch (Exception e) {
Log.e("tag", "error", e);
return false;
}
}
And also change new LoadMoreData().execute(); don't write null
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new LoadMoreData().execute();
}});
Nirali's answer seems correct, just to make further explaination and some edits.
Progress Dialog will be shown by the time doInBackground method returns value. and in your code it just create another thread, and completes execution, so to display progress dialog by the time LoadActivities exectues, execute this statement in the same thread doInBackground executes, so change to following:
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
MainActivity.this.runOnUiThread(new Runnable() {
LoadActivities(); // function to load data from url
return null;
}
i got this progress dialog code:
new Thread() {
#Override
public void run() {
try {
sleep(1000);
}
catch (Exception e) {
Log.e("tag", e.getMessage());
}
// dismiss the progress dialog
progressDialog.dismiss();
}
}.start();
and i got text that will apear after some httprequest actions:
editText2.setText(stringEr);
how do i sync between them? i want that the text will be hidden untill the progress will finish
tnx!
You have to use Handlers to update your UI. A little modification here,
new Thread()
{
#Override
public void run()
{
try
{
//Instead of sleep, call your http request method here.
handler.sendEmptyMessage(0);
}
catch (Exception e)
{
Log.e("tag", e.getMessage());
}
// dismiss the progress dialog
progressDialog.dismiss();
}
}.start();
And create a handler in onCreate(),
Handler handler=new Handler()
{
public void handleMEssage(Message msg)
{
if(msg.what==0)
editText2.setText(stringEr);
}
};
i think you should use AsyncTask for that and you can hide in OnPreExecute Method i mean when asynctask in started and show in OnPostExecute method. after complete the progress.
Android skip the painful Threading concept, Use Asyntask class.
http://developer.android.com/reference/android/os/AsyncTask.html
private class UIOperation extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
//show dialog
}
#Override
protected String doInBackground(String... params) {
//collect data
return null;
}
#Override
protected void onPostExecute(String result) {
//dismiss dialog
//update UI
}
}