Implementing Timer Task makes the application to crash - android

I am developing an application in which I want to implement timer task to print a toast message every 5 seconds. The problem is my application crashes after 5 seconds when i run it.Below is part of my code please tell me where I am making mistakes and how can I overcome it.
public class main_activity extends Activity implements BluetoothLeUart.Callback{
public ImageButton fabbutton;
Activity activity;
Timer time;
TimerTask timetask;
Handler handle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity);
fabbutton = (ImageButton) findViewById(R.id.fabbutton);
startTimer(); //this is where I start my timer task
fabbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
scanLeDevice(false);
Intent intent = new Intent(getApplicationContext(), ScanList.class);
startActivity(intent);
}
});
}
public void startTimer(){
time = new Timer();
initializeTimerTask();
time.schedule(timetask, 5000, 10000);
}
public void initializeTimerTask(){
timetask = new TimerTask() {
#Override
public void run() {
handle.post(new Runnable() {
#Override
public void run() {
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(getApplicationContext(),"Timer...", duration);
toast.show();
}
});
}
};
}
public void stoptimertask() {
//stop the timer, if it's not already null
if (time != null) {
time.cancel();
time = null;
}
}
}

you forgot to initialize handler,
Just add below line in oncreate or startTimer();
handle = new Handler();
Or even in your case you can use,
runOnUiThread(new Runnable(){
#Override
public void run() {
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(getApplicationContext(),"Timer...", duration);
toast.show();
}
});

Related

Launch an Activity after timer

So I have this code, that has a countdown timer in a service with a 10 second timer. What I want to do is in the onFinish() method I want to launch the Activity (which is called MainActivity) automatically even when I am outside the app.
public class TimeDisplayTimerTask extends TimerTask{
CountDownTimer timer;
NotificationCompat.Builder notification;
private static final String TAG="com.timer";
private Handler mHandler = new Handler();
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
timer = new CountDownTimer(10000, 1000) {
#Override
public void onFinish(){
}
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG,"" + millisUntilFinished/1000);
}
};
timer.start();
}
});
}
}
Try This to open your main activty after 10 second.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// launch your main activity here and finish your current activity
}
}, 10000);
}
Probably you will have to override lifecycle method's and also use PARTIAL_WAKE_LOCK to keep cpu running untill you finish execution, in case user lock screen.
If you are inside a service then simply launch you activity using intent. Put this code in your onFinish() method:
Intent i = new Intent();
i.setClass(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
You neet to pass an activity context to your TimeDisplayTimerTask :
public class TimeDisplayTimerTask extends TimerTask{
CountDownTimer timer;
NotificationCompat.Builder notification;
private static final String TAG="com.timer";
private Handler mHandler = new Handler();
private Activity mActivity;
public TimeDisplayTimerTask(Activity activity){
mActivity = activity;
super();
}
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
timer = new CountDownTimer(10000, 1000) {
#Override
public void onFinish(){
if (activity != null {
Intent startIntent = new Intent(activity, MainActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(startIntent);
}
}
#Override
public void onTick(long millisUntilFinished) {
Log.i(TAG,"" + millisUntilFinished/1000);
}
};
timer.start();
}
});
}
}

How to create Timer Task OUTSIDE onCreate in Android Studio?

So I have a very stupid problem. I am able to create a simple timer task that ticks every second:
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (counter == 0) {
//Reload Map...
timer.cancel();
Intent intent = new Intent(MapsActivity.this, MapsActivity.class);
startActivity(intent);
} else {
TimeLabel.setText(Integer.toString(counter));
counter = counter - 1;
}
}
});
}
}, 0, 1000);
After one minute, it will reload my google map. But when I try to open other activity, and try to go back to Map, my MapsActivity is not killed, (even though I used finish();). That's is why my timer is overlapping.
I have a guess that I should create the timer OUTSIDE onCreate, but didn't success in doing so. Can you help me guys?
Try this
public class MainActivity extends Activity {
//Global Variables
Timer timer;
TimerTask task;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Make a method to make it cleaner
setTimer();
}
private void setTimer() {
timer = new Timer();
task = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (counter == 0) {
//Reload Map...
timer.cancel();
Intent intent = new Intent(MapsActivity.this, MapsActivity.class);
startActivity(intent);
} else {
TimeLabel.setText(Integer.toString(counter));
counter = counter - 1;
}
}
});
}
};
}
#Override
protected void onResume() {
super.onResume();
//This will be called after onCreate or your activity is resumed
timer.schedule(task, 0, 1000);
}
#Override
protected void onPause() {
super.onPause();
//This will be called if the app is sent to background or the phone is locked
//Also this prevent you from duplicating the instance of your timer
timer.cancel();
}
}

Invalidate() is not happening from Activity in Timer

This is my code on Activity to Invalidate the canvas it is not invalidating. Means onDraw() is not getting called even once;
public GraphView view;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
view = GraphView(this,null);
runplotTimer();
}
public void runplotTimer()
{
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
InvalidateTimer();
}
},1000,40);
}
public void InvalidateTimer()
{
this.runOnUiThread(new Runnable() {
#Override
public void run()
{
//Log.d(ALARM_SERVICE, "Timer of 40 miliseconds");
view.InvalidateGraph();
}
});
}
on View class this is method which is gettting called from Activity. other OnDraw declaration is same as required.
public void InvalidateGraph()
{
m_bCalledPlotRealTimeGraph = true;
invalidate(chanX_count1, 0, chanX_count1+7, graphheight);
}
Any help please ?
You are attempting to make changes to the View on a Timer Thread, which will not work. You need to call invalidate on the main (UI) thread:
((Activity) view.getContext()).runOnUiThread(new Runnable() {
#Override
public void run() {
invalidate(chanX_count1, 0, chanX_count1+7, graphheight);
}
});
you need to Start the Timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
InvalidateTimer();
}
},1000,40);
t.start()
Instead of Timer use Handler.
class UpdateHandler implements Runnable {
#Override
public void run(){
handler.sendEmptyMessageAtTime(0, 1000);
handler.postDelayed(this, 1000);
}
}
private Handler handler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//Call your draw method
}
}
};
Inside onCreate and onResule write
if( mupdateTask == null )
mupdateTask = new UpdateHandler();
handler.removeCallbacks(mupdateTask);
Call your handler using
handler.postDelayed(mupdateTask, 100);

Handler runnable breaks application

I have timer which schedules each 1 sec, and as we can't toast in timertask I used handler.post(). But this code breaks my app:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
String text = (String) msg.obj;
sec_view.setText(text);
}
};
MyTimerTask myTask = new MyTimerTask();
timer = new Timer();
timer.schedule(myTask, 1000, 1000);
}
Runnable makeToast = new Runnable() {
public void run() {
Toast.makeText(null, "qwerty", Toast.LENGTH_LONG).show();
}
};
class MyTimerTask extends TimerTask {
public void run(){
if(0 == --sec){
handler.post(makeToast); //breaks there
timer.cancel();
}
Message msg = new Message();
msg.obj = sec+" sekund";
handler.sendMessage(msg);
}
}
Can I use anything else to toast from timertask?
currently you are passing null as Context in Toast.makeText.just pass context instead of null to show toast
Toast.makeText(Your_Activity.this, "qwerty", Toast.LENGTH_LONG).show();
and to show Toast or access UI elements from timertask run method use runOnUiThread() as
public void run() {
Current_Activity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
//show your toast here
}
});
}
change toast to
Toast.makeText(getApplicationContext(), "qwerty", Toast.LENGTH_LONG).show();
then add
#override annotation above void run in handler

changing image s for 1 second in android imageview

I am trying to change image after 1 second for image view.but its doesn't show any image on screen. following is code.please help.thank you.
code-
public class Shapes extends Activity {
Timer timer = new Timer();
int flag;
String images[]={};
ImageView iv;
static int v[]={R.drawable.round,R.drawable.rectangle};
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.shapes);
iv=(ImageView) findViewById(R.id.imageView1);
timer.schedule(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
if (flag > 1) {
timer.cancel();
timer = null;
} else
iv.setImageResource(v[flag++]);
}
});
}
}, System.currentTimeMillis(), 1000);
}
}
how can i check resource image and change it
Use Handler instead of Timer
Handler handler = new Handler();
Runnable changeImage = new Runnable(){
#Override
public void run(){
if(flag>1)
handler.removeCallbacks(changeImage);
else{
iv.setImageResource(v[flag++]);
handler.postDelayed(changeImage, 1000);
}
}
};
start the first time from oncreate()
public void onCreate(Bundle b){
handler.postDelayed(changeImage, 1000);
}
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
flag++;
if (flag > 1) {
timer.cancel();
timer = null;
}
else
iv.setImageResource(v[flag]);
}
});
}
}, 1000, 1000); // wait 1 second before start.. then repeat every second..
It's because you put System.currentTimeMillis() as delay.
Try replacing that with 0, because the time should start after 0 ms.

Categories

Resources