Four major components of Android---Service

As one of the four major components of Android, Service has an extraordinary function, mainly to perform some background tasks. Some long-running tasks, and even tasks that need to be executed after the app exits, are inseparable from Service. This section will review this important component.

Knowledge points

Insert picture description here

1. Introduction

1. Concept

A service is an application component, one of the four major components of Android, which means that the application wants to perform a long-running operation without interacting with the user, or to provide functions for other applications. Unlike Activity, Service is a control that can run in the background for a long time without an interface. Used to perform some long-term time-consuming tasks (Is it reminded of Thread to leave a hole first).

2. Notice

1. Service is not a separate process. The Service object itself does not mean that it runs in its own process; unless otherwise specified, it will run in the same process as the application it belongs to. The default is the main process.
2. The service is not a thread. It itself runs in the main thread by default.

2. Life cycle preview and simple creation

1. Life cycle preview

Insert picture description here

Like activity, service also has its own life cycle, we can briefly understand it first.
Left: start mode
Right: bind mode

2. Service creation

(1) The compiler quickly creates

Like activity, the compiler provides a quick way to create. On the corresponding package: new-service. After that, the compiler will automatically register the service for us in the clear manifest file, without us having to register manually.

(2) Manually create

1. Create a class to inherit Service
2. Register under the manifest file.
In general, the creation method is similar to activity, because it is also the four major components, so there are still many similarities.

Three, the simple use of the opening method

1. StartService method

This way of starting is relatively simple, we can also see the life cycle process through the above cycle diagram:
onCreate --> onStartCommand --> onDestory

(1) Simple practice

-------------------------MyService.java---------------------------

public class MyService extends Service {
    
    
    private static final String TAG = "23333";

    @Override
    public void onCreate() {
    
    
        super.onCreate();
        Log.i(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        Log.i(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
    
    
        Log.i(TAG, "onDestroy: ");
        super.onDestroy();
    }


     // bind服务时用的方法
    @Override
    public IBinder onBind(Intent intent) {
    
    
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

-------------- MainActivity.java ----------------------------------

    private Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this, MyService.class);
    }

    public void startService(View view) {
    
    
        startService(intent);
    }
    public void stopService(View view) {
    
    
        stopService(intent);
    }

Insert picture description here
Insert picture description here

Click startService twice and stopService once. The result is as shown in the figure above:
1. The onCreate method is the same as the activity's onCreate method, and the entire life cycle will only be executed once, indicating that the service has started to be created.
2. onStartCommand means to start the service,This method is triggered every time you call the startService(intent) method
3. onDestroy means service destruction. We must have guessed the life cycle of this method and execute it once. Triggered when you call stopService(intent). Or we trigger when we call stopSelf() in MyService.java.

(2) Start the service characteristics

1. There is almost no connection between the service and the component that started the service. We just start it when appropriate, and then we stop it after the task is completed.
2. The service started in start mode will always run in the background (activity destruction will not affect the operation of the Service, as long as the app is not destroyed. More precisely, the process where the service is located is not killed.) Unless we manually StopService, or the system memory is insufficient to kill the process where the Service is located.

(3) The return value of the onStartCommand method

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        Log.i(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

1. This method is called by the system. This method is called back by the system every time the client starts the service through startService. We do not call this method directly.
2. Common return values:

  • public static final int START_STICKY_COMPATIBILITY = 0:
    The compatibility version of the return value of START_STICKY, but there is no guarantee that the service will be opened again when the service is killed.
  • public static final int START_STICKY = 1: The
    system process where the service is located is killed after the onStartCommand method is executed (the return value is START_STICKY). systemmeetingRestart the service. But the system will not use the intent you opened the service last time, but will use aEmpty intent objectTurn on the service. This mode is applicable to scenarios where the user decides to turn on and turn off for any period of time. For example, playing music in the background.
  • public static final int START_NOT_STICKY = 2: The
    system process where the service is located is killed after the onStartCommand method is executed (the return value is START_NOT_STICKY). systemwill notRestart the service. Unless the user calls startService again to start.
  • public static final int START_REDELIVER_INTENT = 3: The
    system process where the service is located is killed after the onStartCommand method is executed (the return value is START_REDELIVER_INTENT). systemmeetingRestart the service.And use the most recentOpen serviceintentObject. This applies to services that actively perform operations that should be resumed immediately. For example, download files.
2. BindService mode

By summarizing the startService method, we know that there is almost no connection between Activity and Service in this way. When information exchange between Activity and Service is needed, it is closer to the actual situation. When weWant to be in ActivityinMethod of calling ServiceWhat should I do at the time? At this time, the bindService method is needed. . .

(1) Bind method


public interface MusicManager {
    
    
    void playMusic();

    void pauseMusic();

    void stopMusic();
}
public class MusicService extends Service {
    
    
    private static final String TAG = MusicService.class.getSimpleName();

    public MusicService() {
    
    
        Log.i(TAG, "MusicService:");
    }

    @Override
    public void onCreate() {
    
    
        super.onCreate();
        Log.i(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        Log.i(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
    
    
        Log.i(TAG, "onUnbind: ");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
    
    
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
    }

    @Override
    public IBinder onBind(Intent intent) {
    
    
        Log.i(TAG, "onBind: ");
        return new MyBind();
    }

    private class MyBind extends Binder implements MusicManager {
    
    

        @Override
        public void playMusic() {
    
    
            Log.i(TAG, "playMusic: ");
        }

        @Override
        public void pauseMusic() {
    
    
            Log.i(TAG, "pauseMusic: ");
        }

        @Override
        public void stopMusic() {
    
    
            Log.i(TAG, "stopMusic: ");
        }
    }
}

public class MainActivity extends AppCompatActivity {
    
    
    private MusicManager musicManager;
    private ServiceConnection conn;
    private Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = new Intent(this, MusicService.class);
        conn = new MyServiceConnection();
    }

    public void bindService(View view) {
    
    
        bindService(intent, conn, BIND_AUTO_CREATE);
    }

    public void unBindService(View view) {
    
    
        unbindService(conn);
    }

    public void playMusic(View view) {
    
    
        if (null != musicManager){
    
    
            musicManager.playMusic();
        }
    }

    public void pauseMusic(View view) {
    
    
        if (null != musicManager){
    
    
            musicManager.pauseMusic();
        }
    }

    public void stopMusic(View view) {
    
    
        if (null != musicManager){
    
    
            musicManager.stopMusic();
        }
    }

    private class MyServiceConnection implements ServiceConnection {
    
    
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    
    
            musicManager = (MusicManager) iBinder;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
    
    

        }
    }
}

Insert picture description here
(2) Introduction of parameters

public boolean bindService(Intent service, ServiceConnection conn, int flags):
1, intent object
2, ServiceConnection interface implementation class object, just implement the interface write callback method.
3. Flag. In fact, we generally use BIND_AUTO_CREATE as flag, which means that it is created when the Service does not exist.
ps: The start of the service is asynchronous, as above, if we directly obtain the IBinder object through the callback in onCreate, directly operate the play, pause, and stop methods, it may report a null pointer.

(3) Operation

1. After clicking the button to bind the service, the callback method is as follows:
2.once againClick onBindno effect

Insert picture description here

1. The effect of clicking the unbinding button is as follows:
2. Clicking unbinding again, the activity crashes directly and can only be unbound once.

Insert picture description here
(3) The characteristics of starting the service in bindService mode:

1. The onBinder method of the service must have a return value object, otherwise the onServiceConnected callback method will not be executed.
2. When the binding button is clicked for the second time, the bound service is unresponsive and can only be bound once.
3. When the Activity is destroyed, unbind the service in ondestory(), otherwise destroy the Activity to automatically unbind (do not live but die at the same time)
4. If the service is unbound multiple times, an exception will be reported. Binding
5. The services opened through the bind method cannot be seen in the running services of the developer option.

3. Hybrid start

Requirements: I want the service to run in the background for a long time and also want to operate the internal method of the service. Solution: Start the service in a mixed way (both methods of opening the service need to be called)
The idea of
starting the service: 1. First call the startService method to start the service ( Ensure that the service runs in the background for a long time)
2. Call bindService to bind the service. When
closing:
1. Call unbindService first (the service will not be unbound at this time)
2. Call stopService to unbind service
ps:
1. Common music players often use this In this way, in order to keep alive, sometimes the service becomes a foreground process.
2. When the onCreate method is opened in this way, it will be executed only once, and the onStartCommand will be executed as many times as startService is called.

Fourth, the difference between Service and Thread

1. Conceptual differences
  • Thread is the smallest unit of program execution. It is the basic unit for allocating CPU. The UI thread in the android system is also a kind of thread. Of course, Thread can also be used to perform some time-consuming asynchronous operations.

  • Service is a mechanism of Android, the service is running on the main thread, it is managed by the system process. The communication between it and other components is similar to client and server. It is a lightweight IPC communication. The carrier of this communication is binder. It is an IPC that exchanges information at the Linux layer, and the so-called Service background task It just refers to components without UI.

2. Differences in execution tasks
  • In the android system, the thread generally refers to the worker thread (ie, background thread), and the main thread is a special kind of worker thread, which is responsible for dispatching events to the corresponding user interface gadgets, such as drawing events and event responses, so In order to ensure the responsiveness of the application UI, time-consuming operations cannot be performed on the main thread. If the performed operations cannot be completed quickly, you should ensure that they are performed in a separate worker thread.

  • Service is a component in the android system. Under normal circumstances, it runs in the main thread. Therefore, time-consuming operations cannot be performed in the Service. Otherwise, the system will report an ANR exception. The reason why Service is called a background service is mostly due to It does not have a UI, and the user cannot perceive it (of course, you can also use some means to let the user know), but if you need the Service to perform time-consuming tasks, you can open a separate thread in the Service to execute

3. Differences in usage scenarios
  • When you want to perform time-consuming network or database queries and other tasks that block the UI thread or intensively use the CPU, you should use a worker thread (Thread) to ensure that the UI thread is not occupied and affect the user experience.

  • In the application, if you need to run in the background for a long time, and no interaction, use the service. For example, to play music, it is executed in the background through Service+Notification, and it is displayed in the notification bar.

Five, Service family

1 、 IntentService
2 、 JobService

6. Front desk service

1. Make the service the foreground

Just open a notification bar in the service, the points of attention are as follows:
1. Add the FORREGROUND_SERVICE permission.
2. In the onStartCommand, startForeground must be called to construct a notification bar, otherwise ANR
3. The foreground service can only be startService, not bindService

//MyService.java
 public void onCreate() {
    
    
        super.onCreate();
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // 通知渠道的id
        String id = "my_channel_01";
        
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel mChannel = new NotificationChannel(id, "我是渠道", importance);
        mNotificationManager.createNotificationChannel(mChannel);

       
        String CHANNEL_ID = "my_channel_01"; //渠道id
        Notification notification = new Notification.Builder(this, CHANNEL_ID)
                .setContentTitle("我是标题").setContentText("我是内容")
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .build();
        startForeground(1, notification);

        Log.i(TAG, "onCreate: ");
    }
2. Front desk service without Notification

1. Implementation principle:

a. Two front desk services, A, B
, and A are required to be turned on, and then a notification bar is turned on in the A service.
C and B are turned on, and the notification bar is turned on in the B service, and then the B service is turned off immediately.
ps: Two services share a Notification ID

2. Description: This vulnerability has been fixed by Google in android7.1.

Seven, remote service IPC

Service not only inSame processTo exchange information betweenDifferent processesIPC during the period. The typical use of ipc using services is aidl. In fact, there are many ways to use IPC. Right hereCombine service relatedIntroduce a typical way:
Android IPC-AIDl use detailed explanation

8. In-depth Service—Service startup process

This involves the analysis of the system source code, and I will summarize it when I have the ability in the future. . .

summary

The knowledge points of "reviewing the past and knowing the new" all produce new gains in retrospect, so I will briefly summarize. Service as one of the four major components is still very important, I believe that in the future use will gradually deepen the understanding.

end

Guess you like

Origin blog.csdn.net/qq_38350635/article/details/99292611