“This is the 26th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

In the last article, we introduced activities as one of the four components of Android development. Today, we introduce Service, the second component of the four components.

Basic understanding of Service

A Service is an application component that can run operations in the background for a long time without using a user interface. A Service can be started by another application component and continues to run in the background even if the user switches to another application. Services are used to process time-consuming logic in the background or to perform long-running tasks. If necessary, we can keep the Service running in the background even after the program exits. A Service is similar to an Activity, but the difference is that a Service always runs in the background and has no user interface, so it does not come to the foreground. If a Service is started, it has its own declaration cycle, just like an Activity. Note that a Service is not the same as a Thread. Don’t be confused by the concept behind a Service. In fact, the Service does not automatically start the thread; all code runs in the main thread by default. Therefore, we need to manually create child threads inside the Service and perform specific tasks there, otherwise we may cause ANR problems.

How to use Service

A Service is in the “Started” state when an application component, such as an Activity, starts it by calling startService(). Once started, a Service can run in the background indefinitely, even if the component that started it has been destroyed. Typically, an open Service performs a single operation and does not return a result to the caller. For example, it might download or upload files over the network. After the operation is complete, the Service automatically stops running. A Service is “bound” when an application component is bound to it by calling bindService(). A bound Service provides a client/server interface that allows components to interact with the Service and even use inter-process communication (IPC) for cross-process operations. The bound Service runs only when bound to another application component. Multiple components can be bound to the service at the same time, but when all are unbound, the service is destroyed.

Use of the Started Service

We Started the project.

Create a class that inherits Service:

Public class MyService extends Service {/** * This method is mandatory for subclasses of Service. It returns an IBinder object, @override public IBinder onBind(intent intent) {return null; @override public void onRebind(intent intent) {@override public void onRebind(intent intent) { super.onRebind(intent); } /** * Override public void onCreate() {super.oncreate (); Log.e("MyService", "onCreate"); } /** * This method is executed every time another component calls startService(Intent), and is used by other components to send a value to the service. The return value is set to control its own restart. @param Intent * @param flags * @param startId * @return */ @override public int onStartCommand(Intent intent, int flags, int startId) { Log.e("MyService", "onStartCommand"); return super.onStartCommand(intent, flags, startId); } /** * Override public void onDestroy() {super.ondestroy (); } /** * this method is called when service unbinds and disconnects. * @param intent * @return */ @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); }}Copy the code

Register Service in manifest file:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".MyService" />
    </application>
Copy the code

Ok, let’s write a class to start the service:

public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btnStartService, btnStopService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); btnStartService.setOnClickListener(this); btnStopService.setOnClickListener(this); } private void initView() { btnStartService = (Button) findViewById(R.id.start); btnStopService = (Button) findViewById(R.id.stop); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start: startService(startIntent); break; case R.id.stop: stopService(stopIntent); break; default: break; }}}Copy the code

OnCreate () and onStartCommand will only be called when the Service is started for the first time. Clicking the Start Service button again thereafter only executes the onStartCommand() method and does not Start another Service.

Use of the Bind Service

Create a BindService:

public class BindService extends Service { private int count=0; private boolean isQuit=false; Public MyBind MyBind =new MyBind(); Public class MyBind extends Binder{public int getCount() {return count; } public BindService getService() { return BindService.this; @override public IBinder onBind(Intent Intent) {return myBind; @override public void onCreate() {system.out.println ("Service is Created."); New Thread(){@override public void run() {while (! isQuit) { try { Thread.sleep(1000); Catch (InterruptedException e) {// TODO auto-generated catch block e.printStackTrace(); } count++; } } }.start(); super.onCreate(); } @override public void onDestroy() {system.out.println ("Service is Destroyed."); isQuit=true; super.onDestroy(); } public String getDemoName() {return "Service instance "; Override public Boolean onUnbind(Intent Intent) {system.out. println("Service is Unbind."); return true; OnRebind () {// next time the client is bound, accept a call to onRebind() instead of onBind()}}Copy the code

Bind also needs to register in the manifest, so I won’t post the code here. Let’s see how bind initializes:

public class BindServiceActivity extends Activity { private Button btnBind,btnUnBind; private BindService bindService; private MyBind myBind; private boolean isBind=false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.bind); btnBind=(Button)findViewById(R.id.btnBind); btnUnBind=(Button)findViewById(R.id.btnUnBind); OnClickListener listener=new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnBind: Intent intent=new Intent(BindServiceActivity.this,BindService.class); // Bind the specified Service bindService(intent, serviceConnection, BIND_AUTO_CREATE); isBind=true; break; Case R.I.B. tnUnBind: if (isBind) {// unbindService unbindService(serviceConnection); isBind=false; bindService=null; Toast.makeText(BindServiceActivity.this,"--Service is Unbind.--" , Toast.LENGTH_LONG).show(); } else {Toast. MakeText (BindServiceActivity. This bundle Service - "" - you haven't, Toast. LENGTH_LONG), show (); } break; }}}; btnBind.setOnClickListener(listener); btnUnBind.setOnClickListener(listener); } // Define a ServiceConnection object private ServiceConnection ServiceConnection =new ServiceConnection() { @override public void onServiceDisconnected(ComponentName name) {Override public void onServiceDisconnected(ComponentName name) { bindService=null; Toast.makeText(BindServiceActivity.this,"--Service UnConnected.--" , Toast.LENGTH_LONG).show(); } // Override public void onServiceConnected(ComponentName = connected) IBinder service) {// Get the BindService object returned by getService() myBind=((myBind)service); bindService=myBind.getService(); Toast.makeText(BindServiceActivity.this,"--Service Connected.--" , Toast.LENGTH_LONG).show(); System.out.println("--Service Connected.--"); }}; }Copy the code

When I click the “Bind Service” button, I can see that the console prints “Service is Created.” and “– service Connected.” After the Service is bound to the Activity, the Activity can also obtain the running state of the Service through the MyBind object. When I click the “Get Service state” button, I see the prompt message on the interface. If we click the “Unbind” button, we can see the output in LogCat: “Service is Unbind.”, “Service is Destroyed.” when the program calls unbindService() to Unbind a Service, the system calls the unbindService() method first. The onDestory() method is then called back.

Difference: Unlike calling the startService () method multiple times to start a Service, calling the bindService() method multiple times does not double bind. In this example, the onBind () method of the Service is called only once, no matter how many times the user clicks the “bind Service” pair.

Let’s look at the lifecycle changes in two different Service startup processes:

In contrast to the figure above, the overall life of the Service starts when onCreate() is called and ends when onDestroy() returns. Like an Activity, a Service performs its initialization in onCreate() and releases any remaining resources in onDestroy(). OnCreate () and onDestroy() are called by all services, whether they are created by startService() or bindService().

The main active method of a Service is when onStartCommand() or onBind() is called, each of which handles the Intent object passed by the startService() or bindService() methods.

If a Service is started by startService(), its active life cycle ends with the entire life cycle.

If services are started by bindService (), their active life ends when onUnbind() returns.

Note: Although a started Service is stopped by calling stopSelf() or stopService(), there is no corresponding callback function, that is, no onStop() callback method. So, when the stop method is called, unless the Service is bound to the client component, the system will destroy it directly, and the onDestory() method will be called, and is the only callback method that will be called at that time.

Precautions for using Service

Start and stop,bind and unbind.