Is there a slicker/simpler way of doing the following? I have a method in a class that shows a progressbar while a thread runs. This code works but it just seems a little overly clunky having 3 steps.
private void pause() {
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressBar.setVisibility(View.VISIBLE);
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
//do stuff
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressBar.setVisibility(View.GONE);
}
});
}
This does not show a progress bar while a thread runs.
Your thread can run 10 seconds but the visibility of the ProgressBar will only blink if you can see it at all.
Instead, you should hide only once the thread has completed, so this would be correct:
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressBar.setVisibility(View.VISIBLE);
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
//do stuff
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressBar.setVisibility(View.GONE);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
For a "slicker" way, you could use an AsyncTask which was created for this very task. Example:
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Guaranteed to run on the UI thread
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(Void... params) {
// Do stuff
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// Guaranteed to run on the UI thread
mProgressBar.setVisibility(View.GONE);
}
}.execute();
Here you can use the handlers concept to communicate with UI Thread.
I.e,
Handler handler=new Handler(){
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what){
case 1:
mProgressBar.setVisibility(View.VISIBLE);
break;
case 2:
mProgressBar.setVisibility(View.GONE);
break;
}
}
}
new Thread(new Runnable() {
#Override
public void run() {
Message processStart = handler.obtainMessage(1);
processStart.sendToTarget();
try {
//do stuff
} catch (InterruptedException e) {
e.printStackTrace();
}
Message processStart = handler.obtainMessage(2);
processStart.sendToTarget();
}
}).start();
I hope this one will helps you :)
Related
I have an array of ImageView with a number of invisible elements that I would like to make visible sequentially (i.e. make the first one visible, wait for half a second, make the next one visible, and so on) using either Thread or runOnUiThread.
I have tried the following:
Thread th = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
im1.setVisibility(View.VISIBLE);
Thread.sleep(500);
im2.setVisibility(View.VISIBLE);
Thread.sleep(500);
im3.setVisibility(View.VISIBLE);
Thread.sleep(500);
im4.setVisibility(View.VISIBLE);
Thread.sleep(500);
im5.setVisibility(View.VISIBLE);
Thread.sleep(1000);
bottom.setVisibility(View.VISIBLE);
} catch (Exception e) {
Log.e("ERR", e.getMessage());
}
}
});
th.start();
and
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
im1.setVisibility(View.VISIBLE);
Thread.sleep(500);
im2.setVisibility(View.VISIBLE);
Thread.sleep(500);
im3.setVisibility(View.VISIBLE);
Thread.sleep(500);
im4.setVisibility(View.VISIBLE);
Thread.sleep(500);
im5.setVisibility(View.VISIBLE);
Thread.sleep(1000);
bottom.setVisibility(View.VISIBLE);
} catch (Exception e) {
Log.e("ERR", e.getMessage());
}
}
});
But I don't get the desired effect. What happens is that all images are made visible at the same time instead of one after the other.
How can I solve this?
int counter=1; //Global variable
private void visibleImageview()
{
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if(counter==1)
{
im1.setVisibility(View.VISIBLE);
}
else if(counter==2)
{
im2.setVisibility(View.VISIBLE);
}
else if(counter==3)
{
im3.setVisibility(View.VISIBLE);
}
++counter;
if(couter<=3)
visibleImageview();
}
}, 3000);
}
Solved it. This is how I managed to do it:
Handler handler = new Handler();
im1.setVisibility(View.VISIBLE);
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
im2.setVisibility(View.VISIBLE);
}
});
}
},500);
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
im3.setVisibility(View.VISIBLE);
}
});
}
},1000);
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
im4.setVisibility(View.VISIBLE);
}
});
}
},1500);
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
im4.setVisibility(View.VISIBLE);
}
});
}
},2000);
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
bottom.setVisibility(View.VISIBLE);
}
});
}
},3000);
I want to implement ProgressBar in Android and when I execute the program, Progressbar should show for up to 2 seconds. I can't get it to work properly but I can't figure out why.
public void myThread(){
Thread th=new Thread(){
#Override
public void run(){
try
{
while(mRunning)
{
Thread.sleep(10L);//10s wait
YourCurrentActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
//DISMISS PROGRESS BAR HERE
mRunning=false;
}
});
}
}catch (InterruptedException e) {
// TODO: handle exception
}
}
};
th.start();
}
I have tried this but it does not giving me output as i want.
That what handlers are for in Android.
Example:
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
// cancel or dismiss your progressbar
}
}, 2000);
I am using onNewIntent when I am scanning NFC tags. I want to show ProgressDialog while tag is scanned. I tried use a thread but it crashed my app. Is there some way how I can show progressDialog when onNewIntent starts?
public void onNewIntent(Intent intent) {
setIntent(intent);
Thread scanning = new Thread(new Runnable() {
public void run() {
ScanDialog = ProgressDialog.show(BorrowActivity.this,
"Scanning...", "scanning");
}
});
scanning.start();
.
. //next code doing something
.
}
You cannot update or use a UI on another thread:
solution:
Call the Main thread and update the UI inside there
Thread scanning = new Thread(new Runnable() {
public void run() {
runOnUiThread(new Runnable()
{
public void run()
{
ScanDialog = ProgressDialog.show(BorrowActivity.this,
"Scanning...", "scanning");
}
});
}
});
Finally I fixed it with asyncTask.
public void onNewIntent(Intent intent) {
setIntent(intent);
ScanDialog = ProgressDialog.show(BorrowActivity.this,
"Scanning...", "Scanning");
try {
new DoBackgroundTask().execute();
} catch (Exception e) {
//error catch here
}
ScanDialog.dismiss();
And AsyncTask:
private class DoBackgroundTask extends AsyncTask<Integer, String, Integer> {
protected Integer doInBackground(Integer... status) {
//do something
}
protected void onProgressUpdate(String... message) {
}
protected void onPostExecute(Integer status) {
}
}
I want to turn on/off the flash light in infinite loop, so when it turned on it should wait for 5 seconds and then turned off then wait 5 seconds to turned on again, and so on...
how I can do that?
here is my code:
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// num = Integer.parseInt(n.getText().toString());
while(bl){
if(camera == null){
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
turnOn();
}
});
}
}).start();
}
else{
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
turnOff();
}
});
}
}).start();
}
}
}
});
I would recommend not using Threads in order to achieve this. Why not use the Runnable class and post it with a delay via a Handler? For example:
Handler handler = new Handler(); // make this a member variable of your class
boolean isOn = false; // make this a member variable of your class
final Runnable flashRunnable = new Runnable() {
#Override
public void run() {
if (isOn) {
turnOff();
isOn = false;
} else {
turnOn();
isOn = true;
}
handler.postDelayed(flashRunnable, 5000);
}
};
handler.postDelayed(flashRunnable, 5000);
If you need to run the code inside the Runnable on the UI thread, you even call postDelayed on a View instead of creating a Handler
Try something like so, using Executors instead of (ugly) Thread.sleep():
boolean cameraOn = true
final Runnable runnable = new Runnable() {
#Override
public void run() {
// your logic here:
// if (cameraOn) ...
// else ...
// cameraOn = !cameraOn
}
};
Executors.newScheduledThreadPool(1).schedule(new Runnable() {
#Override
public void run() {
runnable.run();
}
}, 5, TimeUnit.SECONDS);
I am trying to execute the method doSomeWork(); after the ProgressDialog dismisses in my method printing();which seems to be overlapped by the other method and the dialog is not showed up. If I comment method doSomeWork(); the dialog is displayed correctly until the thread is finished.
Here is my method printing();
public void printing()
{
final ProgressDialog printingDialog = ProgressDialog.show(this, "Printing...", "Please wait", true, false);
new Thread(new Runnable() {
#Override
public void run()
{
//something big executing here
}
}).start();
}
He is my method doSomework():
public void doSomeWork(){
Thread receiptPrint = new Thread(new Runnable() {
#Override
public void run() {
//something here
runOnUiThread(new Runnable() {
#Override
public void run() {
//another dialog here
}
});
}
});
}
Here you can see the how I am calling those two methods:
private OnClickListener onClickPrint = new OnClickListener() {
public void onClick(final View v) {
Log.d("Button","Clicked on Print Order Button");
printing();
doSomeWork();
Does anyone know how could I execute doSomeWork() only when printing(); will be completely finished?
This is one of the purposes of an AsyncTask. It would look similar to this:
public void onClick(final View v) {
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
//Show your progress dialog in here
super.onPreExecute();
}
#Override
protected Void doInBackground( Void... params ) {
printing();
return null;
}
#Override
protected void onPostExecute( Void result ) {
//Dismiss your progress dialog here
doSomeWork();
}
}.execute();
}
Instead of using thread you can use asynchronous task. Show the progress dialog in the preexecute method call the printing method inside the background method after completing printing operation call the doSomeWork() inside the postexecute method.
You can use Handler for that in android. for example consider the following piece of code. you can dismiss the dialogs inside handlers. may it work for you.
private void printing(){
Thread receiptPrint = new Thread(new Runnable() {
#Override
public void run() {
retrieveEmails();
runOnUiThread(new Runnable() {
#Override
public void run() {
try{
//here your code executes
//after code executes do following:
uiHandler.sendEmptyMessage(0);
}catch(Exception ex){
errorHandler.sendEmptyMessage(0);
}
}
});
}
});
receiptPrint.start();
}
final Handler uiHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
//here execute doSomeWork()
}
};
final Handler errorHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
//do other stuff
}
};