Is there any way to show a toast when the service is running on a separate thread?
I use the code below.
public void onStart(Intent intent, int startid){
final String name = intent.getStringExtra("name");
Log.d(TAG,"onStart()");
new Thread(new Runnable() {
public void run() {
try
{
Toast.makeText(getApplicationContext(), "Ashish 1",Toast.LENGTH_LONG).show();
}
catch(Exception e)
{
Log.d(TAG,"Exception....."+e);
}
}
}).start();
}
Toast messages can only shown on uithread. But if you want to use on another thread, you can implement it like this.
yourActivityObject.runOnUiThread(new Runnable() {
public void run()
{
Toast.makeText(yourContextObject, "some text",Toast.LENGTH_LONG).show();
}
});
Related
I am using a toast for Count Down Timer, so the toast should change it's text in every second. I use this to display the toast for exactly 1 second but i want the toast to repeat itself. Hope i make you understand.
toast = Toast.makeText(getApplicationContext(), text.getText().toString(), Toast.LENGTH_SHORT); toast.show();
Handler handler = new Handler();
handler.postDelayed
(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 1000);
This will show a new toast every second for exactly one second.
int count = 100; //Declare as inatance variable
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
final Toast toast = Toast.makeText(
getApplicationContext(), --count + "",
Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 1000);
}
});
}
}, 0, 1000);
run() is called after every second. so show toast there.
Handler handler = new Handler();
handler.postDelayed
(new Runnable() {
#Override
public void run() {
toast.cancel();
toast = Toast.makeText(getApplicationContext(), text.getText().toString(),Toast.LENGTH_SHORT);
toast.show();
}
}, 1000);
This page describes a way to keep the toast be shown indefinitely. So when you have the text view of the toast on hand, you may change the text as you like.
you have to learn more about android srvices
create java class extends from IntentService
override this function
#Override
protected void onHandleIntent(Intent intent) {
try {
Toast.makeText(context,"Click on Location button to find your bus !",Toast.LENGTH_LONG).show();
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
go to manifest an type
go to your launcher java class and
Intent intent = new Intent(this, Service_toast.class);
startService(intent);
====>> for more information about services vist android devloper :
https://developer.android.com/guide/components/services.html
I have try build a android application that use a thread inside a service, the service and the thread run with well, but when i stop and destroy the service, the thread still live, so when i run again the application there are 2 thread in the application, so i wannt to know how i can destroy the thread.
anybody can help me to solve the problem ?
here my service class :
public class MyService extends Service{
Handler handler;
static String toast_msg;
Thread t;
private static final String TAG = "MyService";
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "Congrats! MyService Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
}
#Override
public void onStart(Intent intent, int startId) {
/* Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
//Note: You can start a new thread and use it for long background processing from here.*/
toast_msg = "Horas";
super.onStart(intent, startId);
Toast.makeText(getApplicationContext(), toast_msg, Toast.LENGTH_LONG)
.show();
handler = new Handler() {
public void handleMessage(android.os.Message msg) {
super.handleMessage(msg);
Toast.makeText(getApplicationContext(), toast_msg,
Toast.LENGTH_LONG).show();
}
};
t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
t.sleep(5000);
// Toast.makeText(getApplicationContext(), "Horas",
// Toast.LENGTH_LONG).show();
handler.sendEmptyMessage(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
t.start();
}
#Override
public void onDestroy() {
Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
//t.interrupt();
handler.removeCallbacks(t);
super.onDestroy();
t.currentThread().interrupt();
}
}
t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
if(flag){//here add a flag
return;
}
t.sleep(5000);
// Toast.makeText(getApplicationContext(), "Horas",
// Toast.LENGTH_LONG).show();
handler.sendEmptyMessage(0);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
t.start();
public void onDestroy() {
Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
//t.interrupt();
handler.removeCallbacks(t);
super.onDestroy();
flag = false;//here set flag to false
}
You may want to consider using Service or IntentService instead, as these provide better management of threads, pausing, restarting etc.
See the Android IntentService documentation, or this other StackOverflow question and answer session. There's not much call to be kicking off your own threads these days, as there's better threading/service management features provided by the Android API/SDKs.
These are much more stable, optimised, and (in my opinion) neater and cleaner to use than spinning up a raw thread and trying to manage it yourself, especially if you're not catering for your app suddenly being killed because the battery went flat or the user doing something unexpected.
I'm trying to send a toast notification of an error in a thread. The thread is started in a service that is called from the main thread. I've tried several things with View.post and some weird handler stuff, but nothing seems to work. An excerpt of the thread is as follows:
public int onStartCommand(Intent intent, int flags, int startId)
{
new Thread(new Runnable(){
public void run() {
boolean bol = true;
while (bol)
{
try
{
//Some socket code...
}
catch (Exception e)
{
//Where I want the toast code.
}
}
}
}).start();
return START_STICKY;
}
Try following inside the thread in the service:
Handler h = new Handler(context.getMainLooper());
// Although you need to pass an appropriate context
h.post(new Runnable() {
#Override
public void run() {
Toast.makeText(context,message,Toast.LENGTH_LONG).show();
}
});
Taken from answer given by #Alex Gitelman here on Android: How can i show a toast from a thread running in a remote service? . This might help somebody as it helped me.
Toast can be shown only from UI Thread (Main Thread). To show Toast from some other threads you have to use Handler.
Threads, Handlers and AsyncTask
Yes you should use a Handler, and bind you Activity to your Service
Once the Handler is set, here is what you should do,
Message msg = Message.obtain(null, MyActivity.TOAST);
Bundle bundle = new Bundle();
bundle.putString(MyActivity.TOAST_MSG, "Toast message");
msg.setData(bundle);
try {
myActivityMessenger.send(msg);
} catch (RemoteException e) {
if (D) Log.w(TAG, "Unable to send() the toast message back to the UI.");
e.printStackTrace();
}
myActivityMessenger is set with the Handler of your MyActivity and sent to the Service when you bind MyActivity to it.
However displaying a Toast with a Service as context should work (but it's not the best way), so maybe it's because you try to make it from a new Thread. What is your code for making the Toast ?
new Thread(){
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
_dialog.dismiss();
Toast.makeText(LatestNewsActivity.this, "NO Internet Connection Available", Toast.LENGTH_LONG).show();
}
});
}
}.start();
I have a very simple UI and i need to constantly run a check process, so I am trying to use a Thread with a while loop.
When I run the loop with nothing but a Thread.sleep(1000) command, it works fine, but as soon as I put in a display.setText(), the program runs for a second on the emulator then quits. I cannot even see the error message since it exits so fast.
I then took the display.setText() command outside the thread and just put it directly inside onCreate, and it works fine (so there is no problem with the actual command).
here is my code, and help will be greatly appreciated.
Thank you!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
on=(Button) findViewById(R.id.bon);
off=(Button) findViewById(R.id.boff);
display=(TextView) findViewById(R.id.tvdisplay);
display2=(TextView) findViewById(R.id.tvdisplay2);
display3=(TextView) findViewById(R.id.tvdisplay3);
stopper=(Button) findViewById(R.id.stops);
stopper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(boo=true)
{
boo=false;
display3.setText("System Off");
}
else{
boo=true;
}
}
});
Thread x = new Thread() {
public void run() {
while (boo) {
display3.setText("System On");
try {
// do something here
//display3.setText("System On");
Log.d(TAG, "local Thread sleeping");
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e(TAG, "local Thread error", e);
}
}
}
};
display3.setText("System On");
display3.setText("System On");
x.start();
}
You can't update the UI from a non-UI thread. Use a Handler. Something like this could work:
// inside onCreate:
final Handler handler = new Handler();
final Runnable updater = new Runnable() {
public void run() {
display3.setText("System On");
}
};
Thread x = new Thread() {
public void run() {
while (boo) {
handler.invokeLater(updater);
try {
// do something here
//display3.setText("System On");
Log.d(TAG, "local Thread sleeping");
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e(TAG, "local Thread error", e);
}
}
}
};
You could also avoid a Handler for this simple case and just use
while (boo) {
runOnUiThread(updater);
// ...
Alternatively, you could use an AsyncTask instead of your own Thread class and override the onProgressUpdate method.
Not 100% certain, but I think it is a case of not being able to modify UI controls from a thread that did not create them?
When you are not in your UI thread, instead of display3.setText("test") use:
display3.post(new Runnable() {
public void run() {
display3.setText("test");
{
});
You should encapsulate this code in an AsyncTask instead. Like so:
private class MyTask extends AsyncTask<Void, Void, Void> {
private Activity activity;
MyTask(Activity activity){
this.activity = activity;
}
protected Long doInBackground() {
while (true){
activity.runOnUiThread(new Runnable(){
public void run(){
display3.setText("System On");
}
});
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
Log.e(TAG, "local Thread error", e);
}
}
}
Then just launch the task from your onCreate method.
In non-UI thread,you can't update UI.In new Thread,you can use some methods to notice to update UI.
use Handler
use AsyncTask
use LocalBroadcast
if the process is the observer pattern,can use RxJava
I have a service B that sends a specific number of messages in a fixed interval.
this service is called from another service A.
the code used in service A is
#Override
public void onStart (Intent intent,int startid)
{
Toast.makeText(this, "Service A Running onStart", Toast.LENGTH_LONG).show();
Thread MessagesThread = new Thread(new Runnable()
{
public void run()
{
ApplicationPreferences AppPrefs = new ApplicationPreferences(getApplicationContext());
int NumberOfMessagesToSend = Integer.parseInt(AppPrefs.getNumberOfMessagesToSend());
int NumberOfSentMessages;
for (NumberOfSentMessages = 0 ; NumberOfSentMessages < NumberOfMessagesToSend; NumberOfSentMessages++ )
{startServiceB();
}
}
});
MessagesThread.start();
}
public void startServiceB()
{
final Intent sendingMessages = new Intent(this, ServiceB.class);
startService(sendingMessages);
}
the toasts are to keep track of what is happening
The code in service B is as follow
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
Toast.makeText(getApplicationContext(), "Service B at start ", Toast.LENGTH_LONG).show();
new CountDownTimer(30000,1000)
{
public void onTick (long millisUntilFinished) {}
public void onFinish()
{
showToast();
}
}.start();
}
the showToast() function is as follow
public void showToast()
{
Toast.makeText(getApplicationContext(), "Service B in timer", Toast.LENGTH_LONG).show();
}
As I said I am using the toasts to keep track of what's happening. the problem is when running it, i am getting the first toast (service B at start) 10 times consequently then the second one (service B in timer) 10 times consequently with no time between them.
how do i make each of this toasts appear once every 30 seconds?
Ok, so the final answer could be something like this:
Call only once the B service and in it we will have the handler that will loop at an interval of 30 seconds..
Service B code:
int loop = 5;
int counter = 0;
Handler myHandler;
Runnable run;
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
Toast.makeText(getApplicationContext(), "Service B at start ", Toast.LENGTH_LONG).show();
myHandler = new Handler();
run = new Runnable()
{
public void run()
{
if (counter<loop){
showToast();
counter++;
} else {
myHandler.removeCallbacks(run);
}
}
};
myHandler.postDelayed(run, 30000);
}
I hope this helps someone else too!
If you want to make a toast every 30 seconds than you can do it by using a handler:
Handler myHandler = new Handler();
Runnable run = new Runnable()
{
public void run()
{
showToast();
}
};
myHandler.postDelayed(run, 30000);
If you have problem with this just post here and I will try to help you..