Android Getting Started Tutorial | Service of the four major components (foreground service, background service)

insert image description here

A Service is an application component that performs long-running operations in the background without providing a UI. Services can be started by other application components and will continue to run in the background even if the user switches to another application.

Additionally, components can interact with services by binding to them, and even perform interprocess communication (IPC). For example, a service can handle network transactions in the background, play music, perform file I/O, or interact with content providers.

Reception

The desk service performs some operations that the user can notice. For example, an audio app uses a foreground service to play audio tracks. A foreground service must display a notification. Foreground services continue to run even if the user stops interacting with the app.

Start the foreground service

The foreground service can provide users with operations on the interface. Every foreground service must display a notification in the notification bar. The user can perceive that the app's foreground service is running. This notification cannot be removed by default. After the service is stopped, the notification will be removed by the system. When the user does not need to directly operate the app, and the app needs to show the user a status display, the foreground service can be used.

Start the service in the activity and call startForegroundService(Intent)the method.

startForegroundService(Intent(applicationContext, ForegroundService1::class.java))

Then in the service, you need to use the method accordingly startForeground.

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    
    
        Log.d(TAG, "onStartCommand flags:$flags, startId:$startId [$this] ${Thread.currentThread()}")

        val pendingIntent: PendingIntent =
                Intent(this, ForegroundDemoAct::class.java).let {
    
     notificationIntent ->
                    PendingIntent.getActivity(this, 0, notificationIntent, 0)
                }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    
    
            val chanId = "f-channel"
            val chan = NotificationChannel(chanId, "前台服务channel",
                    NotificationManager.IMPORTANCE_NONE)
            chan.lightColor = Color.BLUE
            chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
            val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            service.createNotificationChannel(chan)
            Log.d(TAG, "服务调用startForeground")

            val notification: Notification =
                    Notification.Builder(applicationContext, chanId)
                            .setContentTitle("RustFisher前台服务")
                            .setContentText("https://an.rustfisher.com")
                            .setSmallIcon(R.drawable.f_zan_1)
                            .setContentIntent(pendingIntent)
                            .build()
            startForeground(1, notification)
        } else {
    
    
            Log.d(TAG, "${Build.VERSION.SDK_INT} < O(API 26) ")
        }
        return super.onStartCommand(intent, flags, startId)
    }` 

Let's look at this code in service. Created a simple one Notification.

  • PendingIntent will be assigned to Notification as a jump action after clicking on the notification
  • Use NotificationManager to create a NotificationChannel first
  • Use Notification.Builder to configure and create a Notification, such as configuring title, content text, icon, etc.
  • Start the foreground service and call startForeground(1, notification)the method

A notification will be displayed on the device. Clicking on this notification will jump to ForegroundDemoAct. This was previously set with PendingIntent.

Out of service

can be used stopServiceto stop the service

stopService(Intent(applicationContext, ForegroundService1::class.java))

In this way, the Service exits and takes onDestroythe method.

stop foreground service

stopForeground(boolean)Calling the method in the Service can stop the foreground, but does not exit the entire service. This boolean indicates whether to cancel the notification of the foreground service. false means keep notifications.

For example, calling in Service

stopForeground(false)

The service became a background service and did not exit. At this time, the corresponding notification can be canceled by sliding.

error message

ANR

The startup service is called in the Activity startForegroundService(Intent), but it is not called Service.startForeground(). OnePlus 5 mobile phone Android10 running log is as follows

2021-08-26 23:03:25.352 25551-25551/com.rustfisher.tutorial2020 D/rustAppUseStartService: 调用 startForegroundService 主线程信息Thread[main,5,main]
2021-08-26 23:03:25.368 25551-25551/com.rustfisher.tutorial2020 D/rustAppForeground1: onCreate Thread[main,5,main] rustfisher.com
2021-08-26 23:03:25.370 25551-25551/com.rustfisher.tutorial2020 D/rustAppForeground1: onStartCommand flags:0, startId:1 [com.rustfisher.tutorial2020.service.foreground.ForegroundService1@c77d408] Thread[main,5,main]
2021-08-26 23:03:35.375 1596-1720/? W/ActivityManager: Bringing down service while still waiting for start foreground: ServiceRecord{
    
    53d70f2 u0 com.rustfisher.tutorial2020/.service.foreground.ForegroundService1}
2021-08-26 23:03:35.382 25551-25551/com.rustfisher.tutorial2020 D/rustAppForeground1: onDestroy [com.rustfisher.tutorial2020.service.foreground.ForegroundService1@c77d408] Thread[main,5,main]

2021-08-26 23:03:52.956 1596-1720/? E/ActivityManager: ANR in com.rustfisher.tutorial2020
    PID: 25551
    Reason: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{
    
    53d70f2 u0 com.rustfisher.tutorial2020/.service.foreground.ForegroundService1}` 

Bad notification

We add it in the method of ForegroundService1 . If the id of 0 is passed in, an error will be reported .onStartCommandstartForegroundstartForeground(0, noti)RemoteServiceException

29871-29871/com.rustfisher.tutorial2020 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.rustfisher.tutorial2020, PID: 29871
    android.app.RemoteServiceException: Bad notification for startForeground

Background Services

Background services perform operations that are not directly noticed by the user. For example, if an app uses a service to compact its storage, that service is usually a background service.

  • The service/Service in this article refers to the background service.
  • The examples are implemented using Kotlin.

new service

We create a new ServiceStartDemo class inheriting Service

class ServiceStartDemo : Service() {
    
    

    companion object {
    
    
        const val TAG = "rustAppStartDemoService"
    }

    override fun onCreate() {
    
    
        super.onCreate()
        Log.d(TAG, "onCreate ${Thread.currentThread()}")
    }

    override fun onBind(intent: Intent): IBinder? {
    
    
        Log.d(TAG, "onBind ${Thread.currentThread()}")
        return null
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    
    
        Log.d(TAG, "onStartCommand flags:$flags, startId:$startId [$this] ${Thread.currentThread()}")
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
    
    
        super.onDestroy()
        Log.d(TAG, "onDestroy [$this] ${Thread.currentThread()}")
    }
}
  • In each life cycle method, we mark the log for follow-up observation
  • Print the detailed information of the service object, thread information, etc. in the log
  • In the onBind method, we return null, indicating that the service cannot be started by bindService

Register this service in AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
  <!-- ... -->
  <application>
    <service
        android:name=".service.start.ServiceStartDemo"
        android:enabled="true"
        android:exported="false" />
            <!-- ... -->
  </application>
</manifest>

Notice

  • name is the class name of our service. it is the only required attribute
  • enabled is true, indicating that the system can instantiate this service. The default value is true
  • application also has its own enabled property, the default value is true. This property applies to all application components, including services
  • Exported is set to false here, indicating that it is not used by other processes (apps), and only applies to our app so that our service is ready.

startService start service

Call the startService method in the activity to start the service.

startService(Intent(applicationContext, ServiceStartDemo::class.java))

After calling the method, the ServiceStartDemo service will be started. When started for the first time, the service will go through the onCreate and onStartCommand methods. The code of initialization nature is placed in onCreate.

If the service already exists, use the startService method to start the service, and the service will use the onStartCommand method. At this time, the startId in onStartCommand will increase automatically. Use this value to see how many times the Service object has been started.

At the same time, we can observe in the Service log that the Service life cycle function is executed in the main thread. Therefore, Service may also encounter ANR problems. Do not put time-consuming tasks in life cycle functions.

Activity communicates with Service

Activity and Service are independent components. Using startServicethe method to start the service does not make the activity hold an instance of the service. They can use broadcasting to communicate with each other. Or use tools like EventBus to communicate.

Out of service

After the task is done, we can stop the service. Save system resources. The front is startServicethe service started by the method, and the latter stopService(Intent)is used to stop the service.

method introduce
stopService(Intent) Activity or other components call this method to stop the target service
stopSelf() Service calls this method to stop itself

For example in Activity

stopService(Intent(applicationContext, ServiceStartDemo::class.java))

in Service

stopSelf()

Once a request is made to stop the service using stopSelf()or , the service will go the other way. The system will destroy the service as soon as possible.stopService()onDestroy()

Binding service

bindService()A service is bound when an application component binds to it through a call .

Bound services provide a client- server interface for components to interact with the service, send requests, receive results, and even perform these operations across processes using interprocess communication (IPC). Bound services only run when bound to another application component. Multiple components can be bound to the service at the same time, but when they are all unbound, the service is destroyed.

Service related interview questions

1. What is Service?

Service is one of the four major components of Android, which can perform long-running operations in the background without application components of the user interface.

There are two ways to start Service: startService start and bindService start.

Note: Services, like other application objects, run in the main thread of their hosting process. This means that if your service wants to perform any CPU-intensive (such as MP3 playback) or blocking (such as network) operations, it should create another child thread in the Service, and then it will be fine to process time-consuming operations here .

2. What to pay attention to when registering a Service

Service still runs in the main thread, so if you need to perform some complex logical operations, it is best to manually create sub-threads inside the service for processing, otherwise the UI thread will be blocked.

3. How to communicate between Service and Activity

method one:

  • Add an inner class that inherits Binder, and add corresponding logic methods
  • Rewrite the onBind method of Service and return the inner class instance we just defined
  • Rewrite ServiceConnection, when onServiceConnected calls the logical method to bind the service

Method Two

  • Calling the Service method through the interface Iservice, using the interface to call the service and calling the service directly are actually the same in essence, but there is an extra step of excuse

4. The difference between IntentService and Service (advantages of intentservice)

IntentService is a subclass of Service. It is an asynchronous service that will stop automatically. It solves the problem of forgetting to stop and destroy Service after processing time-consuming operations in traditional Service.

  • A separate worker thread will be created to handle all Intent requests;
  • An independent worker thread will be created to process the code implemented by the onHandleIntent() method without dealing with multi-threading issues;
  • After all requests are processed, the IntentService will automatically stop without calling the stopSelf() method to stop the Service;
  • Provide a default implementation for Service's onBind() and return null;
  • Provide a default implementation for Service's onStartCommand to add the request Intent to the queue;
  • IntentService will not block the UI thread, while ordinary Serveice will cause ANR exception
  • If the Intentservice has not completed the previous task, it will not open a new thread. It will wait for the previous task to complete before executing the new task, and then call stopSelf() again after the task is completed.

5. Is the Service executed in the main thread, and can time-consuming operations be performed in the service?

By default, if it is not displayed, it refers to the running process of service, Service and activity are running in the main thread (UI main thread) of the process where the current app is located.

Time-consuming operations (network requests, copying databases , large files) cannot be performed in the service

In special cases, you can configure the process where the service is executed in the manifest file, so that the service can be executed in another process

<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" >
</service>

6. Service life cycle

Service has binding mode and non-binding mode, as well as the mixed usage of these two modes. Different usage methods have different life cycle methods.

  • Non-binding mode: when startService is called for the first time, the methods executed are onCreate(), onStartCommand() in turn, and the onDestory method is called when the Service is closed.
  • Binding mode: when the first bindService() is executed, onCreate() and onBind() will be executed when the binding is unbound. onUnbind() and onDestory() will be executed.

The above two life cycles are in relatively simple mode. We must also pay attention during the development process that there will only be one Service instance, that is to say, if the Service to be started already exists, the Service will not be created again and of course the onCreate() method will not be called.

A Service can be bound by multiple clients, only all bound objects are executed

The Service will be destroyed after the onBind() method is executed, but if a client executes the onStart() method, then if all bind clients execute unBind() at this time, the Service will not be destroyed.

The life cycle diagram of Service is shown below to help you remember.

Only use startService to start the life cycle of the service

img

Only use BindService to bind the life cycle of the service

img

At the same time, use startService() to start the service and BindService() to bind the life cycle of the service

img

7. What is the relationship between Activity, Intent, and Service

They are the most frequently used classes in Android development. Among them, Activity and Service are one of the four major components of Android. Both of them are subclasses of ContextWrapper, a subclass of the Context class, so they can be regarded as brothers. However, the two brothers each have their own skills. Activity is responsible for the display and interaction of the user interface, and Service is responsible for the processing of background tasks. Data can be passed between Activity and Service through Intent, so Intent can be regarded as a communication messenger.

8. Are Service and Activity in the same thread?

For the same app, it is in the same thread by default, main Thread (UI Thread).

9. How to increase the priority of service?

  • In AndroidManifest.xmlthe file, you can android:priority = “1000”set the highest priority for the intent-filter through this attribute, 1000 is the highest value, if the number is smaller, the priority is lower, and it is practical for broadcasting.
  • Call the method in onStartCommand startForeground()to upgrade the Service to the foreground process level, and then remember to call stopForeground ()the method in onDestroy.
  • The onStartCommand method manually returns START_STICKY.
  • Send a broadcast to restart the service in the onDestroy method. The service +broadcast method is to send a custom broadcast when the service goes ondestory, and restart the service when the broadcast is received. (When the third-party application or in the setting-application-forced stop, the APP process will be killed directly, and the onDestroy method cannot enter, so there is no guarantee that it will be executed)
  • Monitor the system broadcast to judge the Service status. Through some broadcasts of the system, such as: mobile phone restart, interface wake-up, application status change, etc., monitor and capture, and then judge whether our Service is still alive.
  • Application plus the Persistent attribute.

10. How many return values ​​does the onStartCommand method of Service have? What do they mean?

There are four return values:

  • **START_STICKY: **If the service process is killed, the status of the service is kept as the start status, but the delivered intent object is not kept. Then the system will try to recreate the service. Since the service state is in the start state, the onStartCommand(Intent, int, int) method will be called after the service is created. If no start commands were passed to the service during this time, the parameter Intent will be null.
  • START_NOT_STICKY: "Non-sticky". When using this return value, if the service is killed abnormally after executing onStartCommand, the system will not automatically restart the service.
  • **START_REDELIVER_INTENT:** Retransmit Intent. When using this return value, if the service is killed abnormally after executing onStartCommand, the system will automatically restart the service and pass in the value of Intent.
  • START_STICKY_COMPATIBILITY: The compatible version of START_STICKY, but it does not guarantee that the service will restart after being killed.

11. What are the ways that the Activity calls the methods in the Service?

  • Binder: It is implemented in the form of Binder interface. When the Activity binds the Service successfully, the Activity will obtain the Binder subclass returned by the Service's onBind() method in the onServiceConnected() callback method of the ServiceConnection class, and then call it through the object method.
  • Aidl: aidl is more suitable for scenarios where the client and server are not in the same application.
  • Messenger: It references a Handler object so that others can send messages to it (using the mMessenger.send(Message msg) method). This class allows Message-based communication between processes (that is, two processes can communicate through Messages), and a Messenger is created using a Handler on the server side, and the client can communicate with the server after holding this Messenger. One Messeger cannot send in both directions at the same time, two Messegers can send in both directions

img

12. The difference between Service and Thread

Service is a system component in Android. It runs in the main thread of an independent process and cannot perform time-consuming operations. Thread is the smallest unit of program execution, the basic unit of CPU allocation, and can start sub-threads to perform time-consuming operations. Service can obtain its own instance in different Activities, and it is convenient to operate the Service. It is difficult for Thread to obtain its own instance in different Activities. If the Activity is destroyed, it is difficult to obtain the Thread instance again.

13. Using IntentService

IntentService is a subclass of Scrvice, so it is not an ordinary Service, it adds additional functions than ordinary Service.

Let's first look at the two problems of Service itself.

  • Service does not specifically start a separate process, Service and its application are located in the same process.
  • Service is not a new thread, so time-consuming tasks should not be processed directly in Service.

IntentService just makes up for the lack of Service.

Features of IntentService:

  • IntentService will create a separate worker thread to handle all Intent requests.
  • IntentService will create a separate worker thread to process the code implemented by the onHandleIntent() method, so developers don't have to deal with multi-threading issues.

IntentService instance

  1. Create SccIntentService.java inherited from the IntentService class, rewrite the onHandleIntent() method, and create a no-argument constructor. The code is as follows:
public class SccIntentService extends IntentService {
    
    
 public SccIntentService() {
    
    
 super("SccIntentService");
 }
 @Override
 protected void onHandleIntent(Intent intent) {
    
    
 MLog.e(getClass().getName(), "onHandleWork");
 for (int i = 0; i < 3; i++) {
    
    
 try {
    
    
 MLog.e(getClass().getName(), "Number:开始"+i);
 Thread.sleep(10000);
 MLog.e(getClass().getName(), "Number:结束"+i);
 } catch (InterruptedException e) {
    
    
 e.printStackTrace();
 }
 }
 }
 @Override
 public void onDestroy() {
    
    
 super.onDestroy();
 MLog.e(getClass().getName(), "onDestroy");
 }
}

\2. Add the IntentService component declaration, declare a Service component in the AndroidManifest.xml file, the code is as follows:

<service android:name=".service.SccIntentService"/>

\3. Start SccIntentService

startService(new Intent(ServiceActivity.this, SccIntentService.class));</pre>

\4. Running result

07-07 18:00:39.505 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonCreate
07-07 18:00:39.531 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonStart
07-07 18:00:39.531 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonResume
07-07 18:01:12.690 E/-SCC-com.scc.demo.service.SccIntentService: onHandleWork
07-07 18:01:12.690 E/-SCC-com.scc.demo.service.SccIntentService: Number:开始0
07-07 18:01:22.691 E/-SCC-com.scc.demo.service.SccIntentService: Number:结束0
07-07 18:01:22.697 E/-SCC-com.scc.demo.service.SccIntentService: Number:开始1
07-07 18:01:32.698 E/-SCC-com.scc.demo.service.SccIntentService: Number:结束1
07-07 18:01:32.698 E/-SCC-com.scc.demo.service.SccIntentService: Number:开始2
07-07 18:01:42.699 E/-SCC-com.scc.demo.service.SccIntentService: Number:结束2
07-07 18:01:42.716 E/-SCC-com.scc.demo.service.SccIntentService: onDestroy

Ordinary Service directly executes 20S time-consuming operations, which will block the main thread and cause ANR (Program Not Responding) exception.

IntentService performs 30S time-consuming operations without blocking the main thread, let alone generating ANR. As shown in the figure above, it starts from 18:01:12>18:01:42 for 30 seconds, and no ANR is generated during normal operation.

Another advantage of IntentService is "go away after use". After executing the time-consuming operations in the onHandleIntent() method, call the onDestroy() method to close it.

More complete information from zero-based entry to proficiency in Android can be obtained for free by scanning the QR code! ! !

[Tencent technical team produced] Android zero-based entry to proficiency, Android Studio installation tutorial + a full set of Android basic tutorials

Android programming tutorial

Java language basics from entry to familiarity

insert image description here

Kotlin language basics from entry to familiarity

insert image description here

Android technology stack from entry to familiarity

insert image description here

Android Jetpack family bucket comprehensive learning

insert image description here

For novices, it may be difficult to install Android Studio. You can watch the following video and learn to install and run step by step.

Android Studio installation tutorial

insert image description here

With the learning of the Java stage, it is recommended to focus on video learning at this stage and supplement it with books to check for omissions. If you focus on books, you can type codes based on book explanations, supplemented by teaching videos to check for omissions. If you encounter problems, you can go to Baidu. Generally, many people will encounter problems when getting started, and they will give better answers.

It is necessary to master basic knowledge points, such as how to use the four major components, how to create a Service, how to layout, simple custom View, animation, network communication and other common technologies.

A full set of zero-based tutorials has been prepared for you, if you need it, you can add the QR code below to get it for free

A full set of Android basic tutorials

insert image description here

insert image description here

insert image description here

insert image description here
insert image description here
insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/Android23333/article/details/132423453