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 Activity
startService
Start 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
onServiceConnected
Represents the callback function when the Activity successfully binds to the ServiceonServiceDisconnected
Represents 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…