Always runs service in background on Android? - android

I am building an app which has a background service for continuously communicating with a Raspberry Pi.
I am making the service sticky(Service.START_STICKY) so that is will restart when it's killed by user or OS.
This works well for the first 30-40 minuten. After 30-40 minutes the services seems to be stopped.
Isn't there any way to avoid this problem? I know it's bad for the batterylife if there is service continiously runnnig in the background. The app is used in my own project to automate my room and is only used by me. So the batterylife isn't a problem.
public class RaspberryPiCommunication extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Do continuouswork here in a seperate thread
return Service.START_STICKY;
}
}
I also have another quetions about service:
If the service is started twice in the following example, will there be two instances of SomeObject() and is doSomWork() running twice in background?
public class RaspberryPiCommunication extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SomeObject obj = new SomeObject();
obj.doSomeWork();
return Service.START_STICKY;
}
}

Are you running the service on its own thread ? By default, A service runs on the main thread. For a long running task like this run it in a separate thread
Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work.
Service will run only in one Instance. onStartCommand() is called every time you start the service.
http://developer.android.com/guide/components/services.html#StartingAService

Here is required piece of code.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
handler.postDelayed(runnable, 1000 );// 1000 - Milliseconds
if (appContext == null) {
appContext = getBaseContext();
}
Toast.makeText(appContext, "Services Started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
Runnable runnable = new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
DoBackgroundTasks();
handler.postDelayed(this, 1000 ); // 1000 - Milliseconds
}
};
void DoBackgroundTasks()
{
//write code here.
}

In your manifest where you have declared your service, add this
android:process="remote"

Related

Best approach to execute service in Android

I have a service that have an variable life time. It may execute from 5 minutes to 2 hours (for example). So I'm looking for the best approach to do that, and my service must achieve the following features:
Send (to my server) lat-long every 5 seconds and some extra information (string's, boolean's and int's)
I have tried a "normal" service and tried to do something like this to achieve this:
public class MyFiveSecondsService extends Service {
private Handler handler;
Runnable r = new Runnable() {
#Override
public void run() {
//here send my new data
}
};
public void onCreate(){
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(handler == null){
handler = new Handler();
}
handler.post(r);
return super.onStartCommand(intent, flags, startId);
}
}
Actually that code works, but I got some performance problems with that approach, so I tried to do something like this:
public class SendUniquePositionIntentService extends IntentService {
public SendUniquePositionIntentService() {
super("co.bomboapp.Service.IntentService.SendUniquePositionIntentService");
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
protected void onHandleIntent(Intent intent) {
//do the logic here
}
}
public class MyFiveSecondsService extends Service {
private Handler handler;
Runnable r = new Runnable() {
#Override
public void run() {
//call my SendUniquePositionIntentService here
}
};
public void onCreate(){
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(handler == null){
handler = new Handler();
}
handler.post(r);
return super.onStartCommand(intent, flags, startId);
}
}
And that approach haven't worked, when I had closed the app any service kept running. So before start any other attempt to achieve this, I want some direction, what's the best approach to do this "infinite loop service" and keep the performance?
I'm using Android 4.1 as min API, and targeting 5.0 API.
My test device is a Nexus 5 running Android 6.
Right now I'm using parse.com as database.
"I have tried a "normal" service...but I got some performance problems"
By default, a service runs on the application's main thread, so when you create a handler with
public int onStartCommand(Intent intent, int flags, int startId) {
if(handler == null){
handler = new Handler();
}
...
}
the handler is associated with the main thread's Looper and all messages and runnables are delivered and later executed on the thread. That's the reason of the "performance problems". From the documentation:
Remember that if you do use a service, it still runs in your application's main thread by default...
Regarding the second approach and the part
"...when I had closed the app any service kept running"
you haven't mentioned how exactly you "close" the app, but what I can see is
public int onStartCommand(Intent intent, int flags, int startId) {
...
return super.onStartCommand(intent, flags, startId);
}
which means that if the system kills the service it, by default, will be recreated. So if "closing" your app means killing it, the following chain of actions takes place:
The system recreates MyFiveSecondsService,
onStartCommand() is called and the handler posts the runnable
within the run() method SendUniquePositionIntentService is started
From the documentation of onStartCommand():
the default implementation calls onStart(Intent, int) and returns either START_STICKY or START_STICKY_COMPATIBILITY.
Note that starting a service from another one (like starting SendUniquePositionIntentService from MyFiveSecondsService in your case) is redundant unless you intended to.
The final part of your question is confusing to me. On one hand it doesn't work for you because "...any service kept running" but, on the other hand, you'd like "do this "infinite loop service""...?
If you only need to send such information as "strings, booleans and ints" to a server (without any feedback to the component that started the service), I suppose it's simply enough for you to use IntentService. This is a "out-of-box" framework that does its work on a background thread (letting you avoid freezing the main thread) and stops itself once it's done. As an example you can use the documentation on IntentService - it's well written.
Also note that the behaviour of a service after killing it by the system depends on the flag returned by onStartCommand(). E.g. use START_NOT_STICKY to not recreate the service after killing the app or START_REDELIVER_INTENT to recreate it with the last Intent redelivered.

Stop the Service after the Vibrating the Phone in android?

I am trying to learn service in android.My goal is like that i will pass a LatLng Object to the service then service will do something with that and when the work will be finished then it will buzz the phone for sometime and stop.Finally the service will be finished.Now I have some query on that:
I will call the service from my app and user can close my app though
service is not finished.will service do the job initiated by my app or
it will also finish??
What i studied take me here that service will continue to execute and one thing i don't have to return anything back to activity who has initiated the service.I have written some code.Can anyone help me out??
public class MapService extends Service {
private boolean isRunning = false;
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
isRunning = true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
//Creating new thread for my service
//Always write your long running tasks in a separate thread, to avoid ANR
new Thread(new Runnable() {
#Override
public void run() {
//here i will do my work
if(isRunning){
Log.i(TAG, "Service running");
}
}
//Stop service once it finishes its task
stopSelf();
}
}).start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
}
Will it work if user closes the app??
Yes this service will run even if user will close app.It is also possible if android system demands memory service will be stopped but it will restart again
as you have set your flag START_STICKY in your onStartCommand.
On Android KitKat and above(4.4+), the service will be stopped if user swipe kills the application and it won't be restarted by the system. See this discussion(1). If the application was stopped by Android system itself (for low resources), the service will be restarted after a while(use START_STICKY flag).
On Android 4.3 and below, service will be restarted irrespective of whether application was stopped by system or user(use START_STICKY flag).
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}

Start service once and forever untill it gets killed

A simple question, how to make a Service repeat at log cat console msg "hello", as long as the Service is living/is active? I've tried:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v("LocalService", "Received start id " + startId + ": " + intent);
Mano lopas = new Mano(this);
lopas.Lopas();
while(true) {
Log.v("HAHA", "hello");
}
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
But it never returns START_STICKY, actually it doesnt even build the project. I think im missing something about services? I start my service, in MainActivity in my application, like:
startService(new Intent(getApplicationContext(),Myclass.class));
And it runs only once without my while loop in my service. It says me something in Logcat and this is it. Morever, my service starts so many times as many times I re-open my application. How to make service start run once and "forever", I mean untill it gets killed by the system or user kills it.
Services don't have their own thread, they run on the UI thread. If you want it to run in parallel, you need to create a Thread. So here you should create a Thread in your onStartCommand, and that thread should do whatever it is you want.
Same way you'd log something at intervals in your activity: use a Handler. Post a task that logs a message and re-posts itself to the same Handler using postDelayed(...). Cancel any pending execution in your activity's onPause() or your service's onDestroy().
Note that there is almost never a good reason to explicitly create a Thread or use J2SE constructs like TimerTask in Android. For heavyweight tasks, use AsyncTask. For lightweight tasks, use Handlers. In your case, creating a new Thread would be a ridiculously heavyweight solution for what you want to do.
First of all, do not forget to register the Service in your Manifest.
This can be done by using
<service android:enabled="true" android:name=".services.Paycan" />
Next is, that your Service (if its not an intentservice) run in the MainUI. If you create an endless loop make sure it's in a background thread, otherwise it will freeze the app.
You can do it using an Asynctask, a Thread which get created with onStartCommand and stopped in onDestroy or use an IntentService instead of a Service.
example:
public class yourTestClass extends Service {
Thread testThread;
boolean threadRunning = false;
#Override
public void onCreate() {
super.onCreate();
testThread = new Thread() {
#Override
public void run() {
try {
while(threadRunning) {
Thread.sleep(1000);
Log.i("test", "....");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
threadRunning = true;
testThread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
threadRunning = false;
}

Process and threads in android

Can service and activity run in same linux process at the same time.?
private class Test extends Service{
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
#Override
public void run() {
// Computational logic
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Does the the thread execute in new linux process or the same process which call this service(UI process)?.
By default every application runs in its own process and all components of the application run in that process.
Can service and activity run in same linux process at the same time.?
The above statement already answer this question, and here's what Services docs one more time says:
The Service object itself does not imply it is running in its own
process; unless otherwise specified, it runs in the same process as
the application it is part of.
For further reading consider this link: http://developer.android.com/guide/components/processes-and-threads.html
From the documentation: http://developer.android.com/reference/android/app/Service.html
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
Unless you mention in manifest, the service will run in the same thread: See here: http://developer.android.com/guide/topics/manifest/service-element.html

Android service keeps running indefinitely

I'm trying to create a service in android which i want to keep running in background indefinitely. So I tried to create one like :
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, mssg, Toast.LENGTH_SHORT).show();
}
public int onStartCommand(Intent intent, int flags,int startid) {
Toast.makeText(this, mssg, Toast.LENGTH_LONG).show();
Log.d("Start:", "Service running");
// my code here
return START_STICKY;
}
But when I run this code, the toast messages and logs are only shown once , so does it mean service runs only first time. If it is running again n again which API of it is being called repeatedly ?
Thanks,
shadow.
Running a Service indefinitely and running the same piece of code again and again are two very different things. The piece of code you provided will allow the service to be running the background as long as the Android system doesn't decide to stop it.
Not sure what functionality you are looking to implement, but i suggest you read up on what exactly a Service is used for and what your requirements are.
i suggest you change return START_STICKY;
with return START_NOT_STICKY;
as details given in documentation here.

Categories

Resources