PostDelayed() inside onFinish() in CountDownTimer - java

I need to use postDelayed() method inside onFinish() method of the CountDownTimer. I use the following code:
...
public void onFinish() {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//do something here after 3 seconds
}
}, 3000);
}
But it does not work. It does not delay.

It's not going to work. You will have to find another way to accomplish your goal. The reason why, is because your post delayed is ran on a different thread then the onFinish. onFinish will run on the UI tread. After onFinish is ran the class will be closed out and the postDelayed thread will be no more.

Related

Running 2 methods with X amount of time difference?

I have a mic, which I want to activate for 5 seconds and then get that data. While the activity thread is still running.
Method 1: Is the activation of mic.
Method 2: Is for collecting the .amr/.mp3 output from the file.
And this will only happen one time.
I want that my activity should call method 1 at the start and after time X(or 5 seconds), it should call the other method. I am able to do this manually by using 2 buttons, one for record and other for save the file. But I am unable to do this automatically.
Thanks in advance.
Maybe something like:
firstMethodCall();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
secondMethodCall();
}
}, 5000);
Or better:
firstMethodCall();
new Timer().schedule(new TimerTask() {
#Override
public void run() {
secondMethodCall();
}
}, 5000);
Create a Thread.
Call first method, Thread.sleep() for some time
and Then Call Second Method.
Example:
Thread thread=new Thread(){
public void run(){
firstMethod();
Thread.sleep(time);
secondMethod();
}
};
//on button click
thread.start();

Android Timer in Background Service not updating on time

I am trying to update a user location to our REST WebService every minute. I have tried using a Timer and a Runnable with Handler. Both of these are having problems.
Both work fine on my Emulator, although on our test devices the timer and Runnable are not running every minute, they update sporadically, sometimes within 1 second of each other, sometimes 5 minutes later, and anywhere in between..
Does anyone know why this might happen?
Context context;
Handler handler = new Handler();
#Override
public void onCreate() {
super.onCreate();
context = this;
handler.postDelayed(runnable, 0);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
updateLocation(context);
handler.postDelayed(this, 60000);
}
};

Android start/stop repeating Thread after specific time

I need a thread repeating after 30 seconds that load data from web service.
i want to stop and start thread onResume and onPause so that it runs when screen is active and disable it when activity paused. Restart on resume.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dataIfInternet(refreshTop);
}
}, 30000);
How to stop it when activity paused.
U can't pause the handler, so u need to cancel it in your onPause and post in again in your onResume
so u probably want something like this:
private Handler myHandler = new Handler();
in your onResume()
Runnable myRunnable = new Runnable()
{
#Override
public void run()
{
dataIfInternet(refreshTop);
}
};
myHandler.postDelayed(myRunnable, 30000);
and in your onPause()
// Cancel the runnable
myHandler.removeCallbacks(myRunnable);
I hope this solves your problem

Android Thread Allocation - growing heap?

Hi everyone out there,
i am developing an android application against API 7 at the moment in which i use an activity which need to be restarted. Lets say my activity looks like this:
public class AllocActivity extends Activity implements OnClickListener{
Button but;
private Handler hand = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_alloc);
but = (Button) findViewById(R.id.button);
but.setText("RELOAD");
but.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0){
Intent intent = getIntent();
startActivity(intent);
finish();
}
});
}
#Override
protected void onDestroy(){
super.onDestroy();
System.gc();
}
/****** THREADS AND RUNNABLES ******/
final Runnable fullAnim = new Thread(new Runnable(){
#Override
public void run(){
try{
hand.post(anim1);
Thread.sleep(2000);
hand.post(anim2);
Thread.sleep(1000);
// and so on
}catch(InterruptedException ie){ie.printStackTrace();}
}
});
final Runnable anim1 = new Runnable() {
#Override
public void run(){
// non-static method findViewById
ImageView sky = (ImageView)findViewById(R.id.sky);
}
};
}
The problem is that the gc doesnt seem to free the fullAnim thread so that the heap is growing by ~100K at every restart - till it slows down and crashes. Declaring fullAnim as static does solve this problem - but as i use non static references this doesnt work out for me.
So at this point i am kindof lost - and i hope u can advice me where to go next. Is there something i might be doing wrong or is there a tool i can use to manage threads to drop and free heap after restart.
kindly regards
UPDATE
thanks to everyone who answered - helped alot. using TimerTask did the trick in the end. i did the following change:
/****** THREADS AND RUNNABLES ******/
final TimerTask fullAnim = new TimerTask(){
#Override
public void run(){
try{
hand.post(anim1);
Thread.sleep(2000);
hand.post(anim2);
Thread.sleep(1000);
// and so on
}catch(InterruptedException ie){ie.printStackTrace();}
}
};
as the activity was more than 6k loc long this was a pretty decent solution without facing bigger impacts. KUDOS!
i dont use a Timer to shedule the task - dont know if its bad practice but
the animation is called like this:
Thread t = new Thread(fullAnim);
t.start();
A running Thread is never garbage collected.
A Thread is not stopped automatically if your Activity stops or is destroyed. It could run forever.
Every non-static inner class keeps a reference to the enclosing instance. E.g. hand.post(anim1); works inside that inner class because it has an implicit reference to AllocActivity.this.
So what you effectively do is to keep a reference to your Activity alive for longer than it is supposed to be alive, i.e. until after onDestroy.
Make sure to stop threads manually if you don't want them anymore.
Because final variable have low priority for GC. So you need to explicitly release the runneable objects in onPause() method because there is not ensurence onDestory() will call immediate after finish() call .
#Override
protected void onPause(){
super.onPause();
//cancel timer to stop animations
if(t!=null){
t.cancel();
}
System.gc();
}
UPDATE
use timer to achieve this
boolean isFirstAnim=true;
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
if(isFirstAnim){
// play your first animation at every
}else{
// play your second animation at every
}
}
}, 0, 3000);
What happens when all activities of an application finishes?
"When you call finish() this doesn't mean the Activity instance is
garbage collected. You're telling Android you want to close the
Activity (do not show it anymore). It will still be present until
Android decides to kill the process (and thus terminate the DVM) or
the instance is garbage-collected."
You need to implement your own stop method to stop the running thread, you can make a call to it in onDestroy
refer this Stopping a runnable
Alternatively
you can perform your operation in an asynctask and use onProgressUpdate() to publish progress on UI thread and use cancel(true) in combination with check in doInBackground() whether cancel has been called to stop the task.

Sleep() in Android Java

I am following this tutorial to have a loading screen in my program. The tutorial says my activity should Sleep() using the Sleep() command, however it does not recognize Sleep() as a function and provides me with an error, asking if I would like to create a method called Sleep().
Here is the code sample:
public class LoadingScreenActivity extends Activity {
//Introduce an delay
private final int WAIT_TIME = 2500;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
System.out.println("LoadingScreenActivity screen started");
setContentView(R.layout.loading_screen);
findViewById(R.id.mainSpinner1).setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
//Simulating a long running task
this.Sleep(1000);
System.out.println("Going to Profile Data");
/* Create an Intent that will start the ProfileData-Activity. */
Intent mainIntent = new Intent(LoadingScreenActivity.this,ProfileData.class);
LoadingScreenActivity.this.startActivity(mainIntent);
LoadingScreenActivity.this.finish();
}
}, WAIT_TIME);
}
}
You can use one of the folllowing methods:
Thread.sleep(timeInMills);
or
SystemClock.sleep(timeInMills);
SystemClock.sleep(milliseconds) is a utility function very similar to Thread.sleep(milliseconds), but it ignores InterruptedException. Use this function for delays if you do not use Thread.interrupt(), as it will preserve the interrupted state of the thread.
The function is Thread.sleep(long).
Note, however, that you should not perform a sleep on the UI thread.
The code you posted is horrible. Please don't use that on an actual device. You will get an "Application Not Responding" error if you run something similar to this.
If you're using Handlers, keep in mind that a Handler is created on the thread where it runs. So calling new Handler().post(... on the UI thread will execute the runnable on the UI thread, including this "long running operation". The advantage is that you can create a Handler to the UI Thread which you can use later, as shown below.
To put the long running operation into a background thread, you need to create a Thread around the runnable, as shown below. Now if you want to update the UI once the long running operation is complete, you need to post that to the UI Thread, using a Handler.
Note that this functionality is a perfect fit for an AsyncTask which will make this look a lot cleaner than the pattern below. However, I included this to show how Handlers, Threads and Runnables relate.
public class LoadingScreenActivity extends Activity {
//Introduce a delay
private final int WAIT_TIME = 2500;
private Handler uiHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHandler = new Handler(); // anything posted to this handler will run on the UI Thread
System.out.println("LoadingScreenActivity screen started");
setContentView(R.layout.loading_screen);
findViewById(R.id.mainSpinner1).setVisibility(View.VISIBLE);
Runnable onUi = new Runnable() {
#Override
public void run() {
// this will run on the main UI thread
Intent mainIntent = new Intent(LoadingScreenActivity.this,ProfileData.class);
LoadingScreenActivity.this.startActivity(mainIntent);
LoadingScreenActivity.this.finish();
}
};
Runnable background = new Runnable() {
#Override
public void run() {
// This is the delay
Thread.Sleep( WAIT_TIME );
// This will run on a background thread
//Simulating a long running task
Thread.Sleep(1000);
System.out.println("Going to Profile Data");
uiHandler.post( onUi );
}
};
new Thread( background ).start();
}
use Thread.sleep(1000);
1000 is the number of milliseconds that the program will pause.
try
{
Thread.sleep(1000);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
Keep in mind: Using this code is not recommended, because it is a delay of time but without control and may need more or less time.

Categories