Service of four Android Components
There are two ways to enable the Service of four Android components: startService (); enable the Service.
After the service is enabled, the service will run in the background for a long time, even if the caller exits. the service continues running in the background. the Service has nothing to do with the caller. The caller cannot access the methods in the service. bindService (); bind the service.
After the service is enabled, the lifecycle is associated with the caller. if the caller fails, the Service will also be suspended. if you do not want to live at the same time, but want to die at the same time. the caller and the service are bound together. The caller can indirectly call the methods in the service. AIDL
Local Service: Service Code in this application
Remote service: the service is in another application (in another process)
Aidl: android interface defination language
IPC implementation: inter process communication
Life Cycle of service hybrid call
After the service is enabled, bind the service and then stop the service. In this case, the service cannot be stopped. you must unbind the service before stopping the service. In actual development, this mode is often used to enable the Service (ensure that the service runs in the background for a long time)-> bind the Service (call the service method) -> unbind the service (the Service continues to run in the background)-> stop the service (the service stops). The service is only started once. if the service is enabled, it is ineffective to enable it again.
The principle of binding a service call method defines an interface, which defines a method
Public interface IService {public void callMethodInService (); // provides a method through this class to implement this interface for the custom class}
Customize an IBinder implementation class in the service so that this class inherits the Binder (the Binder is the default adapter of IBinder). Because the custom class is private, this class can be obtained for other classes, we need to define an interface and provide a method for the IBinder class to implement this interface, and call the methods that others want to call in the corresponding method.
Public class TestService extends Service {@ Override public IBinder onBind (Intent intent) {System. out. println (onbind); return new MyBinder ();} private class MyBinder extends Binder implements IService {public void callMethodInService () {// implement this method, call the method methodInService () ;}// public void methodInService () {Toast. makeText (this, I am Chun Ge in the service, balab !, 0). show ();}}
In the service calling class
onServiceConnectedThe second parameter in the method is forced to an interface.
Public class DemoActivity extends Activity {private Intent intent; private Myconn conn; private IService iService; @ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); intent = new Intent (this, TestService. class); setContentView (R. layout. main);} public void start (View view) {startService (intent);} public void stop (View view) {stopService (intent);} public void bind (View view) {conn = new Myconn (); // 1. the binding service transmits a conn object. this conn is a callback interface bindService (intent, conn, Context. BIND_AUTO_CREATE);} www.bkjia.com public void unbind (View view) {unbindService (conn);} // call the public void call (View view) {iService in the service. callMethodInService ();} private class Myconn implements ServiceConnection {// method called when the service is successfully bound. @ Override public void onServiceConnected (ComponentName, IBinder service) {// The second parameter is the return value of the onBind method in the service iService = (IService) service ;} @ Override public void onServiceDisconnected (ComponentName name ){}}}
Remote service aidl
The above describes how to bind a service to call a method in a service. This is also true for remote service binding,
However, this remote service is defined in another program,
It cannot be obtained in another program, even if we define an identical one in our own application.
But because the registration of the two programs is different, these two interfaces are also different. To solve this problem
Question: Google engineers have provided aidl. We will define.javaChange.aidl,
ThenPermission ModifierBothRemoveTo copy the aidl file in another program.
And put it in the same package name.AndroidThe package names are used to differentiate applications.
aidlThe system will think that the interfaces of the two programs are the same, so that
Program to convert parameters into this interface, in useaidlAfter the file is copied to your project, it will automatically
Generate an interface class, which has an internal classStubThis class inheritsBinderAnd implements
This interface, so we can customizeIBinder implementation classOnly need to inherit the custom classStub class
You can.
Define an interface in the remote service and change it
aidl
package com.seal.test.service; interface IService { void callMethodInService(); }
Define
Ibinder implementation classSo that the implementation class inherits
Stub class,
And
onBindMethod returns this custom Class Object
Public class RemoteService extends Service {@ Override public IBinder onBind (Intent intent) {System. out. println (remote service bound); return new MyBinder ();} private class MyBinder extends IService. stub {@ Override public void callMethodInService () {methodInService () ;}} public void methodInService () {System. out. println (method in remote service );}}
When you want to bind this service to other programs and call methods in this service, you must first copy
This
aidlFile the file to your project, and then
ServiceConnectionIn the implementation class
Use
asInterfaceThe method is converted to an interface. In this way, the interface is obtained and the method in the interface is called.
public class CallRemoteActivity extends Activity { private Intent service; private IService iService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); service = new Intent(); service.setAction(com.itheima.xxxx); } public void bind(View veiw){ bindService(service, new MyConn(), BIND_AUTO_CREATE); } public void call(View view){ try { iService.callMethodInService(); } catch (RemoteException e) { e.printStackTrace(); } } private class MyConn implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { iService = IService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } } }
Finally, let's talk about it.IntentService:
IntentServiceYesServiceTo process asynchronous requests. The client canstartService(Intent)MethodIntentSend requestIntentService,
IntentServiceTheIntentAdd to the queue, and thenIntentEnable oneworker threadAnd stops automatically after all the work is executed.Service.
Each request is stored in a separateworker threadDoes not block the main thread of the application.IntentServiceActuallyLooper,Handler,ServiceIt not only provides service functions, but also processes and cyclically messages.
Service:
A Service is not a separate process. the Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part. A Service is not a thread. it is not a means itself to do work off of the main thread (to avoid Application Not Responding errors ).
Therefore
ServiceA new thread is required for time-consuming operations.
Why?
ServiceInstead
ThreadThe main difference is that different lifecycles,
ServiceIs a component of the Android system. The Android system will try its best to maintain
ServiceLong-term background running,
Even if the service is killed due to insufficient memory (the service is rarely killed due to insufficient memory), the service will be revived when the memory is available.
ThreadThe IntentService will be killed later.
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests throughstartService (Intent) CILS;
The service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. this "work queue processor" pattern is commonly used to offload tasks from an application's main thread. the IntentService class exists to simplify this pattern and take care of the mechanic.
To use it, extend IntentService and implement onHandleIntent (Intent ). intentService will receive the Intents, launch a worker thread, and stop the service as appropriate. all requests are handled on a single worker thread-they may take as long as necessary (and will not block the application's main loop ), but only one request will be processed at a time.