I have an activity (MapActivity actually) that has a linearLayout with a mapView and a textView, for displaying current speed, among other things. The thing is that I would like the textView to be updated every 0.5 seconds, for example.
I know this can be done with a service (at least that is how I learnt to do it), but I was wondering if it is possible to do so using a Timer inside the MapActivity itself. I tried this approach:
onCreate{
...
updateTimer = new Timer();
updateTimer.scheduleAtFixedRate(doRefresh, 0, updateInterval);
}
private Timer updateTimer;
private TimerTask doRefresh = new TimerTask()
{
public void run()
{
updateData();
}
};
private void updateData()
{
//update the textView with the data
}
private int updateInterval = 500;
However, it gives me the following error:
04-10 22:24:56.529: ERROR/AndroidRuntime(9434): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Then, is it possible to do what I'm trying in an easy way, without using a service class?
Thank you and regards,
=)
Call postDelayed() on some widget, supplying a Runnable and 500 as the delay. The Runnable should do whatever work you want done, then call postDelayed() again with itself as the Runnable and 500 as the delay.
This avoids background threads and services, which are not needed for simple timing events in an activity.
Related
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);
I have a runnable class like this:
public class GetUpdatesThread implements Runnable{
#Override
public void run() {
//call a webservice and parse response
}
}
Which I want fire every 10 seconds for instance...
I would like to know how can I manage handlers or runnables or timers in my activity to acomplish this?
Thanks in advance!
You can use TimerTask and can implement like this.
int delay = 5000; // delay for 5 sec.
int period = 10000; // repeat every 10 secs.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("repeating");
}
}, delay, period);
You can use the timer method called scheduleAtFixedRate from this link. I am already using it inside my project and it works like charm. You just have to give a starting delay time and a period for it then it works.
You can use Handler and calling the sendEmptyMessageDelayed method. Here's a tutorial or two on using Handler. Also check out Updating the UI from a Timer from the official doc - it covers both approaches with TimerTask and Handler.
The best way to do this thing is to use AlarmManager class.
1) schedule a AlarmManager with serRepeat method. link for AlarmManager
2) set Broadcast receiver in Alarmmanager, it will call Receiver every particular time duration, now from Receiver you can start your thread .
if you use Timer task and other scheduler, Android will kill them after some time.
I has use OnTouchListener to visible layout1 while screen was touch.
Now I want invisible layout1 while the screen didn't be touch three seconds.
But I don't know which event listener can I use?
Now the problem has be resolved.
But another one was appear.
I use:
class unTouchTask extends TimerTask {
public void run() {
if(untouch == true) {
RelativeLayout rl = (
RelativeLayout)findViewById(R.id.relativeLayout2);
rl.setVisibility(View.INVISIBLE);
timer.cancel();
untouch = false;}
}
}
Below error on linerl.setVisibility(View.INVISIBLE);:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Option1 : You need to run a timer to track the user intraction inactive time, and on every user touch you will need to reset the timer.
Code your timer as below:
class UpdateTimeTask extends TimerTask {
public void run() {
//hide your layout
}
}
And in the event listener to start this update, the following Timer() instance is used:
if(startTime == 0L) {
startTime = evt.getWhen();
timer = new Timer();
timer.schedule(new UpdateTimeTask(), 300, 200);
}
NOTE :In particular, note the 300, 200 parameters. The first parameter means wait 300 ms before running the clock update task the first time. The second means repeat every 200ms after that, until stopped.
Option 2: Fortunately, the role of Timer can be replaced by the android.os.Handler class, with a few tweaks
You can get more detailed example at http://www.vogella.de/articles/AndroidPerformance/article.html
Regards.
You can use the Timer and TimerTask to schedule something to happen in a time interval.
If the user ever touches the screen, cancel the timer and reset it. You will need to UI related stuff in the UI thread. This article will give you an idea.
You are getting this Error because You can use threads but all the views, and all the views related APIs, must be invoked from the main thread (also called UI thread.) So the solution to this is to use the Handler. A Handler is an object that will post messages back to the UI thread for you. http://developer.android.com/reference/android/os/Handler.html will guide you to code handlers.
The second option is to use runOnUiThread. Following is what I do in my thread :
runOnUiThread(new Runnable() {
public void run() {
titleProgress.setVisibility(View.VISIBLE);
}
});
//long operation here
runOnUiThread(new Runnable() {
public void run() {
titleProgress.setVisibility(View.INVISIBLE);
}
});
Every 5 seconds, I want to call my webservice and get text (not images), then display it in my ImageAdapter. What would be the best way to accomplish this?
final Handler handler = new Handler();
final Runnable r = new Runnable()
{
public void run()
{
callWebservice();
}
};
handler.postDelayed(r, 5000);
It depends if you want to use a different thread or not. Do you want the user to be able to interact with the application on the UI Thread while the images are downloading? If so, then I would definitely use an AsyncTask with a small ProgressBar (style="#android:style/Widget.ProgressBar.Small")
If you don't care about threading then what #inazaruk said.
Edit: the truth is most modern apps that retrieve data from a web service will use an AsyncTask with a discreet little loader in the corner just to let the user know it's updating.
Edit 2: here's an example of using a TimerTask to run something every 5 seconds. The key is the runOnUiThread(). There may be better ways to tie all the elements together but this accurately portrays all the pieces.
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
CallWebService();
}
}, 0, 1000);
}
private void CallWebService()
{
this.runOnUiThread(fetchData);
}
private Runnable fetchData = new Runnable() {
public void run() {
asyncTask.execute();
}
};
You should call asynctask inside the application main thread. Asynctask can't be called in a background thread.
I am new to Android and I am having trouble understanding the concept so basically this is what i want to do to understand it better..
I created a DrawShape class that extends view. In this class in the OnDraw() I am creating a circle and filling it with a color.
From the Activity I am calling the application. //Until this point I am doing fine.
Now, I need to re-paint the Circle multiple times (Blue, Red, Yellow etc..)
So I was reading and the best way is to use Threads.. I also read you need to use postInvalidate() to redraw (I still dont understand from where I should be calling this) is this called from the Activity?, or within the OnDraw()?.
Hopefully you understand what i want to accomplish, is just that i havent found a good tutorial that shows this, how to repaint something x amount of times .. when I do Thread.sleep() it all stops then it shows my app.. but now i understand why, because i am playing with the main Thread.
Please help me understand this..
Thank you
i did something like this
animcolor()
{
Timer timer = new Timer();
int delay = ...;
int period = ...;
timer.schedule(new TimerTask(){
run() {
setColor( randomint() ); )
customview.postInvalidate();
}
}, delay, period);
threads? not necessary to create them; Timers make a good job on concurrency.
... and the code would somewhat look like....
res/layout/file.xml
<org.customviewlayout a:id="#+id/customlayout"/>
src/org.MyActivity.java
class MyActivity
{
onCreate()
{
customlayout = findViewById(R.id.customlayout);
customlayout.animcolor();
}
}
src/org.customlayout.java
import org.customview;
class customlayout
{
customview;
customlayout(context, attrs)
{
customview = new customview();
addview(customview); // so it's onDraw() method will be called
}
onlayout(...)
{
customview.layout(...);
}
animcolor()
{
Timer timer = new Timer();
int delay = ...;
int period = ...;
timer.schedule(new TimerTask(){
run() {
setColor( randomint() ); )
customview.postInvalidate();
}
}, delay, period);
}
setcolor(int)
{
....
}
}
i think, you can do this using a Timer and a TimerTask inside your activity. The TimerTask runs with the delay you specify and when run all you what to do is yourDrawShapeInstance.postInvalidate();
the mechanism is this, because you arent on the ui thread you call postInvalidate() to add an invalidate on the ui queue, when the ui engine pick the delayed invalidate that you invoke before, then calls automatically the onDraw method of your DrawShape view and the view will be redrawed.
(i donĀ“t test this, i write here)
TimerTask task = new TimerTask(){
public void run(){
myDrawShapeInstance.postInvalidate();
}
}
When drawing, always use a thread away from the main thread and always invalidate after thread has finished (for the most part -- to display current results from drawing). You will probably call your drawing functions from some user-related event, so make sure you're making another thread for that drawing process. Follow those rules and you will be fine.
void drawCircleToCanvas(int color)
{
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
myDrawShapeInstance.postInvalidate();
}
};
Thread updateUI = new Thread() {
public void run() {
//************draw something here***************
handler.sendEmptyMessage(0);
}
};
updateUI.start();
}