There is a ProgressDialog in my app. It is running but after finishing process does not close. Where is the error, I'm doing.
Thanks.
button.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
progressdialog.show();
new Thread(new Runnable() {
public void run() {
try {
// doing something...
progressdialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
});
do this......
button.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
progressdialog.show();
new Thread(new Runnable() {
public void run() {
try {
// doing something...
hm.sendEmptyMessage(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
});
Handler hm = new Handler()
{
public void handleMessage(Message msg)
{
progressdialog.dismiss();
}
}
Thanks.
progressdialog.setVisible(false);
if pricessdialog instanse of JDialog
Call progressdialog.dismiss(); from the main thread;
The right way of doing any work in background while showing the progress dialog is using AsyncTask with ProgressDialog bounded. See here. Remember, that you can not modify the UI from the thread, which is not UI thread.
The process dialog can also be dismissed by calling following method.
progressdialog.cancel();
Related
I am trying to use swipe refresh layout to update some data.
All works fine but a small bug that I can't seem to solve
When I pull to refresh, the animation gets frozen.
I have implemented it this way:
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myRefreshLayout.setRefreshing(false);
}
});
and also tried this:
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
myRefreshLayout.post(new Runnable() {
#Override
public void run() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
myRefreshLayout.setRefreshing(false);
}
});
}
});
}
});
but the animation remains frozen until the everything is done, and then it just vanishes (because it hits the setRefreshing(false))
After searching a little, I thought it could be the UI that is waiting for the stuff to finish, so I tried to implement it this way:
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new Thread(new Runnable() {
#Override
public void run() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
myRefreshLayout.setRefreshing(false);
}
});
}
});
}
});
}
What happens in this case is that the refresh indicator never vanishes, so I guess it is not calling the runOnUiThread
I tried the same thing with the main looper (handler) instead of the runOnUiThread with the same effect.
Is there any neat way of implementing this?
Am I missing some detail?
I tried the steps described above and I also looked on Stack Overflow for similar issues to no avail.
Thanks!
It's right to do refreshing on background thread,and setRefreshing(false) on main thread. The problem is you forgot to call start() after new thread.
myRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
new Thread(new Runnable() {
#Override
public void run() {
// Do some stuff
// Sleep as a demonstrator of the issue
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
myRefreshLayout.setRefreshing(false);
}
});
}
}).start();// start the thread here
}
});
}
After click button I would like to change its color, then wait one second and change its color back.
This is my code:
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
t.join();
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
}
It doesn't work. I've checked it with more complex code and debugger and it looks like all UI changes are made collectively after finish this function.
I've found this thread: apply ui changes immediately and tried to put setBackgroundColor() and setClickable() into runOnUiThread function:
runOnUiThread(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
}
});
But it also doesn't work. What should I do?
Something like this :
private final Handler handler = new Handler();
public void click(final View view) {
view.setBackgroundColor(Color.parseColor("#0000ff"));
view.setClickable(false);
handler.postDelayed(() -> {
view.setBackgroundColor(Color.parseColor("#e2e2e2"));
view.setClickable(true);
}, 1000);
}
#Override protected void onPause() {
super.onPause();
handler.removeCallbacks(null);
}
The question is not very clear. However, I am trying to summarize the question that I have understood from your question.
You are trying to set a button's background color on clicking on it and change it back after some time. If this is the situation, then I think your idea of how threads work is wanting.
In your code, the button will change the color immediately as the sleep that you are using is running in another thread (other than UI thread). The code is executed correctly, however, you cannot see the effect of the Thread.sleep as its running in a separate thread.
So all you need to do here is to change the background color again inside the thread. Modify your code like the following.
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
This should work.
I have created a demo trying to show what the code will do.
However, using Handler in case of updating UI elements in this specific case is recommended. Please see the comments below.
public void click(final View view) throws InterruptedException {
final Button btn = findViewById(view.getId());
btn.setBackgroundColor(Color.parseColor("#0000ff"));
btn.setClickable(false);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
btn.setBackgroundColor(Color.parseColor("#e2e2e2"));
btn.setClickable(true);
}
}, 1000);
}
Not sure why that wouldn't work, but I've done something similar with
delayHandler = new Handler();
delayHandler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//change stuff on ui
}
});
}
}, 1000);
if that doesn't work the only other functional difference in my code is that instead of btn being a final Button it's a private global variable in my activity.
Hope the following code will help :
btn.setBackgroundColor(Color.RED); // color you want for a second
new CountDownTimer(1000, 1000) {
#Override
public void onTick(long arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
btn.setBackgroundColor(Color.BLUE); //to change back color to prior state
}
}.start();
Try this,i think it's work for you..
final Button bPdf = findViewById(R.id.pdf);
bPdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bPdf.setBackgroundColor(Color.parseColor("#0000ff"));
new CountDownTimer(1000, 50) {
#Override
public void onTick(long arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
bPdf.setBackgroundColor(Color.parseColor("#e2e2e2"));
}
}.start();
}
});
I've got this code:
#Override
public void onClick(View v) {
progressDoalog = new ProgressDialog(Hack.this);
progressDoalog.setMax(100);
progressDoalog.setMessage("Its loading....");
progressDoalog.setTitle("ProgressDialog bar example");
progressDoalog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDoalog.show();
new Thread(new Runnable() {
#Override
public void run() {
try {
while (progressDoalog.getProgress() <= progressDoalog
.getMax()) {
Thread.sleep(200);
handle.sendMessage(handle.obtainMessage());
if (progressDoalog.getProgress() == progressDoalog
.getMax()) {
progressDoalog.dismiss();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
Handler handle = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDoalog.incrementProgressBy(1);
}
};
});
}
}
Where can I add a code to open new activity when the ProgressDialog will be at 100%? Which and where exactly? Thanks for your help!
You can't start an Activity from a Dialog, but what you can do is start the Activity from the old one using a OnDismissListener.
Take a look at the documemtation :
https://developer.android.com/reference/android/content/DialogInterface.OnDismissListener.html
I haven't noticed but you can check the progress in your Handler, check if it's 100%, dismiss the dialog and start the new Activity, remember that you gotta do this on the UI thread
I want to call adapter.notifyDataSetChanged() from another thread. I read that I should use an AsyncTask and do the adapter.notifyDataSetChanged() in post execute.
I must execute the AsyncTask every 5 seconds only on the current activity (might be parent or child activity) because only one activity can do the asynctask at the same time.
Should I create a TimerTask which executes the AsyncTask every 5 seconds, stop it when I start another activity and start it back in onResume ?
Here is my code for the thread which updates the ListView of the current Activity.
private void runEventHandler() {
new Thread() {
public void run() {
while (true) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
users.add(new User(10, "a", false));
adapter.notifyDataSetChanged();
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Now I must be able to update the child activities' ListViews when a new User is added.
one possible way is that you create a flag in both activity to control your threads to be run ( the following codes are not runable just example to understand what you can do):
Activity A
{
public static boolean stopThread = false;
#Override
public void onResume()
{
super.onResume();
// put your code here...
stopThread =false;
runEventHandler();
}
private void runEventHandler() {
new Thread() {
public void run() {
while (A.stopThread != false) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
users.add(new User(10, "a", false));
adapter.notifyDataSetChanged();
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
#Override
protected void onStop(){
super.onStop();
stopThread =true;
}
}
Activity B
{
public static boolean stopThread = false;
#Override
public void onResume()
{
super.onResume();
// put your code here...
stopThread =false;
runEventHandler();
}
private void runEventHandler() {
new Thread() {
public void run() {
while (B.stopThread != false) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
users.add(new User(10, "a", false));
adapter.notifyDataSetChanged();
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
#Override
protected void onStop(){
super.onStop();
stopThread =true;
}
}
also you can use onPause() instead of onStop(). depends on your program concept.
You should a timertask like in link below : https://examples.javacodegeeks.com/android/core/activity/android-timertask-example/
the code to post any change on UIThread if you are in a different thread like doInBackground of AsyncTask:
runOnUiThread(new Runnable() {
#Override
public void run() {
// Here you can set your Ui Components
}
});
I have a task to run which takes a long time. So, I'd like to implement a progress dialog, spinning wheel, to show a message to users that the task is still running in the background. I found many solutions online and I used the following code. I ensured to run the task in separate thread. But it is not showing on UI.
OnClickListener confirmPrintButtonListener = new OnClickListener() {
public void onClick(View v) {
try {
final SalesStockController salesStockController = new SalesStockController();
final ArrayList<ProductReload> productReloadList = reloadActivityAdapter
.getReloadList();
if (productReloadList.size() != 0) {
progressDialog = new ProgressDialog(StockReloadActivity.this);
progressDialog.setTitle("ABC Trading");
progressDialog.setMessage("Wait while loading...");
progressDialog.show();
new Thread(new Runnable() {
public void run()
{
// do the thing that takes a long time
try {
salesStockController.reload(productReloadList);
} catch (SQLiteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ABCException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run()
{
progressDialog.dismiss();
}
});
}
}).start();
AlertDialog.Builder builder = new AlertDialog.Builder(
v.getContext());
builder.setCancelable(false).setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
finish();
}
});
AlertDialog alert = builder.create();
alert.setTitle("ABC Trading");
alert.setMessage("Reload Successfully");
alert.show();
ReloadSlipPrint print = new ReloadSlipPrint(
productReloadList);
print.print();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(
v.getContext());
builder.setCancelable(false).setPositiveButton("OK", null);
AlertDialog alert = builder.create();
alert.setTitle("ABC Trading");
alert.setMessage("No Stock To Reload");
alert.show();
}
} catch (Exception e) {
ABCUtil.displayErrorMsg(v.getContext(), e);
}
}
};
Can someone please point me out what is wrong with my code? Any help will be very much appreciated.
Just made up a simple example for you, you can try it.
public class MainActivity extends Activity {
private ProgressDialog mLoadingDialog;
private Handler mHandler = new Handler();
private void showLoadingDialog(final String title, final String msg) {
mHandler.post(new Runnable() {
#Override
public void run() {
if(mLoadingDialog == null) {
mLoadingDialog = ProgressDialog.show(MainActivity.this, title, msg);
}
mLoadingDialog.setTitle(title);
mLoadingDialog.setMessage(msg);
}
});
}
private void hideLoadingDialog() {
mHandler.post(new Runnable() { //Make sure it happens in sequence after showLoadingDialog
#Override
public void run() {
if(mLoadingDialog != null) {
mLoadingDialog.dismiss();
}
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread() {
#Override
public void run() {
showLoadingDialog("Loading", "Please wait...");
//DO something
hideLoadingDialog();
}
}.start();
}
}
You can use AsyncTask class to perform long runnning task
below is api link for the same
http://developer.android.com/reference/android/os/AsyncTask.html