Binder 자바 층 실현 원리
다음은 자신 이 쓴 에 이 드 파일 입 니 다.
package android.os;
interface IHelloService
{
void setVal(int val);
int getVal();
}
이것 은 aidl 파일 입 니 다. 컴 파일 한 후에 IHello Service. java 가 생 성 됩 니 다.이 파일 의 내용 에 어떤 비밀 이 숨겨 져 있 는 지 살 펴 보 자. 프로 세 스 간 통신 을 이렇게 신기 하 게 지원 할 수 있다.
자바 에 adl 파일 이 있 습 니 다. 많은 작업 을 줄 였 습 니 다. 사실은 다음 단락 에서 adl 파일 을 펼 치 는 것 이 c + + 와 비슷 합 니 다.
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/core/java/android/os/IHelloService.aidl
*/
package android.os;
public interface IHelloService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.IHelloService// Server , ,
{
private static final java.lang.String DESCRIPTOR = "android.os.IHelloService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.os.IHelloService interface,
* generating a proxy if needed.
*/
public static android.os.IHelloService asInterface(android.os.IBinder obj)// c++ , client new proxy
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.IHelloService))) {
return ((android.os.IHelloService)iin);
}
return new android.os.IHelloService.Stub.Proxy(obj);
}
public android.os.IBinder asBinder()
{
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_setVal:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
this.setVal(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getVal:
{
data.enforceInterface(DESCRIPTOR);
int _result = this.getVal();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.os.IHelloService// , client C++
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
public void setVal(int val) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(val);
mRemote.transact(Stub.TRANSACTION_setVal, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
public int getVal() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getVal, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_setVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getVal = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void setVal(int val) throws android.os.RemoteException;
public int getVal() throws android.os.RemoteException;
}
여기 서 우 리 는 IHello Service. aidl 이라는 파일 을 컴 파일 한 후의 정 체 를 볼 수 있 습 니 다. 원래 IHello Service 인터페이스의 정의 에 따라 해당 하 는 Stub 와 Proxy 류 를 생 성 하 는 것 입 니 다. 이것 이 바로 우리 가 익숙 한 Binder 체제 의 내용 입 니 다. 즉, 이 Hello Service 를 실현 하 는 서버 는 반드시 이곳 의 IHello Service. Stub 류 를 계속 해 야 합 니 다.이 Hello Service 의 원 격 인 터 페 이 스 는 바로 이곳 의 IHello Service. stub. Proxy 대상 이 얻 은 IHello Service 인터페이스 입 니 다.다음 내용 은 IHello Service. Stub 와 IHello Service. Stub. Proxy 가 어떻게 만 들 거나 사용 하 는 지 볼 수 있 습 니 다.
셋. HelloService 시작 과정
HelloService 의 시작 과정 을 논의 하기 전에 HelloService 인 터 페 이 스 를 실현 하 는 서버 가 어떻게 정의 되 는 지 살 펴 보 겠 습 니 다.
Ubuntu 에서 Android 시스템 의 Application Frameworks 층 에 하드웨어 접근 서 비 스 를 추가 한 것 을 기억 합 니 다. 저 희 는 frameworks / base / services / java / com / android / server 디 렉 터 리 에 Hello Service. java 파일 을 추 가 했 습 니 다.
package com.android.server;
import android.content.Context;
import android.os.IHelloService;
import android.util.Slog;
public class HelloService extends IHelloService.Stub {// aidl ,
private static final String TAG = "HelloService";
HelloService() {
init_native();
}
public void setVal(int val) {
setVal_native(val);
}
public int getVal() {
return getVal_native();
}
private static native boolean init_native();
private static native void setVal_native(int val);
private static native int getVal_native();
}
여기 서 볼 수 있 듯 이 HelloService 는 IHello Service. Stub 류 를 계속 진행 하 였 으 며, 로 컬 방법 으로 getVal 과 setVal 두 함 수 를 호출 하 였 습 니 다.저 희 는 이 두 함수 의 구체 적 인 실현 에 관심 이 없습니다. 관심 이 있 는 독 자 는 Ubuntu 에서 안 드 로 이 드 시스템 의 Application Frameworks 층 에 하드웨어 액세스 서 비 스 를 추가 하 는 것 을 참고 할 수 있 습 니 다.Hello Service 라 는 서버 클래스 가 생 긴 후, 다음 단 계 는 어떻게 그것 을 시작 할 것 인 가 를 고려 하 는 것 이다.frameworks / base / services / java / com / android / server / System Server. java 파일 에서 SystemServer 클래스 를 정의 합 니 다.SystemServer 대상 은 시스템 이 시 작 될 때 만 들 어 졌 습 니 다. 만 들 때 HelloService 를 만 들 기 위해 스 레 드 를 시작 하고 Service Manager 에 추가 합 니 다.
우 리 는 이 부분의 코드 를 살 펴 보 자.
class ServerThread extends Thread {
......
@Override
public void run() {
......
Looper.prepare();
......
try {
Slog.i(TAG, "Hello Service");
ServiceManager.addService("hello", new HelloService());// serviceManager
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Hello Service", e);
}
......
Looper.loop();
......
}
}
......
public class SystemServer
{
......
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
......
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
......
}
4. Client 가 HelloService 의 자바 원 격 인 터 페 이 스 를 가 져 오 는 과정앞에서 우 리 는 안 드 로 이 드 시스템 하드웨어 추상 층 (HAL) 을 공부 할 때 우 분투 에서 안 드 로 이 드 시스템 에 자바 응용 프로그램 테스트 Application Frameworks 층 의 하드웨어 서 비 스 를 내장 하 는 글 에서 우 리 는 응용 프로그램 을 만 들 었 다. 이 응용 프로그램 은 클 라 이언 트 역할 로 Service Manager 라 는 자바 원 격 인 터 페 이 스 를 통 해 HelloService 의 원 격 인 터 페 이 스 를 얻 었 다.헬 로 서비스 가 제공 하 는 서 비 스 를 호출 합 니 다.
Service Manager 라 는 자바 원 격 인 터 페 이 스 를 통 해 HelloService 의 원 격 인 터 페 이 스 를 어떻게 얻 는 지 살 펴 보 자.Hello 라 는 Activity 의 onCreate 함수 에서 IServiceManager. getService 함 수 를 통 해 HelloService 의 원 격 인 터 페 이 스 를 얻 을 수 있 습 니 다.
public class Hello extends Activity implements OnClickListener {
......
private IHelloService helloService = null;
......
@Override
public void onCreate(Bundle savedInstanceState) {
helloService = IHelloService.Stub.asInterface(
ServiceManager.getService("hello"));// helloservice, asInterface
}
......
}
자바 가 c + + 를 호출 하 는 JNI 는 분석 하지 않 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.