How to set delay properly in android (Eclipse) - android

im new at eclipse and at making applications and i wanted to create infinite loop with 3 pictures that every picture will turn visible or invisible in his turn.
but when i run the application only the second picture become visible once and that's it, then is stop and noting happen.
what i need to do to get it to work?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dk1 =(ImageView) findViewById(R.id.dkmain1);
dk2 =(ImageView) findViewById(R.id.dkmain2);
dk3 =(ImageView) findViewById(R.id.dkmain3);
dk1.setVisibility(View.VISIBLE);
dk2.setVisibility(View.INVISIBLE);
dk3.setVisibility(View.INVISIBLE);
if(dk1.getVisibility()==View.VISIBLE)
{
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dk1.setVisibility(View.INVISIBLE);
dk2.setVisibility(View.VISIBLE);
dk3.setVisibility(View.INVISIBLE);
}
}, 2000);
}
if(dk2.getVisibility()==View.VISIBLE)
{
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dk1.setVisibility(View.INVISIBLE);
dk2.setVisibility(View.INVISIBLE);
dk3.setVisibility(View.VISIBLE);
}
}, 2000);
}
if(dk3.getVisibility()==View.VISIBLE)
{
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dk1.setVisibility(View.VISIBLE);
dk2.setVisibility(View.INVISIBLE);
dk3.setVisibility(View.INVISIBLE);
}
}, 3000);
}

If you set the view invisible:
dk2.setVisibility(View.INVISIBLE);
Then check if it's visible:
if(dk2.getVisibility()==View.VISIBLE)
It will always evaluate to false and will never be executed.
I would consider a different approach such as:
Timer - http://developer.android.com/reference/java/util/Timer.html
CountDownTimer - http://developer.android.com/reference/android/os/CountDownTimer.html
Also, you can set the default visibility in the layout using:
android:visibility="visible|invisible|gone"

You need to make the Handlers nested to make sure they run one by one :
if(dk1.getVisibility()==View.VISIBLE)
{
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dk1.setVisibility(View.INVISIBLE);
dk2.setVisibility(View.VISIBLE);
dk3.setVisibility(View.INVISIBLE);
//put your 2nd if here, and 3rd if INSIDE your 2nd if
if(dk2.getVisibility()==View.VISIBLE)
//rest of the 2nd if code, and out the 3rd if here
}
}, 2000);

Related

Best practice to create a thread that runs every hour in Android?

So I'm attempting to create background task that needs to be run every hour in an Android app. Its a rather heavy task that takes around 5 - 10 minutes to finish, and right now it runs on the UI thread which of course isn't good, because it hangs the whole application. I've attempted the following in my MainActivity onCreate:
new Thread(new Runnable() {
private Handler HeavyTaskHandler = new Handler(Looper.getMainLooper());
public void run(){
final TextView updatedTxt = findViewById(R.id.txt);
updatedTxt.post(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Performing cleanup..");
}
});
HeavyTask(); // <-- This method runs for 5 - 10 minutes
updatedTxt.post(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Done..");
}
});
HeavyTaskHandler.postDelayed(this, HeavyTaskCycle);
}
}).start();
I have two issues with the above
It works fine the first time, and the task is performed in the background well without hanging the UI thread. However, after this first time and the next time(s) it is run, the UI thread hangs again when it is run. What am I missing?
Notice that before the HeavyTask() method is called i try to set a TextViews text to "Performing cleanup.." .. This never shows, only the "Done.." which happens after the HeavyTask() method is done. How can i ensure that the message also appears before?
I ended up doing the following from MainActivity which doesn't hang the application
private void CreateCleanUpThread()
{
CleanUpThread = new Thread(new Runnable() {
public void run(){
try {
while(true) {
performingCleanup = true;
final TextView updatedTxt = findViewById(R.id.updated_txt);
runOnUiThread(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Performing database history cleanup..");
}
});
HeavyTask(); // <-- This method runs for 5 - 10 minutes
runOnUiThread(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Done..");
}
});
performingCleanup = false;
Thread.sleep(CleanUpCycle); // 1 hour wait time
}
} catch(Exception ex) {
System.out.println("Error in CreateCleanUpThread : " + ex.getMessage());
}
}
});
}
// onCreate in MainActivity
...
CleanUpThread.start();
Certainly not the best way, but it works and will do for now. Should be moved to a service instead i think.

Changing an Image resource

When I'm clicking on a button, I want to change an Image view to different picture, to wait 3 seconds, and to change it again to another picture (without clicking again).
1 click -> change picture -> wait 3 seconds -> change picture.
This is my code:
northLight.setImageResource(R.drawable.red_and_yellow);
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {}
northLight.setImageResource(R.drawable.green);
While I'm running the program, when I'm actually clicking the button, the program ignores the first setImage and changes it straight to the second setImage (to the green).
How can I solve this?
you can use handler for it,
northLight.setImageResource(R.drawable.red_and_yellow);
new Handler().postDelayed(new Runnable() {
public void run() {
// Actions to do after 3 seconds
northLight.setImageResource(R.drawable.green);
}
}, 3000);
You can try using a Handler to wait and change the image. When your button gets clicked, change your image and run the handler with a delay of 3 seconds.
//Call this method when your button is clicked
public void changeImage() {
northLight.setImageResource(R.drawable.red_and_yellow);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
northLight.setImageResource(R.drawable.green);
}
}, 3000);
}
Try this code
new CountDownTimer(3000,1000){
#Override
public void onTick(long l) {
northLight.setImageResource(R.drawable.red_and_yellow);
}
#Override
public void onFinish() {
northLight.setImageResource(R.drawable.green);
}
}.start();

How can I reset the time of a postDelayed runnable in onClick?

I've got a listView that gets populated from a server. In the onClick of the ListItem, I display a button for a x number of seconds and I make it invisible again. How can I reset the time every time the onClick is called?
Here is my listItem onClick:
private void displayInCallButton() {
mButton.setEnabled(true);
if (canDisplayInCallControlls) {
canDisplayInCallControlls = false;
fadeInAnimation(mButton);
mButton.setEnabled(true);
mFrontView.postDelayed(new Runnable() {
public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
}, 5000);
}
}
Thank you in advance.
You have to remove the callbacks and set it once again with the new one with the reset time.
first, set the call back like
Runnable myRunnable = new Runnable() {
#Override
public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
};
then set it to mFrontView like,
mFrontView.postDelayed(myRunnable,5000)
If you want to reset, do it like
mFrontView.removeCallbacks(myRunnable);
mFrontView.postDelayed(myRunnable, 2000);
How can I reset the time every time the onClick is called?
There is no built-in mechanism to accomplish that.
You can, however, keep a reference to the Runnable you post, remove it and then repost it again to restart at the original delay.
The result would look somewhat like this in its most simple form:
Runnable mDelayedRunnable = new Runnable() {
#Override public void run() {
fadeOutAnimation(mButton);
mButton.setEnabled(false);
hasAnimationEnded = true;
canDisplayInCallControlls = true;
}
};
private void displayInCallButton() {
mButton.setEnabled(true);
if (canDisplayInCallControlls) {
canDisplayInCallControlls = false;
fadeInAnimation(mButton);
mButton.setEnabled(true);
mFrontView.removeCallbacks(mDelayedRunnable);
mFrontView.postDelayed(mDelayedRunnable, 5000);
}
}
You can safely call removeCallbacks() with a Runnable that was never posted in the first place (or even null).
If you don't want to keep an explicit reference to the Runnable, you could also opt to tag the view with it. Just don't forget to clean up on i.e. orientation changes and the like.

how to keep screen on for an specific duration?

in one of my Activities I want to keep screen on for 2 minutes (e.g.). I know I can keep screen on with:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
but how to do that for an specific duration ?
You have many ways to clear flags after 2 minutes..like you can use timer or thread or handler
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}, 20000);
in this way you can clear the flags
Take this:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// turn screen off function
}
}, 2000);
After 2sec it will turn off the screen. You just have to put the turn off function in it.
Handler handler = new Handler();
// run a thread after 2 seconds to start the home screen
handler.postDelayed(new Runnable() {
#Override
public void run() {
finish();
// start your screen
}
}, 2000); // time in milliseconds (1 second = 1000 milliseconds) until the run() method will be called

android set visibility of a button on timer

I have an app that shows a disclaimer at the beginning of the program. I want a button to remain invisible for a set amount of time, and then become visible.
I set up a thread that sleeps for 5 seconds, and then tries to make the button visible. However ,I get this error when I execute my code:
08-02 21:34:07.868: ERROR/AndroidRuntime(1401): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
How can I count 5 seconds, and then make the button visible?
THanks.
Thread splashTread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while(_active && (!_ok2)) {
sleep(100);
if(_active) {
waited += 100;
if(waited >= _splashTime)
{
turnButtonOn();
}
}
}
} catch(InterruptedException e) {
// do nothing
} finally {
finish();
startActivity(new Intent("com.lba.mixer.Choose"));
}
};
splashTread.start();
public static void turnButtonOn() {
okButton.setVisibility(View.VISIBLE);
}
The problem is that you're not in the UI thread when you call okButton.setVisibility(View.VISIBLE);, since you create and run your own thread. What you have to do is get your button's handler and set the visibility through the UI thread that you get via the handler.
So instead of
okButton.setVisibility(View.VISIBLE)
you should do
okButton.getHandler().post(new Runnable() {
public void run() {
okButton.setVisibility(View.VISIBLE);
}
});
I found this to be a much simpler solution. Visibility on 7 second delay
continuebutton.setVisibility(View.INVISIBLE);
continuebutton.postDelayed(new Runnable() {
public void run() {
continuebutton.setVisibility(View.VISIBLE);
}
}, 7000);
I found this a Better solution to the problem
(button id = but_resend)
define handler
private Handler handler;
call function in extend class
showButtons();
define after class
private void showButtons() {
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
((Button) findViewById(R.id.but_resend)).setVisibility(View.VISIBLE);
}
}, 20000); // produce 20 sec delay in button visibility
}
and keep in mind to hide the visibility in the.xml file by
android:visibility="invisible"

Categories

Resources