Service is stopped when executed on BOOT_COMPLETED

0

Personal was doing an example for an application service to be started at boot, it seems to start but if it stops in a few seconds and I can not understand why, I'm following an example from a book, and found the same thing in many examples almost the same. Some hint because I can not understand why the service is interrupted.

public class NotificacaoTask extends TimerTask {

    private static int i = 0;

    @Override
    public void run() {
        Log.i("servico" ,"Incremento: "+ i++);

    }
 }
public class Servico extends Service {

 public static final String CATEGORIA = "servico";
 public Timer timer;

@Override

 public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i("servico","O servico foi iniciado!!!!");
    timer = new Timer();
    long delayInicial = 1 * 1000; //segundos
    long periodo = (long) 1 * 1000;

    timer.scheduleAtFixedRate(new NotificacaoTask() ,  delayInicial, periodo );
    return START_STICKY;
 }


public void onDestroy(){
    Log.i("servico" , "servico destruido");
    timer.cancel();
    super.onDestroy();
}


@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

}
public class BootReciever extends BroadcastReceiver {

public static Intent service;

@Override
public void onReceive(Context context, Intent intent) {
    service = new Intent("INICIAR_SERVICO");

    context.startService( service );

    Log.i("servico","iniciou serviço boot");

}
}

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="18" />


<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>


<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.serviceboot.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>


    <service android:name="Servico">
     <intent-filter>
     <action android:name="INICIAR_SERVICO" />
     <category android:name="android.intent.category.DEFAULT" />
     </intent-filter>
    </service>

    <receiver android:name="BootReciever">
        <intent-filter >
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>

</application>

logcat output

04-08 18:37:47.036: I/servico(704): iniciou serviço boot
04-08 18:37:47.057: I/servico(704): O servico foi iniciado!!!!
04-08 18:37:48.077: I/servico(704): Incremento: 0
04-08 18:37:49.186: I/servico(704): Incremento: 1
04-08 18:37:50.166: I/servico(704): Incremento: 2
04-08 18:37:51.077: I/servico(704): Incremento: 3
04-08 18:37:52.077: I/servico(704): Incremento: 4
04-08 18:37:53.077: I/servico(704): Incremento: 5
04-08 18:37:54.085: I/servico(704): Incremento: 6
    
asked by anonymous 09.04.2014 / 01:06

1 answer

0

What I think is happening is: your service creates an instance (object) of Timer called timer , however this instance will only last while the Service is running, after that there will be no one else referencing this instance and it will be deleted by the garbage collector . And in fact, its Service runs after boot and then ends (there is no reason why it should not finish because there is no loop in it or any other longer execution command - do not think that timer.scheduleAtFixedRate() is waiting for the tasks to run), and when the service ends, the Timer instance is garbage-collected shortly afterwards.

(Note that even if this does not happen, the timer.cancel(); line in the onDestroy() method will cause timer to be canceled and tasks stop executing the same way.)

The solution in this case would be to store the reference to Timer in a variable of longer duration, such as a static variable.

However, the right way to do it, if you want to schedule your device to perform a task from time to time, is to not use TimerTask , but to do onReceive() method of your broadcast receiver schedule periodic execution of a service through the AlarmManager (you use this class to I would like to schedule a service execution in a similar way as you have programmed the TimerTask execution. But I am not being precise: what actually happens is that AlarmManager will call another broadcast receiver that this sim will call the service you want to run). Reading so looks complicated, but it's simple - have a link below with an example. By doing so, it is the "Android" way of doing, after the boot the device will run the desired service from time to time.

Tip: Scheduling the service in this way will probably want to define your service as a subclass of IntentService and overwrite your method onHandleIntent () , which performs tasks on a secondary thread . This is because the basic class Service executes on the main thread of the thread ), which should not be overloaded with time-consuming tasks because is responsible for updating the screen.

Useful links:

09.04.2014 / 01:40