I am attempting to making a method that on a button click, it will display a layout.
After a few seconds, I want a new activity/layout to be displayed.
Any suggestions on how to do this??
I would suggest not to wait on the UI Thread.
You can use a Handler for your Task. The run method will be executed in the same thread the Handler has been created:
//delay in ms
int DELAY = 1000;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(CurrentActivity.this, NextActivity.class);
startActivity(intent);
}
}, DELAY);
Does the UI need to do anything during this delay? If not, you can just use:
Thread.sleep(timeToWaitInMilliseconds);
inside your handler for the button. This will stop the UI thread for a few seconds however, your UI will "Freeze" during the delay.
A slightly better option is to use an AsyncTask and a Handler, which is a new thread, and make that thread sleep for the time you want to delay the new activity opening then opening the new activity in the handler.
The asynctask is a bit better for your case I think, as it will allow the user to interact with the UI during your "delay".
More info on AsyncTasks here:
http://developer.android.com/reference/android/os/AsyncTask.html
Related
I am displaying image on when clicking on a Button using interface but the image ic_launcher.png does not show up on the Button after some time the image_all.png is only shown.
How should I show my first image for some time using sleep and then show image2?
Should I show both the images on the same button but with time delay.
Any help would be appreciated.
try{
button1.setBackgroundResource(R.drawable.ic_launcher);
Thread.sleep(1000);
} catch(Exception e){
}
button1.setBackgroundResource(R.drawable.images_all);
When you use Thread.sleep(1000); you're actually "stopping" the UI thread, because you're calling sleep(1000); on the UI thread. This causes your application to halt completely for 1 second in your case.
So this isn't such a good idea :-)
Instead you should use something like a Handler for instance. A Handler can be called with a specified delay, so that the action will first be performed after the specified delay. And most importantly, the Handler doesn't "block" the UI thread, as the Thread.sleep(1000); does.
So using a Handler your code, could look something like this instead:
button1.setBackgroundResource(R.drawable.ic_launcher);
Handler uiHandler = new Handler();
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
button1.setBackgroundResource(R.drawable.images_all);
}
}, 1000);
Notice the 1000 in the end of postDelayed() which tells the Handler to post this "message" after 1000 milliseconds instead of immediately.
On a side-note: It's not good practice to "eat" the Exceptions like you do in your try-catch.
You should be able to see the R.drawable.ic_launcher change occur. My thoughts about this are around how you're doing the Thread.sleep(). Android isn't fond of performing blocking tasks (such as Thread.sleep) in the UI Thread. When you call the setBackgroundResource and then sleep, the thread that would update the UI is sleeping and cannot perform the update. This is how I would do it instead:
button1.setBackgroundResource(R.drawable.ic_launcher);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
button1.setBackgroundResource(R.drawable.images_all);
}
}, 1000);
In my app (as long as it is open) I want to sync my data with my server.
My strategy is the following :
//create the handler on which we will use postdelayed
Handler handler = new Handler();
//create the first runnable.
//Will this run on UI thread at this stage ? as it is being called from the handler ?
Runnable runnable1 = new Runnable()
{
public void run()
{
Thread t = new Thread(runnable2);
}
};
//create the second runnable.
//This is for sure being called from a thread, so it will not run on UI thread ? NO ?
Runnable runnable2 = new Runnable()
{
public void run()
{
//connect to internet
//make the check periodical
handler.postdelayed(runnable1, 1000);
}
};
//call the postdelayed.
handler.postdelayed(runnable1, 1000);
In case I want the handler to stop its runnable task once the application is closed. What shall I do incase I have several activities and I do not know where is the user when he/clicks the home button. Should I include a check in all onDestroys() ?
Yes you're second Runnable will be ran on a new thread not the UI thread.
When you do new Handler(); this creates a handle to the current thread, if this code was in onCreate that thread would be the UI thread.
Therefore when you do handler.post it will post onto the UI thread (runnable1) , but when you start runnable2 you are explicitly creating a new thread to run this on.
It might not be the right strategy to create a new thread every 1 second (postDelayed ..1000) perhaps keep a reference to another background thread and post it a message every second to do something new.
To stop your repeated runnables you need to call removeCallbacks(runnable1) in onPause of any Activity (that I assume called postDelayed in onCreate)
I'm working on an app that synchronizes some graphic UI events with an audio track. Right now you need to press a button to set everything in motion, after onCreate exits. I'm trying to add functionality to make the audio/graphical interaction start 10 seconds after everything is laid out.
My first thought is, at the end of onCreate, to make the UI thread sleep for 10000 miliseconds using the solution here and then to call button.onClick(). That seems like really bad practice to me, though, and nothing came of trying it anyway. Is there a good way to implement this autostart feature?
Never ever put sleep/delay on UI-thread. Instead, use Handler and its postDelayed method to get it done inside onCreate, onStart or onResume of your Activity. For example:
#Override
protected void onResume() {
super.onResume();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do whatever you want here
}
}, 10000L); //the runnable is executed on UI-thread after 10 seconds of delay
}
Handler handler=new Handler();
Runnable notification = new Runnable()
{
#Override
public void run()
{
//post your code............
}
};
handler.postDelayed(notification,10000);
Yes, putting the UI thread to sleep isnt a good idea.
Try this
private final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.schedule(task, 10, TimeUnit.SECONDS);
This is my first question here, so please forgive me if I disobeyed any of the forum rules.
I need my program to wait for 3 seconds and then change the Content View
My code is:
setContentView(R.layout.logout);
new Thread(new Runnable() {
#Override
public void run(){
try {
synchronized(this){
wait(3000);
}
}
catch(InterruptedException ex){
}
}
}).start();
setContentView(R.layout.main);
The program works with no errors, but there is no waiting. When it gets to this part, it just shows the "main" layout without showing the "logout" layout at all.
What is wrong in my approach?
As people noted, don't sleep on or otherwise block the UI thread, but you seem to be aware of this with the new thread you create.
Now for why it doesn't behave as you want:
Right now, you call setContentView(), start a new thread, call setContentView() a second time on the UI thread -- this happens in quick succession with no delay/wait/sleep inbetween. The wait(3000) happens in the new thread you started -- so that new thread starts, waits for 3000ms, then exits. It's an expensive no-op.
You would need to make the second call to setContentView() from inside that new thread's run() method to get the desired effect. Also, you should use sleep() instead of wait() -- wait() is a low-level tool for synchronizing threads while sleep() is the usual "don't continue for X amount of time".
Let me propose a better way:
An arguably nicer and much lighter approch is using Handler.postDelayed() -- this allows you to invoke a Runnable on the UI thread after a delay:
setContentView(R.layout.logout);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.main);
}
}, 3000);
Edit to reply to your comment:
Define and find the button before the Runnable as a final variable, this way you can access it later from inside the Runnable.
Please note that to reference the this instance of the surrounding class from inside an anonymous inner class (your new Runnable()), you need to prefix it with the class name of the surrounding class (your Activity class):
final View submitButton = findViewById(R.id.submit_button);
setContentView(R.layout.logout);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.main);
// adapt to your actual Activity class name:
submitButton.setOnClickListener(YourClassName.this);
}
}, 3000);
wait() doesn't wait for a certain amount of time, but rather has the current Thread wait for this to do a notify() for a maximum amount of time. What you are looking for, is Thread.sleep().
And at the moment the only thing that will be waiting, is the additional thread you are spawning, not the activity itself. That's why I'd suggest you look at Handler.postDelayed(), CountDownTimer or AsyncTask. Handling threads is very low-level.
Your code not work to sleep UI thread.To sleep UI thread try this code
new Handler().postDelayed(new Runnable()
{
public void run()
{
setContentView(R.layout.main);
}
}, 3000);
Try using Sleep() instead of Wait()
android.os.SystemClock.sleep(3000)
As far as i can understand the wait is happening in the new thread where as you are calling setContentView(R.layout.main) in the current thread.
Try
setContentView(..)
synchronized(this) {
this.wait(1000);
}
setContentView(..)
Please note sleeping or waiting in the UI thread is not a best practice though.
I have a time consuming task (iterating through files and sending it's content to server) that I want to execute in background thread, in specific interwal (that's why I want to use Handler).
From UI thread I have a call like this:
LogsManager lm;
lm = new LogsManager(this);
lm.processLogFiles();
And in LogsManager class I have following piece of code:
public void processLogFiles(){
Handler mHandler = new Handler();
mHandler.postDelayed(logsRunable, 1000);
}
private Runnable logsRunable = new Runnable() {
#Override
public void run() {
File f = new File(Environment.getExternalStorageDirectory()+Constants.LOG_DIR);
File[] logFiles = f.listFiles();
for (int i = 0; i < logFiles.length; i++) {
readLogs(logFiles[i]); // executes some other methods inside
}
}
};
As you can see it's just method with Handler that calls Runnable. And, unfortunately it also blocks my UI thread. Isn't Handler supposed to start a new thread for Runnable? I use handlers in other parts of my app also, and they works just fine. Am I'm doing something wrong?
As stated in the docs, Handler:
When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it
So if you're creating mHandler in UI thread, then it will run the tasks in UI thread - hence the problem.
All the post* methods in Handler run code on Handler's original thread (in your case the GUI thread). If you want a background thread, you need to explicitly start one (see below) or use AsyncTask, if you need to update the GUI.
Thread t = new Thread(logsRunable);
t.start();
I think you should use AsyncTask class for this purpose.
Scheduled the execution for the task after a specific delay, in your case it is 1000.
I also think AsyncTask is a good solution for your case.