Android System Level service detailed

Source: Internet
Author: User
Tags mul mutex stub usleep

First, Android system-level service brief description

The Android system-level service includes both Android and native services.

The Android service, also known as the Java Service, is written in the Java language and is implemented at the framework level.

Native Service, also known as System Service, is written in C + + language and is implemented in the runtime layer.

For both types of service, two Peer-to-peer service communications are using binder, just a use of *.aidl, a use of iinterface to write serialization code, the essence is the same, the following first introduced native The process of writing service and how to communicate with two native service. second, the characteristics of native service

A, because the underlying core service is the closest linux/driver part of the Android framework. To give full play to the differentiated features of hardware devices, core services are an important conduit for using the DRIVER/HW Device feature for upper-layer Java applications.

B, in the boot process, you can start core services (such as Chinese character input method services, etc.), so that many applications to share.

C, because of sharing, so can effectively reduce the size of the program and unified interface changes. Iii. How to implement an Android service
3.1. Take Alarmmanagerservice as an example to explain

Java-tier services, as the name implies, provide services from the Java layer, unlike the C + + layer service where the service process is maintained by the system (ServiceManager). In the file Frameworks/base/services/java/com/android/server/systemserver.java we can see the following code:

Alarmmanagerservice alarm = new Alarmmanagerservice (context);
ServiceManager. AddService (context. Alarm_service, ALARM);

This operation is completed when the system is started, and ServiceManager is responsible for creating the service process and running it.

Ialarmmanager.aidl the file in the directory/frameworks/base/core/java/android/app.

The implementation class of the Alarmmanagerservice aidl in the directory Frameworks/base/services/java/com/android/server,

Add the service implementation file to the directory frameworks/base/services/java/com/android/server. 3.2. Experiment Test Add Java System level service steps
3.2.1 Add aidl file

Add the file Idvbservice.aidl in the directory Frameworks/base/core/java/android/app.

Package Android.app;

Interface Idvbservice {
	int counttest (in int testvalue);
}

3.2.2 Create service class

Add Dvbmanagerservice implementation Idvbservice.aidl classes in the directory frameworks/base/services/java/com/android/server.

Package com.android.server;

Import Android.content.Context;
Import Android.util.Slog;
Import Android.app.IDvbService;

Class Dvbmanagerservice extends Idvbservice.stub {
 
    private static final String TAG = "Dvbmanagerservice";
    Private static Final Boolean LOCALLOGV = false;

    Private final context Mcontext;
    
    Public Dvbmanagerservice {
        super ();
        Mcontext = context;
        SLOG.W (TAG, "Dvbmanagerservice");
    }
    
    public int counttest (int value) {return
    	value*2
    }}
    

3.2.3 Add services to ServiceManager

Increase in the run () method in the file Frameworks/base/services/java/com/android/server/systemserver.java class

try {
	slog.i (TAG, "Alarm dvbmanagerservice");
	Dvbmanagerservice DVB = New Dvbmanagerservice (context);
	Servicemanager.addservice (Context.dvb_service, DVB);  
catch (Throwable e) {
	reportwtf ("Starting Dvbmanagerservice", e);
}

3.2.4 adds a constant to the service in the context

Increase in file Frameworks/base/core/java/android/content/context.java

public static final String Dvb_service = "DVB";//dvb

3.2.5 Add package management class to the framework

Add Dvbmanager.java to File Frameworks/base/core/java/android/app

Package Android.app;

Import Android.content.Context;
Import android.content.Intent;
Import android.os.RemoteException;
Import Android.os.ServiceManager;


public class dvbmanager{
    private final idvbservice mservice;

    /**
     * Package Private on Purpose * *
    Dvbmanager (idvbservice service) {
        mservice = service;
    }
    

    public int count (int value) {
        try {return
        	mservice.counttest (value);
        } catch (RemoteException ex) {
        }
        Return-1
    }    
}

3.2.6 Increase the way to get the encapsulation management class

To add a new attribute to the file Frameworks/base/core/java/android/app/contextimpl.java

private static Dvbmanager Sdvbmanager;//dvb

Increase in the Getsystemservice (String name) method

else if (dvb_service.equals (name)) {//DVB return
	getdvbmanager ();

Additional methods

    Private Dvbmanager Getdvbmanager () {//dvb
        synchronized (ssync) {
            if (Sdvbmanager = null) {
                IBinder B = Servic Emanager.getservice (dvb_service);
                Idvbservice service = IDvbService.Stub.asInterface (b);
                Sdvbmanager = new Dvbmanager (service);
            }
        return sdvbmanager;
    }

You can also add it directly to the static code block without doing the above two actions.

Registerservice (Account_service, New Staticservicefetcher () {public
	Object CreateService () {
		IBinder B = Servicemanager.getservice (dvb_service);
		Iaccountmanager service = IAccountManager.Stub.asInterface (b);
		return new Dvbmanager (service);
	}
);

Note: If you need to pass in the context parameter in the encapsulated management class, see the difference in the bold section below:

Registerservice (Account_service, New Servicefetcher () {public
	Object CreateService (Contextimpl ctx) {
		IBinder B = Servicemanager.getservice (account_service);
		Iaccountmanager service = IAccountManager.Stub.asInterface (b);
		return new Accountmanager (CTX, service);
	}
});

3.2.7 is configured inside the Android.mk .

Add one line under Local_src_files + + in Frameworks/base/android.mk

CORE/JAVA/ANDROID/APP/IDVBSERVICE.AIDL \

call in 3.2.8 application

The following applications are called:

Imports import Android.app.DvbManager;

Usage

Dvbmanager dvb= (Dvbmanager) Getsystemservice (dvb_service);
int count = Dvb.count (9);
LOG.I ("Dvbmanager", "Count =" + count);

3.2.9 Compilation Process

Compiled as follows:

(1) First compile frameworks

. build/envsetup.sh

Choosecombo

Make-j4 Framework

Framework.jar will be generated after compilation

(2) Then compile the Frameworks/base/services/java service

Make-j4 Frameworks/base/services/java

Services.jar will be generated after compilation

(3) Compiling application

Because the service is custom, all must be compiled in a custom SDK to be used. Iv. How to realize a native service

The main points are as follows:

A, core services are usually performed in separate processes (process).

b, the IBinder interface must be provided to allow other programs to bind (Binding) and call across processes.

C, because it is shared, you must ensure multithreading security (Thread-safe).

D, the definition of C + + category, the birth of its object, through the assistance of SM, the object reference value to the Iservicemanager::addservice () function, to join the Binder Driver.

E, the application can bind the core service far away through SM's assistance, and SM will return the IBinder interface to the application.

F, applications can transfer data to and from core services through the Ibinder::transact () function.

Here is a concrete example of how each step can be accomplished

First, describe the module structure of a test example:

Servicetesta is a common process that provides two integers for multiplication and division operations.

SERVICETESTB is an ordinary process that provides two integers for addition and subtraction operations.

Testservice is a test process program that primarily validates the interface functions of two service processes, where the code can be placed in any process for access calls

4.1 Writing Service processes

ServiceTestA.h header File Definition:

#ifndef __service_test_a__
#define __SERVICE_TEST_A__

#include <utils/RefBase.h>
#include < binder/iinterface.h>
#include <binder/Parcel.h>
#include <utils/threads.h>

namespace Android {
//Inherits Bbinder class to provide IBinder interface
class Servicetesta:public Bbinder {public
:
	Servicetesta ();
	Virtual ~servicetesta ();
	static int instantiate (); Create a unique class instance
	virtual status_t ontransact (uint32_t, const parcel&, parcel*, uint32_t);
Private:
//protected by Mlock Multithreading security
	mutable Mutex mlock;
}
#endif/* __service_test_a__ * *

ServiceTestA.cpp implementation file:

#include <cutils/log.h> #include <cutils/properties.h> #include <binder/IServiceManager.h> # Include <binder/IPCThreadState.h> #include <serviceTestA/serviceTestA.h> namespace Android {enum{Calcula

	Te_mul_num = 0, Calculate_div_num,};
		int Servicetesta::instantiate () {Logi ("Servicetesta instantiate"); int r = Defaultservicemanager ()->addservice (STRING16) (service.
		Testa "), New Servicetesta ());
		Logi ("Servicetesta r =%d/n", r);
	return R;
	} servicetesta::servicetesta () {Logi ("Servicetesta created");
	} servicetesta::~servicetesta () {Logi ("Servicetesta destroyed"); } status_t servicetesta::ontransact (uint32_t code, const Parcel&data, parcel*reply, uint32_t flags) {LOGI ("service
		Testa::ontransact code =%d ", code);
		Mutex::autolock _l (Mlock);
					Switch (code) {case calculate_mul_num:{int a = Data.readint32 ();
					int b = Data.readint32 ();
					int sum = a * b;
					Logi ("sum mul value =%d", sum); Reply->wRiteInt32 (sum);
				return no_error;
			} break;
				Case calculate_div_num:{int a = Data.readint32 ();
				int b = Data.readint32 ();
				int sum = A/b;
				Logi ("sum div value =%d", sum);
				Reply->writeint32 (sum);
			return no_error;
			} break;
		Default:return bbinder::ontransact (Code, data, reply, flags);
	return 0; }
}

ANDROID.MK file:

Local_path:= $ (call My-dir)
include $ (clear_vars) 
local_src_files:= serviceTestA.cpp
local_shared_ libraries:= libutils libutils libbinder
local_c_includes: = $ (top)/frameworks/base/include
LOCAL_MODULE:= Libservicetesta
local_prelink_module:= false
include $ (build_shared_library)

The Libservicetesta dynamic library is generated here, and the example upgrade service program

Writing a separate process program:

Its use is: the birth of a servicetesta category of objects, and then the object reference into the Binder Driver.

#include <sys/types.h>
#include <unistd.h>
#include <cutils/log.h>
#include < binder/iservicemanager.h>
#include <binder/IPCThreadState.h>
#include <servicetesta/ Servicetesta.h>

using namespace Android;

int main (int argc, char *argv[]) {
	sp < processstate > proc (processstate::self ());
	SP < iservicemanager > SM = Defaultservicemanager ();
	Logi ("ServiceManager:%p", Sm.get ());
	Servicetesta::instantiate (); This is the point ....
	processstate::self ()->startthreadpool ();
	Ipcthreadstate::self ()->jointhreadpool ();
	return 0;
}

ANDROID.MK file:

Local_path:= $ (call My-dir)
include $ (clear_vars)
local_src_files:= main.cpp
local_shared_libraries : = Libutils libservicetesta
local_module:= servicetesta
include $ (build_executable)

The most important here is the call: Servicetesta::instantiate ();

First executes to the new Servicetesta (), on the birth of a servicetesta category of objects;

Then, call Defaultservicemanager () function to obtain SM Iservicemanager interface;

Then call Iservicemanager::addservice () to deposit the object reference in the Binder Driver, and deposit it at the same time

Register and manage in ServiceManager so that other processes can find the corresponding service process through Servicemanager::getservice

The above code similarly, the SERVICETESTB service process is likewise established, no longer repeat.

4.2 Test Service Process

TestService.cpp writing:

#include <cutils/log.h> #include <cutils/properties.h> #include <binder/IServiceManager.h> # Include <binder/IPCThreadState.h> #include <serviceTestA/serviceTestA.h> #include <servicetestb/

Servicetestb.h> using namespace Android;

enum {calculate_add_num = 0, Calculate_sub_num,};

enum {calculate_mul_num = 0, Calculate_div_num,};
	int main (int argc, char *argv[]) {SP < ibinder > testabinder;
	SP < ibinder > testbbinder;
	Parcel data, reply;
	int sum = 0;
	Logi ("Testservice Main is call ...");

	SP < iservicemanager > SM = Defaultservicemanager (); while (1) {Testabinder = Sm->getservice (STRING16) ("service.")
		Testa "));
		LOGE ("Testa::getaddservice%p/n", Sm.get ());
			if (Testabinder = = 0) {LOGE ("Testaservice not published, waiting ...");
			Usleep (1000000);
		Continue
			else {Logi ("Testa::getaddservice success ...");
		Break } while (1) {Testbbinder = Sm->getservice (String16) (service.
		Testb ")); LOGE("Testb::getaddservice%p/n", Sm.get ());
			if (Testbbinder = = 0) {LOGE ("Testbservice not published, waiting ...");
			Usleep (1000000);
		Continue
			else {Logi ("Testb::getaddservice success ...");
		Break
	}//test functions in two service data.writeint32 (1000);
	Data.writeint32 (200);
	Logi ("Bpaddservice::create Remote ()->transact ()/n");
	Testabinder->transact (calculate_mul_num, data, &reply);
	sum = Reply.readint32 ();

	Logi ("Calculate_add_num value =%d", sum);
	Data.writeint32 (1000);
	Data.writeint32 (200);
	Logi ("Bpaddservice::create Remote ()->transact ()/n");
	Testabinder->transact (calculate_div_num, data, &reply);
	sum = Reply.readint32 ();

	Logi ("Calculate_sub_num value =%d", sum);
	Data.writeint32 (1000);
	Data.writeint32 (200);
	Logi ("Bpaddservice::create Remote ()->transact ()/n");
	Testbbinder->transact (calculate_add_num, data, &reply);
	sum = Reply.readint32 ();

	Logi ("Calculate_mul_num value =%d", sum);
	Data.writeint32 (1000); Data.writeint32 (200);
	Logi ("Bpaddservice::create Remote ()->transact ()/n");
	Testbbinder->transact (calculate_sub_num, data, &reply);
	sum = Reply.readint32 ();

	Logi ("Calculate_div_num value =%d", sum);
return 0; }

The most important thing here is to get the default SM through Defaultservicemanager, then get Sp<ibinder> object through GetService, then the interface function of the corresponding service process can be operated, the whole process is quite clear.

Finally attach the results of the test to print:

#./testservice./testservice # logcat Logcat---------beginning Of/dev/log/main (i/): 1379 Main is
Call ...
e/(1379): Testa::getaddservice 0xa680/n i/(1379): Testa::getaddservice success ...
e/(1379): Testb::getaddservice 0xa680/n i/(1379): Testb::getaddservice success ...        i/(1379): Bpaddservice::create remote ()->transact ()/n i/(1371): Servicetesta::ontransact code = 0 i/ (1371): sum mul value = 200000 i/(1379): calculate_mul_num value = 200000 i/(1379): Bpaddservice  :: Create Remote ()->transact ()/n i/(1371): servicetesta::ontransact code = 1 i/(1371): sum div value =        5 i/(1379): Calculate_div_num value = 5 i/(1379): Bpaddservice::create remote ()->transact ()/n i/ (1374): Servicetestb::ontransact code = 0 i/(1374): Sum add value = 1200 i/(1379): Calculate_add_nu M value = 1200 i/(1379): Bpaddservice::create RemotE ()->transact ()/n i/(1374): Servicetestb::ontransact code = 1 i/(1374): Sum sub value = i/ (1379): Calculate_sub_num value = 800

The results indicate that it is completely correct

Please click to download the document version. "How to create Android Services", Hasen personal blog to save personal gas.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.