startService(), bindService() of Android Component Service (1)

Keywords: Android xml

startService(), bindService() of Android Component Service (1)

1. Introduction to Service

service is a program in Android that implements program running in the background. It is very suitable to perform tasks that do not need to interact with users for a long time, and its operation does not depend on any user interface.
The service does not run in a separate process, but depends on the application process in which the service was created. When an application's process is killed, the services that depend on it will also stop running.
The service does not automatically open threads, and all code is defaulted in the main thread. This requires us to create sub-threads manually within the service and perform specific tasks here, otherwise the main thread may be blocked.

2. Basic usage of services

Service uses the following steps:
1. Inheritance of service class
2. Register services in the <application> node of the Android Manifast.xml configuration manifest file <service name=". Service Name"/>

The service cannot run on its own and needs to be started by Contex.startService() or Contex.bindService().

2.1 startService() Usage

The service started by the startService() method has nothing to do with the caller. Even if the caller closes, the service still runs to stop the service and calls the Context.stopService() or stopSelf() method. At this point, the system calls onDestory(). When the service is started with this method, the onCreate() - > onStartCommand() of the service is invoked first time when the service is started. If the service has been started, the service is redeployed again. With onStartCommand() method, onStart method is discarded when API 5 is triggered, and onStartCommand method is replaced by onStartCommand method.

    public class MainActivity extends AppCompatActivity {
        private Button btn_startservice;
        private  Button btn_stopservice;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn_startservice = (Button) findViewById(R.id.btn_startserver);
            btn_stopservice = (Button) findViewById(R.id.btn_stopservice);

            btn_startservice.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                //Implementation of Startup Services with Intent
                    Intent startIntent = new Intent(MainActivity.this, StartService.class);
                    startService(startIntent);
                }
            });

            btn_stopservice.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    Intent stopIntent = new Intent(MainActivity.this, StartService.class);
                    //Out of Service
                    stopService(stopIntent);
                }
            });
        }
    }
    //Class service
    public class StartService extends Service {

        @Override
        public void onCreate(){
            super.onCreate();
            Log.d("startService", "onCreate executed");
        }
        @Override
        public int onStartCommand(Intent intent, int flag, int startId){
            Log.d("startService", "onStartCommand executed");
            return super.onStartCommand(intent, flag, startId);
        }
        @Override
        public void onDestroy(){
            super.onDestroy();
            Log.d("startService", "onDestroy executed");
        }
        @Override
        public IBinder onBind(Intent intent){
            throw new UnsupportedOperationException("Not yet implemented");
        }

    }
Display results:
    02-21 09:10:06.086 3712-3712/com.example.servicetest D/startService: onCreate executed
    02-21 09:10:06.086 3712-3712/com.example.servicetest D/startService: onStartCommand executed
    02-21 09:10:07.933 3712-3712/com.example.servicetest D/startService: onStartCommand executed
    02-21 09:10:09.703 3712-3712/com.example.servicetest D/startService: onDestroy executed

In the application interface, onCreate() onStartCommand() is invoked by using the startservice button, onStartCommand() is invoked by pressing only onStartCommand() again, and onDestroy() is invoked by pressing the stopservice button.

2.2 bindService() mode

The service started with bindService() is bound to the caller (Context), and terminates as soon as the caller closes the service. When the service is started with this method, the service first starts the system and calls the service onCreate() - > onBind (). If the service is started again, the two methods will not be triggered. When the caller exits (or does not exist), the system will call the service onUnbind() - > onDes. Contex.unbindService() can be used to actively unbind. The system calls onUnbind() - > onDestory (), in turn.
Using bindService, you can communicate with a running service. startService is suitable for long-term operation in the background. Frequent communication with it will cause performance problems.

    //Create a Binder object to manage the download function
    public class DownBinderService extends Service {
        /**
         * 1. A public inner class inherits Binder and adds two methods.
         * 2. Create a new IBinder object, the new Binder inner class;
         * 3. onBind Method returns the IBinder object.
         */
        private DownloadBinder mBinder = new DownloadBinder();
        //Inherited Binder's DownloadBinder inner class and wrote two operable methods.
        class DownloadBinder extends Binder {
            public void startDownload(){
                Log.d("DownBinderService", "startdownload");
            }
            public int getProgress(){
                Log.d("DownBinderService","getprogress..");
                return 0;
            }
        }

        @Override
        public IBinder onBind(Intent intent) {
            return mBinder;

        }
    }
    //In onCreate() in MainActivity, the following code services are bound and unbound
            btn_bindservice = (Button) findViewById(R.id.btn_bindservice);
            btn_unbindservice = (Button) findViewById(R.id.btn_unbindservice);

            btn_bindservice.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    Intent bindIntent = new Intent(MainActivity.this, DownBinderService.class);
                    //Binding service
                    bindService(bindIntent, connection, BIND_AUTO_CREATE);
                }
            });
            btn_unbindservice.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    //Unbundling service
                    unbindService(connection);
                }
            });
//Write the following code for service callback in MainActivity
        private DownBinderService.DownloadBinder downloadBinder;
        //In Activity, we get the connection through the Service Connection interface
    //    Define callbacks for service binding and pass them to bindService ()
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                downloadBinder = (DownBinderService.DownloadBinder) service;
                downloadBinder.startDownload();
                downloadBinder.getProgress();
            }
        //Call this method when the service contact is interrupted
            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
    };

The steps for bindService() to invoke a method:

  • Create an internal class (such as the DownloadBinder above) within the service to provide methods that can indirectly invoke the service's methods
  • The onBind() method, which implements the service, returns the object of the inner class DownloadBinder (which is also actually an IBinder object).
  • Bind services in Activity.
  • The callback method onService Connected, which is successfully bound to the service, passes an IBinder object.
  • Force the type to be converted to a custom interface type (such as download Binder = downBinder Service. Download Binder) service;) and invoke the method in the interface.

The ServiceConnection anonymous class is created, and two of the methods are rewritten to be invoked when the service is successfully bound and unbounded.

Binding is asynchronous, and bindService() returns immediately, without returning IBinder to the client. To receive IBinder, the client must create an instance of Service Connection and pass it to bindService(). Service Connection contains a callback method that the system will call to pass the IBinder required by the client.

Be careful:
Only activities, services and content provider s can be bound to services, and services cannot be bound from broadcast receiver s.

3. Service life cycle

In Bounded mode, onUnbind() is also called as onRebind(): When the service is rebounded, the object of this binding is previously created and not destroyed (onDestroy()), so the onRebind() method will be invoked when the binding service is executed, and onBind() will not be invoked this time.

Posted by Najjar on Mon, 01 Apr 2019 15:24:30 -0700