What I want to do is to launch from the MainActivity in a new Thread a procedure that:
1) Makes an Internet call
2) Extract something like a boolean from the response (that represent which AlertDialog to show)
3) Show the correct (depending on the value of the boolean) AlertDialog in the MainActivity
I have no problems in executing first two steps using a Runnable or a AsyncTask but I can't show the alert in MainActivity
I followed different guides but I couldn't reach the solution.
Solved
My MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler=new Handler();
new Thread(new UpdateRunnable(this,mHandler)).start();
/* Other stuff */
}
My Runnable:
public class UpdateRunnable implements Runnable{
private Activity activity;
private Handler mHandler;
private boolean update;
/* Other stuff */
public UpdateRunnable(Activity activity, Handler mHandler){
this.activity = activity;
this.mHandler = mHandler;
/* Other stuff */
}
#Override
public void run() {
// It get from web which Dialog to call
update = update();
// It manage the UI work
mHandler.post(new Runnable() {
public void run() {
if(update){
show_dialog_you_are_not_updated();
} else {
show_dialog_you_are_updated();
}
}
});
}
/* The methods update, show_dialog_you_are_not_updated, show_dialog_you_are_updated */
}
Related
I am currently implementing my own custom progress dialog, where I call show and hide once a result comes in/error occurs. However, I want to implement a custom method that says if the progress dialog has not hidden after 10 seconds no matter what, hide it and put up an alert.
This is my custom progress dialog with my method that works but not entirely.
public class CustomProgressDialog extends ProgressDialog {
private AnimationDrawable animation;
private CountDownTimer cTimer = null;
private Context mContext;
public CustomProgressDialog(Context context) {
super(context);
mContext = context;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_progress_dialog);
ImageView la = (ImageView) findViewById(R.id.animation);
la.setBackgroundResource(R.drawable.custom_progress_dialog_animation);
animation = (AnimationDrawable) la.getBackground();
}
#Override
public void show() {
super.show();
animation.start();
startTimer();
}
#Override
public void dismiss() {
super.dismiss();
animation.stop();
if(cTimer != null) {
cTimer.cancel();
}
}
//timer added just in case progress dialog does not stop on its own
private void startTimer() {
cTimer = new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
dismiss();
AlertDialogManager alert = new AlertDialogManager();
alert.showAlertDialog(mContext, mContext.getString(R.string.loadingErr), mContext.getString(R.string.loadingErrTxt), 3);
}
}.start();
}
#Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
animation.stop();
cTimer.cancel();
}
}
This is how I implement it in the activity/fragment:
private void showProgressDialog() {
customProgressDialog = new CustomProgressDialog(this);
customProgressDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
customProgressDialog.show();
//so it cannot be closed by user first one lets back button cancel it
//customProgressDialog.setCanceledOnTouchOutside(false);
customProgressDialog.setCancelable(false);
}
private void hideProgressDialog() {
if(customProgressDialog != null) {
//customProgressDialog.hide();
}
}
UPDATE: This is a second option I tried it still does not stop the alert from popping up which makes me think the timer is still going even on cancel.
This is the activity:
private void autoProgressShutdown() {
Runnable progressRunnable = new Runnable() {
#Override
public void run() {
customProgressDialog.cancel();
callAlert();
}
};
Handler pdCanceller = new Handler();
pdCanceller.postDelayed(progressRunnable, 10000);
}
private void callAlert() {
AlertDialogManager alert = new AlertDialogManager();
alert.showAlertDialog(this, getString(R.string.loadingErr), getString(R.string.loadingErrTxt), 3);
}
private void showProgressDialog() {
customProgressDialog = new CustomProgressDialog(this);
customProgressDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
customProgressDialog.show();
//so it cannot be closed by user first one lets back button cancel it
//customProgressDialog.setCanceledOnTouchOutside(false);
customProgressDialog.setCancelable(false);
autoProgressShutdown();
}
private void hideProgressDialog() {
customProgressDialog.cancel();
if(customProgressDialog != null) {
customProgressDialog.hide();
}
}
In the custom dialog edited the file to remove all the timer stuff and added this:
#Override
public void setOnCancelListener(OnCancelListener listener) {
super.setOnCancelListener(listener);
dismiss();
}
Possible Issues:
-not sure if memory leak issues since I am not destroying it
Definite Issues:
-if the Progress dialog is hidden the alert still pops up after 10 seconds which means either cancel did not get called
-Also, if I switch screens not sure if the cancel is enough to destroy the timer
You can use Handler#postDelayed to make something happen later on a given thread, and you can use Handler#removeCallbacksAndMessages to cancel pending tasks. If you call it with null, it just cancels anything pending on the handler if you've got some stuff that you need to prevent in the posted task.
Here's your dialog, but properly self-terminating:
class SuicideDialog extends Dialog{
private Handler mAutoTerminationHandler;
#Override
public void onShow(){
mAutoTerminationHandler = new Handler();
}
#Override
public void show(){
super.show();
mAutoTerminationHandler.postDelayed(new Runnable(){
dismiss();
}, 666L);
}
#Override
public void dismiss(){
mAutoTerminationHandler.removeCallbacksAndMessages(null);
super.dismiss();
}
}
Or, you can put the lifecycle listening into its own class:
class ShownTaskListener implements OnShowListener, OnDismissListener {
private Handler mHandler;
#Override
public ShownTaskListener(Handler handler, Runnable showTask){
mHandler = handler;
mShowTask = showTask;
}
// from OnShowListener
#Override
public void onShow(){
mHandler.postDelayed(mShowTask, 666L);
}
// from OnDismissListener
#Override
public void onDismiss(){
// get rid of all pending actions in the Handler
mHandler.removeCallbacksAndMessages(null);
}
}
And then, you can use it to self-dismiss any Dialog by attaching this listener with Dialog#setOnShowListener and Dialog#setOnDismissListener.
How can i pause the handler.postDelayed() timer using a button. So when i click the same button again the handler.postDelayed() timer should resume.
handler.postDelayed(counterz, 60);
Handler does not have a timer to tweak. You are posting to event-queue of a thread, where a lot of other stuff is running as well.
You can cancel posted Runnable's:
handler.removeCallbacks(counterz);
And post again, to resume.
Handler does not have a pause method. You need to cancel and run again.
http://developer.android.com/reference/android/os/Handler.html#removeCallbacks(java.lang.Runnable)
public final void removeCallbacks (Runnable r)
Remove any pending posts of Runnable r that are in the message queue.
When not required you need to call m_handler.removeCallbacks(m_handlerTask) to cancel the run. If you need again you need to run the the task again.
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run(); // call run
Suppose you use a timer. Even timer does not have pause method.
public class YourActivity extends AppCompatActivity {
private static boolean handlerflag=false;
private Handler handler;
private Runnable runnable;
private int myind=0,index=0,count=0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activtiy);
//oncreate exe only
handlerflag=true;
handler = new Handler();
startyourtime(0);
}
private void startyourtime(int a) {
myind=0;
for (index=a; index<10 ;index++) {
myind++;
runnable=new Runnable() {
count++;
#Override
public void run() {
//your code here
}
};handler.postDelayed(runnable, Constants.TIME_LIMIT * myind);
}
#Override
protected void onPause() {
super.onPause();
handlerflag=false;
handler.removeCallbacksAndMessages(null);
}
#Override
protected void onResume() {
super.onResume();
if(!handlerflag)
{
startyourtime(count);
}
}
}
I am learning how to use Looper and Handler class in android development
http://developer.android.com/reference/android/os/Looper.html
The example given in the android development is not clear to understand what is the usage and the how to use it.I dont know how to add Handler inside the Looper and how I can call the Looper to loop.
If it is available, can anyone give me a simple example to use it.
public class LooperTest extends Activity{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
private class LooperTesting extends Thread
{
public Handler handler;
public void run()
{
Looper.prepare();
handler = new Handler()
{
public void handlerMessage(Message msg)
{
// do something
}
};
Looper.loop();
}
}
}
Hope this Links are helps to u
Link1
Link2
Link3
In your example you have only defined a Thread with a Looper. You need to start the Thread with the associated Looper before you can post any messages to it. I've added some code to your example to illustrate what has to be done:
public class LooperTest extends Activity{
LooperTesting mBgThread;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBgThread = new mBgThread();
// Start the thread. When started, it will wait for incoming messages.
// Use the post* or send* methods of your handler-reference.
mBgThread.start();
}
public void onDestroy() {
// Don't forget to quit the Looper, so that the
// thread can finish.
mBgThread.handler.getLooper().quit();
}
private class LooperTesting extends Thread
{
public Handler handler;
public void run()
{
Looper.prepare();
handler = new Handler()
{
public void handlerMessage(Message msg)
{
// do something
}
};
Looper.loop();
}
}
}
I have a GPS class which returns the current GPS coordinates to the calling activity via a callback.
The user either takes a picture or chooses one from the library and then returns to the main activity. After he returns to the main activity, I poll the gps class for the location data.
Once the callback return, it updates two class properties, one for Lat and one for Lon.
Sometimes it takes several second for the callback to be called and I want the activity to wait for the callback and display some kind of dialog to the user.
I am just using a while loop to wait for the properties to update, but I'm sure there is a more graceful solution to this.
use threading:
private ProgressDialog progressDialog;
protected void btnDoOperation_onClick() {
final Runnable r = new Runnable()
{
public void run()
{
doMyOperations();
}
};
progressDialog = ProgressDialog.show(this, "title","Please wait");
performOnBackgroundThread(r);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
#Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
private void doMyOperations() {
// do every thing you like here ;)
this.runOnUiThread(new Runnable() {
public void run() {
progressDialog.dismiss();
}
});
}
i am trying to make facebook asynchronous non blocking thread in android. due to which our UI is run separate thread but i am unable to do that can any one tell me how to do that.
and If possible pleade give me one example.
Thanks.........
I don't know much about the Facebook but to access to the ui component from the other thread-
public class Dictionary extends Activity{
Handler mhandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Handler mhandler = new Handler();
SearchThread thread = new SearchThread();
thread.setParent(this);
thread.setHandler(mhandler);
}
public void notifyItemChanged(ArrayList<ListItem> lItems){
//write code relating to ui here
}
private class SearchThread extends Thread{
private Handler handler;
Dictionary parent;
public void setParent(Dictionary parent) {
this.parent = parent;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
#Override
public void run() {
final Runnable mUpdateResults = new Runnable() {
public void run() {
parent.notifyItemChanged(listItems);
}
};
handler.post(mUpdateResults);
}
}