Android Service...application crashes when making a Toast - android

This is my Service class:
public class MySrv extends Service {
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
final Context c = getApplicationContext();
Timer t = new Timer("mytimer");
TimerTask task = new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(c, "Not a beautyfull day today...", Toast.LENGTH_SHORT).show();
}
};
t.schedule(task, 5000, 6000);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
The application crashes at Toast.makeText()... So what am I doing wrong?

The TimerTask's run() method doesn't execute in the UI thread, so you can't do UI-related things like creating a Toast.
Investigate using a Handler or runOnUiThread() instead.
Example:
final Handler handler = new Handler ();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post (new Runnable (){
#Override
public void run() {
Toast.makeText(c, "Not a beautyfull day today...", Toast.LENGTH_SHORT).show();
}
});
}

The problem here is that you are trying to update the UI in the timers thread, you should use a Handler for this.
Read How to display toast inside timer?

You cannot make a Toast in another Thread, you can use a Handler to do it or use the runOnUiThread.
public class YourActivity extends Activity {
private Handler toastTeller;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
toastTeller = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 2)
Toast.makeText(LibraryActivity.this, msg.obj.toString(),
Toast.LENGTH_LONG).show();
super.handleMessage(msg);
}
};
new Thread(new Runnable(){
public void run(){
Message msg = new Message();
msg.what = 2;
msg.obj = "Your item was downloaded.";
toastTeller.sendMessage(msg);
}
}).start();
}

Related

android implements runnable not working?

this is a simple code to understand the runnable .I tried but not working . can you guys help me pls this is my code
public class Autostart extends activity implements Runnable {
#override
public void run (){
System.out.println ("message");
}
}
}
this not printing any statements
If you are using an Activity, you need to write your code inside Activity lifecycle methods. onCreate() is called when the Activity is created. So starting your Runnable here would be the correct way to do it.
#Override
public void onCreate(Bundle savedInstanceState) {
Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
System.out.println ("message");
}
};
handler.postDelayed(r, 1000);
}
You have to create a Thread object and call start() using that object.
Thread t = new Thread(this);
t.start();
Or Just use Handler
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do Something here
}
}, 5000);
You can use below code to print a value after regular interval of time
public void callAsynchronousTask() {
final Handler handler = new Handler();
timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
Log.e("on print timee", your value);
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 1000); // will execute after 1 sec
}
Hope this will help you
I found a similar solution to Swayam (android implements runnable not working?), however another handler.postDelayed reference within run() was required;
public void onCreate(
...
final Handler handler = new Handler();
final Runnable r = new Runnable()
{
public void run()
{
Log.i(TAG, "message");
handler.postDelayed(this, 1000);
...
}
};
handler.postDelayed(r, 1000);
Try following code
Handler mainThreadhandler = new Handler(getMainLooper());
mainThreadhandler.post(new Runnable(){
public void run(){
// UI work
}
});
public class Autostart extends activity implements Runnable {
Thread = thread;
#override
public void onCreate() {
thread = new Thread(this);
thread.start();
}
#override
public void run (){
System.out.println ("message");
}
}

Implementing Timer Task makes the application to crash

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();
}
});

is really all of the Handler objects for a particular thread receive the same message

Quoting from this
Inside the Handler, override the handleMessage() method. The Android system invokes this method when it receives a new message for a thread it's managing; all of the Handler objects for a particular thread receive the same message.
My doubt is here : all of the Handler objects for a particular thread receive the same message
I have created a activity, which have below code
#Override
protected void onPostCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onPostCreate(savedInstanceState);
self = new Handler(Looper.getMainLooper()){
#Override
public void handleMessage(Message msg) {
Log.e(TAG,"HAndle MainActivity: "+msg.what);
};
};
sen = new Sender(new Handler(Looper.getMainLooper()), Thread.NORM_PRIORITY);
sen.start();
sen.repeatMsg();
}
Where sender is a thread, which creates a Handler(Looper.getMainLooper())
public class Sender extends Thread{
protected static final String TAG = "Sender";
private Looper mLooper;
private Handler uiHandler;
private int mPriority;
public Sender(Handler handler,int priority) {
// TODO Auto-generated constructor stub
mPriority = priority;
uiHandler = handler;
}
#Override
public void run() {
// TODO Auto-generated method stub
Log.e(TAG,"Inside run");
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
// setPriority(mPriority);
Process.setThreadPriority(mPriority);
Looper.loop();
Handler msgHandler = new Handler(mLooper){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.e(TAG,"Inside handleMessage "+msg.what);
}
};
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been
// created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public void repeatMsg() {
Log.e(TAG,"Inside repeatMsg");
Timer t = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() {
Handler h = new Handler(Looper.getMainLooper());
Message m = Message.obtain();
m.what = 1000;
h.dispatchMessage(m);//sendMessage(m);
repeatMsg();
}
};
t.schedule(tt, 2000);
}
}
What i expect is , the dispatched message should be received by the self handler, because both handlers bound to same thread, and is what the quoted statement states. But self's handleMessage is never called.
Why this mess?? What i mis understood??
What i should do to get my expected behaviour?
Also, Consider again a SeconMainActivity, which is similar to MainActivity, On some click event, say, the SeconMainActivity is launched, with same onPostExecute of MainActivity. Meanwhile, the Sender thread is still repeating the message. Now, who will receive the handleMessge call??
MainActivity ?
SecondMainActivity ?
Handler inside Sender Thread ?
None !
Update : Year 2018 , the doc still reads the same

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

Android: Accessing UI Element from timer thread

public Button stb;
static int cnt=0;
public ArrayList<RadioButton> Butgrp1 = new ArrayList<RadioButton>();
Timer myt;
TimerTask t;
stb.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
myt.mschedule(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Entering run");
Handler h=new Handler();
h.post(new Runnable() {
public void run() {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
Butgrp1.get(cnt).setChecked(true);
cnt=cnt+1;
if(cnt>4)
cnt=0;
if(cnt>0)
// Butgrp1.get(cnt-1).setChecked(false);
System.out.println(cnt);
}
});
}
});
//rg.getChildAt(cnt).setPressed(true);
}
},1000,2000);
I need to access a group of radio buttons on the ui and set it as checked at regular intervals, but i keep getting different errors, i realized i must use a handler, but its still not working...can anyone please tell me where i am going wrong....am a newbie and am trying out stuff to understand the working better...please help...
You have to create the Handler in the UI Thread, i.e. in onCreate of your Activity.
Because you create it in the run method of a background thread, the handler will execute your code in that very same background thread.
You could also initialize your Handler directly:
public class MyActivity extends Activity{
private Handler handler = new Handler();
//more code
}
And then don't use runOnUIThread:
handler.post(new Runnable() {
public void run() {
// TODO Auto-generated method stub
Butgrp1.get(cnt).setChecked(true);
cnt=cnt+1;
if(cnt>4)
cnt=0;
if(cnt>0)
// Butgrp1.get(cnt-1).setChecked(false);
System.out.println(cnt);
}
});
EDIT:
Ok try this cleaned up code. Because you did not post your full Activity this won't work out of the box:
public class TestActivity extends Activity {
private Button button;
static int cnt=0;
public ArrayList<RadioButton> buttonArray = new ArrayList<RadioButton>();
private Timer timer = new Timer();
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
timer.schedule(new MyTimerTask(), 1000,2000);
}
});
}
private void doButtonStuff(){
buttonArray.get(cnt).setChecked(true);
cnt=cnt+1;
if(cnt>4){
cnt=0;
}
if(cnt>0){
// Butgrp1.get(cnt-1).setChecked(false);
System.out.println(cnt);
}
}
private class MyTimerTask extends TimerTask{
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
doButtonStuff();
}
});
}
}
}
You can pass the Activity as a parameter to the method that runs the timertask, and then you can use Activity.runOnUiThread to execute your tasks in UI Thread. There are lots of post in stackoverflow site regarding the usage of runOnUiThread usage.
You don't need to call runOnUIThread inside the handler. By calling post on the Handler instance, the runnable you pass will be executed on the UI thread at some point in the future. Change your code to look like this and it should work:
Handler h=new Handler();
h.post(new Runnable() {
public void run() {
// TODO Auto-generated method stub
Butgrp1.get(cnt).setChecked(true);
cnt=cnt+1;
if(cnt>4)
cnt=0;
if(cnt>0)
// Butgrp1.get(cnt-1).setChecked(false);
System.out.println(cnt);
}
});

Categories

Resources