Service is one of the four components of Android, which is often used in our daily development, such as performing some background operations, playing music, downloading and so on.

Let’s start with a simple Service usage and walk through Service step by step

Service simple use

Create an Activity and set two buttons in the Activity to start and close the Service. The Service simply prints logs of its life cycle and does nothing.

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private final static String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button startService = findViewById(R.id.btn_start_service);
        Button stopService = findViewById(R.id.btn_stop_service);
        
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, MyService.class);
        switch (v.getId()) {
            case R.id.btn_start_service:
                startService(intent);
                break;
            case R.id.btn_stop_service:
                stopService(intent);
                break;
            default:
                // fall through}}}Copy the code

activity_main


      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_start_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Service on"/>

    <Button
        android:id="@+id/btn_stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Service shutdown"/>

</LinearLayout>
Copy the code

MyService

public class MyService extends Service {

    private final static String TAG = MyService.class.getSimpleName();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onCreate(a) {
        Log.e(TAG, "service onCreate");
        super.onCreate();
    }

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

    @Override
    public void onDestroy(a) {
        Log.e(TAG, "service onDestroy");
        super.onDestroy(); }}Copy the code

Finally, don’t forget to register the Service in AndroidManifest

Use a Service step

  • Create a class that inherits Service
  • Register the Service in AndroidMainfest
  • Used in an ActivitystartServiceStart the Service

Note that I’m using a display to launch a Service. To implicitly launch a Service, specify the package name and action in the Intent

intent = new Intent();
intent.setAction("com.sui.SERVICE");
intent.setPackage("com.sui.testapplication");
startService(intent);
Copy the code

Starting a Service using an action is not allowed since Android 5, Android Lollipop

At this point, we can open the Service by clicking the start Service button and see the printed log.

If you want to stop a Service, you can pass in an Intent with stopService(). Note that the Intent that starts and ends a Service must be the same Intent

The Service binding

The above method of starting the Service has nothing to do with the Activity that calls startService. Using startService simply tells the Service that you are ready to start. If you want to associate an Activity with a Service, use context. bindService(Intent Intent, ServiceConnection conn, int flags).

  • The first parameter is the incoming Intent
  • The second parameter is the connect state callback
  • The third parameter is the binding relationship

Using bindService

 bindService(intent, serviceConnection, BIND_AUTO_CREATE);
Copy the code

The intent is the same as above, except that we need to define a second parameter

ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {}@Override
    public void onServiceDisconnected(ComponentName name) {}};Copy the code

You implement an anonymous inner class with two essential functions that must be implemented, onServiceConnected and onServiceDisconnected

  • onServiceConnectedRepresents the callback function when the Activity successfully binds to the Service
  • onServiceDisconnectedRepresents the callback function when the Activity is disconnected from the Service

The onServiceConnected method has a very important parameter called IBinder Service. This parameter is the data returned by the service if the binding is successful. Remember the method we had to override in the service

public IBinder onBind(Intent intent) {
        return null;
}
Copy the code

The IBinder service parameter accepts the return information from onBind

If you want to return messages, you need to create a class that inherits from Binder

// Service file
public static class MyBinder {
    int addPlus(int x, int y) {
        returnx + y; }}public IBinder onBind(Intent intent) {
        return new MyBinder();
}

// In the Activity file
ServiceConnection serviceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
		MyService.MyBinder binder = (MyService.MuBinder)service;
        
         int res = binder.addPlus(1.1);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {}};Copy the code

Once the connection is successful, you execute the addPlus method in your onServiceConnected block of serviceConnection

Here are a few things to note: If the onBind method in the Service does not return any information, that is, null, then the callback methods onServiceConnected and onServiceDisconnected will not execute, even if the Service and Activity are successfully bound

The third argument flags, which has a special value, context.bind_auto_create. The special thing about this value is that when we bind to a Service, if the Service is not already started, bindService will start the Service. Note that all of the new life cycle functions of the Service will be executed

To unbind the service, simply use unbindService and pass in the ServiceConnectiong as defined by bindService

The Service life cycle

The life cycle of a Service includes onCreate, onStartCommand, and onDestroy

When we start the Service for the first time, we will execute onCreate -> onStartCommand

While we are executing startService all the time, onCreate will only execute once, whereas onStartCommand will execute every time.

When using bindService, neither onCreate nor onStartCommand will be executed (if BIND_AUTO_CREATE is specified and no Service is created).

Finally, when we use stopService, we execute the onDestroy method

If we use bindService to bind to Service after enabling Service, and then stopService, we can see that onDestroy does not execute. The Service will not be destroyed using stopService until all bindings for the current Service are unbound (all bindings perform unbindService)

Across processes Service

A Service can be placed in a separate process by specifying Android: Process in the AndroidMainfest file

<application>.<service android:process=":remote" android:name=".MyService" />.</application>
Copy the code

You can start another process’s Service in another process’s Activity, or use startService. You can stop another process’s Service using stopService.

If you use bindService to bind the Service of another process, this involves waking up the Service. You need to implicitly start the Service to show that the launch cannot get the bytecode information of the class (and therefore cannot pass in the Intent).

intent = new Intent();
intent.setAction("com.sui.SERVICE");
intent.setPackage("com.sui.testapplication");
bindService(intent, connect, BIND_AUTO_CREATE);
Copy the code

If you want to communicate with binder at this point, you can use Android’s cross-process aiDL and create an AIDL file

package com.sui.mutiprocessapplication;
interface IMyService {
    int addPlus(int x, int y);
}
Copy the code

There are several points to note:

  • Do not add public before interface
  • Do not precede the return value of a function with an access restriction modifier

Android Studio will rebuild the Project (Build -> rebuild Project), you can generate the corresponding interface file

With everything in place, we can now return the class that instantiates the custom AIDL interface in the Service’s onBind method

public iBinder onBind(Intent intent) {
    return myBinder;
}

private IMyService.Stub.myBinder = new IMyService.Stub() {
    
    // Implement custom functions in the AIDL interface
    @Override
    public int addPlus(int x, int y) {
        return x + y
    }
}
Copy the code

Call addPlus in ServiceConnect in the Activity

ServiceConnect connect = new ServiceConnection() {
    @Override
    public void onServiceConnection(ComponentName name, IBinder service) {
        IMyService binder = IMyService.Stub.asInterface(service);
        
        int res = binder.addPlus(1.2);
    }
    
    @Override
    public void onServiceDisconnected(ComponentName name) {}}Copy the code

This completes a cross-process communication between an Activity and a Service.

Some questions about Service

1. What is the difference between a Service and a Thread?

Do not perform time-consuming operations in a Service. If a Service does not start a separate process, it runs in the main thread, the UI thread. Time-consuming operations may cause ANR. If you perform a time-consuming operation in a Service, you should start a thread in it.

The usage of the Service will be updated gradually in the future operation process, the current time is 27 January 2021

Refer to the link

  • Blog.csdn.net/rongwenbin/…
  • Blog.csdn.net/qq_30993595…
  • Blog.csdn.net/yuzhiqiang_…
  • Blog.csdn.net/pvpheroszw/…
  • Blog.csdn.net/guolin_blog…