Only one instance of Thread in service - android

I initialize new Thread in service but when i start service the new one is made and it make my app crash beacause I use camera in it.
How to make that it will be ony one instance of that Thread?
When Thread is closing? If I close service where I made it, it will be also closed?

you could use a lock or a static variable:
private static boolean isThreadRunning;
and then in your service:
if(isThreadRunning)
return;
Thread t=new Thread(new Runnable(){
protected void run(){
isThreadRunning=true;
while(yourcondition){
//your thread code...
}
isThreadRunning=false;
//if you want to start another thread after this one is ended, you should post a message to a handler here and it should start another thread like this
}
});

You can also achieve this using Handler class, which is recommended by Google in thread operations. The code bellow shows generic example how to use it in Service.
public class MyService extends Service{
private final Handler handler = new Handler();
private final static int RUNABLE_WHAT=6558057;
private final static int PEROID=6*1000;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(!handler.hasMessages(RUNABLE_WHAT))
{
handler.sendMessageDelayed(new Worker().extractMessage(), PEROID);
}
return START_STICKY;
}
private class Worker implements Runnable{
#Override
public void run() {
//DO WORK HERE
handler.sendMessageDelayed(new Worker().extractMessage(), PEROID);
}
private Message extractMessage()
{
Message message = Message.obtain(handler, this);
message.what=RUNABLE_WHAT;
return message;
}
}
}

Related

What kind of services should I use for accessing sensors data in background?

I successfully used a service to do a certain task in the foreground. Now, to do it in the background, I'd remove the handler.removeCallbacks method in onDestroy().
But this would also prevents me from stopping the service using stopService(intent).
I saw on the official docs that I should maybe use JobScheduler (as I target API 28).
Here is a more precise indication of my code :
public class MainActivity {
private Intent intent;
onCreate() {
if (intent == null) {
intent = new Intent(this, MyService.class);
}
}
startService(intent);
... // Then is some code to stop the service if needed with stopService(intent)
}
--------------------------------------------------------------
public class myService {
private Handler handler = null;
private static Runnable runnable = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
System.out.println("Running service times " + i);
i++;
handler.postDelayed(runnable, 1000);
}
};
handler.post(runnable);
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
I would like it to run in the background (even if the device is locked) but still being able to disable the service (or JobScheduler?).
What are your suggestions?
you can use work manager
or job dispatcher
and there is a lot of options like
SyncAdapter, Bound services, Intent Service
you can use one of these options according to your need

How do I stop my thread and will my service stop too if I do?

I'm currently working on my first android app and I've run into a problem.
My app is supposed to be counting in the background using a Service and I'm creating a new thread to handle that. If I don't stop the thread in my Service's onDestroy() method, my phone gives me the message "Unfortunately, (my app) has stopped." every time I close the app. I need to stop it somehow, and I tried to do it using :
while(!Thread.currentThread().isInterrupted()){
**my code**
}:
And then interrupting it in the onDestroy() method.
It works, but it makes my app count extremely fast, so I would like to know if it can be done any other way that does not change the functionaliy of my code.
Also, since my thread gets stopped in the onDestroy method, I guess my service stops as well. Is there any way to keep my service running even when my app has been closed?
Here's my code:
public class CounterService extends Service {
private Handler handler;
private int time = -1;
private boolean isActive;
private Intent timeBroadcaster;
private Runnable counter;
private Thread serviceCounter;
#Override
public void onCreate(){
super.onCreate();
handler = new Handler();
timeBroadcaster = new Intent();
timeBroadcaster.setAction("EXAMPLE_BROADCAST");
counter = new Runnable() {
#Override
public void run() {
isActive = ((PowerManager) getSystemService(Context.POWER_SERVICE)).isInteractive();
if (isActive) {
handler.postDelayed(this, 1000);
time += 1;
} else {
if (time > 5) {
//log
}
time = 0;
handler.postDelayed(this, 1000);
}
timeBroadcaster.putExtra("counter", time);
sendBroadcast(timeBroadcaster);
}
};
serviceCounter = new Thread(counter);
serviceCounter.start();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy(){
//serviceCounter.interrupt();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Is there any way to keep my service running even when my app has been closed?
you can use sync adapter which runs in background even app is stoped.
https://developer.android.com/training/sync-adapters/creating-sync-adapter.html

Android create handler inside thread into Service

i'm writing simple android service and i want to use such as Toast or Notification but i get this error:
FATAL EXCEPTION: Thread-17116
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
i can not use runOnUiThread . my service does not know that. for example i try to use that with : this, getBaseContect(), getApplication, mContext for .runOnUiThread(new Runnable() {}
i get problem and i can not resolve problem.
this is my code:
public class TsmsService extends Service {
private Timer smsThread;
private DatabaseHandler db;
private SQLiteDatabase dbHelper;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
smsThread = new Timer();
GetSMSThread getSMSThread = new GetSMSThread(getBaseContext());
smsThread.scheduleAtFixedRate(getSMSThread, 0, 1000); //(timertask,delay,period)
return super.onStartCommand(intent, flags, startId);
}
public class GetSMSThread extends TimerTask {
private Context mContext;
public GetSMSThread(Context context) {
mContext = context;
}
#Override
public void run() {
this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplication() , "Service is Running ... " , Toast.LENGTH_SHORT).show();
}
});
}
}
}
Try creating a Handler in onStartCommand (so, from the UI thread). Then use that Handler to trigger the Toast. For example:
private Handler mToastHandler = null;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
mToastHandler = new Handler();
...
}
...
// from inside your child thread
mToastHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(...);
}
});
Here you can use ResultReceiver that is used for the purpose of receiving a callback result from someone. In your case its Service
You can check the complete example of Service with TimerTask using ResultReceiver for updating the UI inside Activity

How to stop a service after it has finished its job?

I have a service which I start from my Activity.
Now the serivce performs some task by starting a new thread from onStartCommand()
I want to stop the service after the thread has finished its job.
I tried using a Handler like this
public class MainService extends Service{
private Timer myTimer;
private MyHandler mHandler;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mHandler = new MyHandler();
myTimer = new Timer();
myTimer.schedule(new MyTask(), 120000);
return 0;
}
private class MyTask extends TimerTask{
#Override
public void run() {
Intent intent = new Intent(MainService.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
mHandler.sendEmptyMessage(0);
}
}
private static class MyHandler extends Handler{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("", "INSIDE handleMEssage");
//stopSelf();
}
}
First it was giving me a warning that if handler class is not static it will cause leaks
After I made it static, stopSelf() can not be called, because its non static.
Is my approach correct or is there a simpler way around ?
you should use IntentService rather service. It starts automatically in separate thread and stop itself as task completes.
public class MyService extends IntentService {
public MyService(String name) {
super("");
}
#Override
protected void onHandleIntent(Intent arg0) {
// write your task here no need to create separate thread. And no need to stop.
}
}
Use IntentService its base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
try this,
private static class MyHandler extends Handler{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("", "INSIDE handleMEssage");
MainService.this.stopSelf();;
}
}

Android - how to run a task via "handler" periodically within a service-intent (worker-thread)

My question is Android related:
How do I run a task every 20 seconds within an intentservice ?
Problem is, I have to init some classes which will be used in the Handler "run" process.
It works one time - but then the service stops & the application crashes when the handler-loop starts again after 20 seconds (probably because of the classes that got eliminated when the service stopped?). So maybe the solution is to get the service to stay running as long as the Handler runs or to throw away the code and do it right ?
Hope, someone can help me.
public class Fadenzieher extends IntentService{
private Handler handler = new Handler();
private Runnable timedTask = new Runnable(){
#Override
public void run() {
// My functions get called here...
// class1member.getDBWorkdone();
handler.postDelayed(timedTask, 20000);
handler.obtainMessage();
}};
public Fadenzieher() {
super("Fadenzieher");
}
#Override
protected void onHandleIntent(Intent intent) {
// SOME INITIALISING
// I have to init some vars & functions here that
// will also be used inside the handler loop
// Class1 class1member = new Class1();
// class1member.startUpDB();
handler.post(timedTask); }
Thank you very much in advance!!!
---- So this is the updated code now (14. nov. 2011)
public class Fadenzieher extends Service{
private static final long UPDATE_INTERVAL = 60000;
Context context = this;
private Timer timer = new Timer();
DbHelper dbHelper;
public void onCreate(){
dbHelper = new DbHelper(context);
runTheLoop();
}
protected void runTheLoop() {
timer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run() {
dbHelper.dosomethings();
Toast.makeText(context, "CALL", Toast.LENGTH_LONG).show();
}}, 0, UPDATE_INTERVAL);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Starte Service“, Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
}
public void onDestroy() {
super.onDestroy();
dbHelper.close();
Toast.makeText(this, "Stoppe Service“, Toast.LENGTH_LONG).show();
}
// We return the binder class upon a call of bindService
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
public class MyBinder extends Binder {
Fadenzieher getService() {
return Fadenzieher.this;
}
}
}
The whole application crashes immediately.
How do I run a task every 20 seconds within an intentservice ?
That is not an appropriate use of IntentService. Use a regular Service, please.
It works one time - but then the service stops & the application crashes when the handler-loop starts again after 20 seconds
IntentService shuts down when onHandleIntent() returns, which is why this is breaking for you. Use a regular Service, please.
Also:
Please allow the user to configure the polling period
Make sure that this service will shut down when the user no longer wants it to be running

Categories

Resources