Android Service foreground service startforegroup

Posted by gazever on Sat, 15 Jan 2022 21:26:30 +0100

preface

I wrote a script to execute automatic clock in, and the effect is good
I also learned some knowledge points about android system

The foreground service is used to eliminate the possibility of being killed by using the player mode
Increase Service priority

How to keep the Service alive

1. Improve Service priority:

To prevent the Service from being recycled by the system, you can try to solve the problem by increasing the Service priority,
1000 is the highest priority. The smaller the number, the lower the priority
android:priority="1000"

2. Write service as system service

At manifest If the persistent attribute is set to true in the XML file, the service can be protected from the out of memory killer.
However, this approach must be cautious. Too many system services will seriously affect the overall operation efficiency of the system.

3. Change the service to foreground service:

Override the onStartCommand method and use the startforegroup (int, notification) method to start the service.
Note: generally, the front desk service will display a notice in the status bar. The most typical application is the music player. As long as it is playing,
Even if you sleep, you won't be killed. If you don't want to display the notification, just set int in the parameter to 0.
Meanwhile, for the service started through startforegroup,
The onDestory method needs to cancel the foreground running state through stopforegroup (true).

4. Broadcast using Android system

Check the running status of the Service by using the system broadcast of ANDROID. If it is killed, it will get up again. The system broadcast is intent ACTION_ TIME_ Tick, this broadcast is sent every minute. We can check the running status of the Service every minute. If it has been finished, restart the Service.

Analyze why background services are recycled?

When the background service is recycled and we check the logs in Logcat, we may see the following logs

Killing ProcessRecord{43a96570 6437:com.example.helloandroid/u0a187}: background ANR 
Process com.example.helloandroid (pid 6437) (adj 0) has died. 

Look at the log to explain that it is caused by ANR. How to avoid anr?

1. The main thread ("event processing thread" / "UI thread") does not respond to the input event within 5 seconds
2. The broadcastreceiver did not complete the return within 10 seconds
3. Network operation in the main thread
4. Perform some slow disk operations (I/O operations or database operations) in the main thread
As for how to avoid the occurrence of ANR, you should try to avoid the above situations, and you can basically avoid most ANRS.

Foreground Service

Foreground services are those services that are considered to be known by the user (recognized by the user) and are not allowed to be killed by the system when the system memory is insufficient. The foreground service must provide a notification to the status bar, which is placed under the heading "going" - which means that the notification can only be released after the service is terminated or the notification is actively removed from the foreground.

The Service works hard in the background almost all the time. However, in this case, the system priority of the Service running in the background is relatively low. When the system memory is insufficient, the Service running in the background may be recycled.
Then, if we want the Service to keep running and not be recycled in case of insufficient memory, we can choose to set the Service to keep running as the foreground Service.

Follow the idea of making a music player and explain how to use the front desk service

public class MusicPlayerService extends Service {
  
  private static final String TAG = MusicPlayerService.class.getSimpleName();
  
  @Override
  public void onCreate() {
      super.onCreate();
      Log.d(TAG, "onCreate()");
  }
  
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "onStartCommand()");
  }
  
  @Override
  public IBinder onBind(Intent intent) {
       Log.d(TAG, "onBind()");
       // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
  }
}

Then create a Notification:

Add the following code in onStartCommand of Service:

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "-------------onStartCommand");
        Context context = this;
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        builder.setSmallIcon(R.mipmap.timer_task);
        builder.setContentTitle("New news").setContentText("This is a scheduled task");
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.timer_task));
        // 8.0 setting the Notification Channel_ID, otherwise it cannot be displayed normally
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId("notification_id");
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
            assert notificationManager != null;
            notificationManager.createNotificationChannel(channel);
        }
        //The purpose of enabling the foreground Service is to keep alive and improve the priority of the Service
        startForeground(0, builder.build());
    }

After building the Notification notification message,
In the onStartCommand of the Service, you can use the startforegroup method to make the Android Service run in the foreground.

If you need to stop the foreground service, you can use stopForeground to stop the running foreground service.

 @Override
    public void onDestroy() {  
    	//Out of Service
        stopForeground(true);
        super.onDestroy();
        Log.e(TAG, "-------------onDestroy");
    }

summary

What is the difference between front desk service and general service?

1. The foreground Service has higher system priority and is not easy to be recycled;
2. The foreground Service will always have a running icon displayed in the status bar of the system. After pulling down the status bar, you can see more detailed information, which is very similar to the effect of notification.

Topics: Android service