I cant make myHandler run - android

What I want to do is just a basic implementation of handler example. I have a TextView on the mainActivity, and once the page loads the handler is supposed to run and show the user value coming from SystemClock.uptimeMillis. But ıt doesn't work more than once. How can I make this code run?
public class MainActivity extends Activity {
long uptoMS=0L;
TextView tv;
Handler handler=new Handler();
long swaptime=0L;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView)findViewById(R.id.textView1);
uptoMS=SystemClock.uptimeMillis();
tv.setText(String.valueOf(uptoMS));
handler.post(runner);
}
private Runnable runner=new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
swaptime+=uptoMS;
tv.setTag(String.valueOf(swaptime));
handler.post(this);
}
};
}

See this below example
scheduler(){
TimerTask tasknew = new TimerSchedulePeriod();
Timer timer = new Timer();
// scheduling the task at interval
timer.schedule(tasknew,100, 100);
}
// this method performs the task
public void run() {
System.out.println("timer working");
}

timer = new Timer();
refreshTask = new TimerTask() {
#Override
public void run() {
swaptime+=uptoMS;
tv.setTag(String.valueOf(swaptime));
handler.post(this);
}
};
timer.schedule(refreshTask,
100, 100);

Well, there some problems with your code.
Firstly, you use setTag() instead of setText(), so the value will never update.
tv.setTag(String.valueOf(swaptime));
Secondly, you get uptoMS once in onCreate(), and then you use it in every "handler loop". I don't know what you try to achive but it's unlike that you want this.
Thirdly, you instantly repost your Runnable, so the main thread's message queue will be busy. You should give some break instead of instant reposting. For example you can wait 100 ms between the updates, so the TextView will be updated 10 times in every second.
handler.postDelayed(this, 100);
And finally, however others suggest you using Timer, just ignore them. Handler is the Android way to achieve tasks like this.

Related

runOnUiThread() no executing when using Thread.sleep()

I'm using code that looks like this :
_thread = new Thread(){
#Override
public void run() {
try {
while (true) {
operate();
Thread.sleep(DELAY);
}
} catch (InterruptedException e) {
// Doesn't matters...
}
}
};
operate function looks like this :
// does things....
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// adds an ImageView to the screen
}
});
// does other things...
At the bottom line, what i wanted to achieve is an operation that happens once in a while, without interrupting the main thread and the UI, something like a game-loop.
In the first 2 times that operate() runs, it adds the ImageView and everything is alright, but after 2 or 3 times it stops adding the ImageViews, but the UI is still running as usual. When i debugged the problem, i found out that after 3 times the run() method of the Runnable isn't called anymore, even thought the operate function was called.
The wired thing (for me) was that when i removed the Thread.sleep, everything worked fine (much faster of course...). I tried to replace it with a very long for loop (just for checking) and it worked, but of course it is not an appropriate solution to the problem.
I read about the problem, most of the people that asked this question did a thread.sleep or an infinite loop on the main thread, but, as i see it, i didn't do such thing. Many people wrote that you should replace the Thread.sleep with Handler.postDelayed. I tried to do it but it didn't work, maybe I did it wrong. I even tried replacing the runOnUiThread with other options I found on the internet, but all of them gave me the same exact results. I tried to replace the method that I'm adding the view to the activity, but all of them, again, gave the same result.
The waiting is crucial for this application. I got to find a way to wait sometime and then execute a function on the UI thread, cause this pattern returns at least a couple of times in my application.
It sounds like you want a post delay so that you can do the code on the UI thread after some delay. Handler Post Delay.
private static final int DELAY = 500;
private Handler mHandler;
private Runnable mRunnable;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start();
}
private void start()
{
mHandler = new Handler();
mRunnable = new MyRunnable(this);
mHandler.postDelayed(mRunnable, DELAY);
}
private void stop()
{
mHandler.removeCallbacks(mRunnable);
}
private void doSomething()
{
// Do your stuff here.
// Reschedule.
mHandler.postDelayed(mRunnable, DELAY);
}
Recommended way of creating a Runnable.
private static class MyRunnable implements Runnable
{
private WeakReference<MainActivity> mRef;
// In here you can pass any object that you need.
MyRunnable(MainActivity activity)
{
mRef = new WeakReference<MainActivity>(activity);
}
#Override
public void run()
{
// Safety check to avoid leaking.
MainActivity activity = mRef.get();
if(activity == null)
{
return;
}
// Do something here.
activity.doSomething();
}
}
There could be several reasons why the UI Runnable isn't being executed. Probably the activity variable has something messed up with it or it's referencing the context incorrectly, or as you said the Thread.sleep() could be causing an issue. At this point more parts of the code needs to viewed to better solve the problem.
A better way of implementing your logic is to use a scheduled Timer instead of using an infinite loop with a Thread.sleep() in it. It will execute the code within a background thread. And then use a Handler to update the UI instead of activity.runOnUiThread(). Here's an example:
// Global variable within the activity
private Handler handler;
// Activity's onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
handler = new Handler(getMainLooper());
Timer timer = new Timer("ScheduledTask");
// Timer must be started on the Main UI thread as such.
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
operate();
}
}, 0L, DELAY);
}
private void operate() {
// does things in background....
handler.post(new Runnable() {
#Override
public void run() {
// adds an ImageView to the screen from within the Main UI thread
}
});
// does other things in the background...
}

Setting Interval For Activiry and Perform Task

Is there any function in Android that can use to make the activity wait for an interval and continue working?
I mean , for example, I use setContentView() to set a layout , and after 3 seconds it will load another layout, and continue to do another job, I don't need to repeat doing same thing after an interval, just continue do another thing.
Thanks in advanced.
You can Use Following Method to Set Interval
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// This method will be executed once the timer is over
// Do your code here
}
}, 3000);
Here, 1000 = 1 Second
But Before running this code make sure that you are not in BACKGROUND PROCESS THREAD...otherwise this may cause an error..
Do it at Android Style:
Handler mHandler = new Handler();
mHandler.postDelayed(runnableHandler, 3000);
private Runnable runnableHandler = new Runnable() {
#Override
public void run() {
doSomething()
}
};
private void doSomething() {
// Before do something remove all callbacks from Handler
mHandler.removeCallbacks(runnableHandler);
andFinallyDoWhatYouNeed();
}

Updating UI on button click after a certain time

I have a TextView. I want to update its text (append a "1") after 1 second of a button click.
public class HaikuDisplay extends Activity {
Method m;
Timer t;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = new Timer();
m = HaikuDisplay.class.getMethod("change");
}
//Event handler of the button
public void onRefresh(View view)
{
//To have the reference of this inside the TimerTask
final HaikuDisplay hd = this;
TimerTask task1 = new TimerTask(){
public void run(){
/*
* I tried to update the text here but since this is not the UI thread, it does not allow to do so.
*/
//Calls change() method
m.invoke(hd, (Object[])null);
}
};
t.schedule(task1, 1000);
}
public void change()
{
//Appends a "1" to the TextView
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "1");
}
//Event handler of another button which updates the text directly by appending "2".
//This works fine unless I click the first button.
public void onRefresh1(View view)
{
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "2");
}
}
Consider all Exceptions be handled.
On first click, m.invoke gives InvocationTargetException. But it calls the method change() on successive invokes without any Exceptions(verified by logging). But it does not update the text. Where am I wrong?
Also, I see in the debugger that it creates a new Thread every time I click the button. That is fine. But why isn't it removing the previous Threads though their execution has been completed?
Do something like this
public void onRefresh1(View v) {
// You can have this in a field not to find it every time
final EditText t = (EditText) findViewById(R.id.textView1);
t.postDelayed(new Runnable() {
#Override
public void run() {
t.append("1");
}
}, 1000);
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Update UI
}
}, 1000);
implement this on button click
UPDATE:
There are some other answers. dtmilano suggested another solution which is almost same to mine except he is calling the postDelayed method of View class and In my answer I used postDelayed method of handler class.
from the api reference of android the postDelayed method of Handler says
The runnable will be run on the thread to which this handler is
attached.
and the postDelayed method of View says
The runnable will be run on the user interface thread.
This is the only difference between these two solution. in my answer instead of creating new Handler every time you can use any other handler instance. Then the runnable will be run on that thread where that specific handler is declared. And if the postDelayed of EditText is used the the runnable method will be run on the user Interface Thread.
Now the performance issue, both has the same performance (If anybody can prove me wrong with reference I will be happy)
That's looking awful convoluted - have you considered using CountDownTimer instead?
new CountDownTimer(1000, 1000) {
public void onTick(long millisUntilFinished) {
// no-op
}
public void onFinish() {
change();
}
}.start();
This should call change (and hence change the text) on the UI thread, avoiding reflection and threading errors.
Hi Use the following code for that. Hope this will help you .
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
// your code here
}
},
1000
);
Have a look of this question also.
display data after every 10 seconds in Android
You can try with this also.
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
doStuff();
/*
* Now register it for running next time
*/
handler.postDelayed(this, 1000);
}
};
**EDIT 3**
Try with this once you are need to enable once (i mean if you put your code in yourmethod()== this will get automatically call 1 seconds once.
private Timer timer;
TimerTask refresher;
// Initialization code in onCreate or similar:
timer = new Timer();
refresher = new TimerTask() {
public void run() {
yourmethod();
};
};
// first event immediately, following after 1 seconds each
timer.scheduleAtFixedRate(refresher, 0,100);

Refresh parsing code android

I am using the JSON parser to parse some pages but I would like to recall the parsing function every 30 seconds. How can i do that ?
One of the method to call a method every 30 seconds is by using postDelay of Handler see below code.
Handler handler;
handler=new Handler();
handler.removeCallbacks(run);
handler.post(run);
Runnable run=new Runnable()
{
public void run()
{
parsing();
handler.postDelayed(run,30000);
}
};
Another approach is by using "AlarmManager"
That is a weird need, only parsing when necessary would probably be a lot better.
Anyway, you should have a look at Timers and background services but be sure of what you are doing : if you create a background service that make a network call twice every minute, if that call is costly, you could cost a lot of data and/or battery to your users which is not a good idea.
You can do it using a timer.
Timer myTimer = new Timer();
After that you can call use the schedule method to call your json parser method.
myTimer.schedule(new TimerTask()
{
public void run() {
timerMethod();
}
}, 0, 1000);
private void timerMethod()
{
this.runOnUiThread(doSomething);
}
private Runnable doSomething = new Runnable() {
public void run() {
// Your code for doing something
}

how to stop/cancel android CountDownTimer

I'm extending the CountDownTimer class to obtain some custom functionality .In onTick() in case some conditions are met I call cancel() , expecting that will be the end of it, however the onTick() callback gets call until the the count down is reached . So how to prevent this from happening ?
CountDownTimer.cancel() method seems to be not working. Here's another thread without a solution Timer does not stop in android.
I would recommend you to use Timer instead. It's much more flexible and can be cancelled at any time. It may be something like that:
public class MainActivity extends Activity {
TextView mTextField;
long elapsed;
final static long INTERVAL=1000;
final static long TIMEOUT=5000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextField=(TextView)findViewById(R.id.textview1);
TimerTask task=new TimerTask(){
#Override
public void run() {
elapsed+=INTERVAL;
if(elapsed>=TIMEOUT){
this.cancel();
displayText("finished");
return;
}
//if(some other conditions)
// this.cancel();
displayText("seconds elapsed: " + elapsed / 1000);
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, INTERVAL, INTERVAL);
}
private void displayText(final String text){
this.runOnUiThread(new Runnable(){
#Override
public void run() {
mTextField.setText(text);
}});
}
}
CountDownTimer is also working fine for me, but I think it only works if you call it OUTSIDE of the CountDownTimer implemetation (that is don't call it in the onTick).
Calling it inside also didn't worked.
I tried this code snippet, since most answers are saying you cannot cancel the timer inside its implementation, thus i tried using a handler inside onFinish. Old post but if anyone comes across this its helpful.
new Handler().post(new Runnable() {
#Override
public void run() {
timerTextView.setText("00:" + String.format("%02d", counter));
cancel();
}
});

Categories

Resources