안 드 로 이 드 IPC 메커니즘 의 Binder 작업 메커니즘 에 대해 논 하 다.

8476 단어 AndroidIPCBinder
프로 세 스 와 스 레 드 의 관계
운영 체제 의 설명 에 따 르 면 스 레 드 는 CPU 스케줄 의 최소 단위 이 고 스 레 드 도 유한 한 시스템 자원 이다.프로 세 스 는 일반적으로 실행 단원 을 가리 키 며,pc 단 이나 이동 단 에 서 는 프로그램 이나 응용 프로그램 을 가리킨다.하나의 프로 세 스 에 하나 이상 의 스 레 드 를 포함 할 수 있 습 니 다.그래서 그들의 관 계 는 포함 되 고 포 함 된 관계 일 것 이다.
크로스 프로 세 스 의 종류
Android 에서 프로 세 스 간 통신 방식 은 여러 가지 가 있 습 니 다.Bundle,파일 공유,AIDL,Messenger,ContentProvider,Socket 등 은 프로 세 스 간 통신 을 실현 할 수 있 습 니 다.물론 프로 세 스 간 통신 을 실현 할 수 있 지만 이들 의 실현 원리 나 바 텀 실현 방식 은 다 릅 니 다.다음은 우리 가 일일이 설명 할 것 이다.
주:많은 학생 들 이 프로 세 스 를 만 들 려 면 새로운 응용 프로그램 을 만들어 야 한다 고 생각 합 니 다.사실은 아니에요.우리 가 AndroidMenifest 에 이 코드 를 추가 하면 안 드 로 이 드:process=":remote"의 구체 적 인 것 은 학생 들 이 스스로 이해 할 수 있 습 니 다.
IPC 를 말 하기 전에 먼저 기초 개념 을 말 하면 뒤의 내용 을 더욱 잘 이해 할 수 있다.
직렬 화 가능,Parcelable 인터페이스
Serializable 인 터 페 이 스 는 자바 가 제공 하 는 직렬 화 된 인터페이스 입 니 다.이것 은 빈 인터페이스 로 대상 에 게 표준 직렬 화 와 반 직렬 화 작업 을 제공 합 니 다.
Serializable 직렬 화 와 반 직렬 화 는 모두 Object OutputStream 과 Object InputStream 을 채취 하면 실 현 될 수 있 습 니 다.물론 이 시스템 들 은 기본적으로 우 리 를 위해 실현 되 었 습 니 다.
Parcelable 인 터 페 이 스 는 안 드 로 이 드 자체 의 직렬 화 방식 이다.서열 화 와 반 서열 화 는 모두 writeToParcel 방법 을 통 해 이 루어 진다.
이들 의 차이 점:Serializable 은 자바 의 직렬 화 인터페이스 사용 이 간단 하지만 직렬 화 와 반 직렬 화 과정 은 대량의 I/o 작업 이 필요 하기 때문에 성능 이 비교적 떨어진다.Parcelable 인 터 페 이 스 를 사용 하 는 것 은 비교적 번 거 롭 지만 효율 이 높 지만 매우 큰 단점 이 있 습 니 다.바로 Parcelable 에 의 해 대상 을 직렬 화 한 후에 대상 을 디스크 에 저장 하 는 것 은 매우 번 거 로 울 것 입 니 다.그래서 Serializable 을 사용 하 는 것 을 권장 합 니 다.
Binder
직관 적 으로 볼 때 Binder 는 Android 의 한 종류 로 IBinder 인 터 페 이 스 를 실현 합 니 다.IPC 의 측면 에서 볼 때 Binder 는 Android 의 크로스 프로 세 스 통신 방식 이자 가상 물리 장치 로 이해 할 수 있 습 니 다.장치 구동 은/dev/binder/입 니 다.프레임 워 크 측면 에서 볼 때 Binder 는 ServiceManager 의 다리 이다.응용 층 에서 볼 때 Binder 는 클 라 이언 트 와 서버 가 통신 하 는 매개체 이다.
Android 개발 에서 Binder 는 주로 Service 에 사용 되 는데 AIDL 과 Messenger 를 포함한다.Messenger 의 밑바닥 이 사실은 Aidl 이기 때문에 지금 은 AIDL 로 binder 의 작업 체 제 를 분석 해 보 자.
상위 코드:

/*

 * This file is auto-generated.  DO NOT MODIFY.

 * Original file: /Users/huangjialin/MyApplication/service/src/main/aidl/aidl/MyAIDLService.aidl

 */

package aidl;

// Declare any non-default types here with import statements


public interface MyAIDLService extends android.os.IInterface {



    /**

     * Local-side IPC implementation stub class.

     */

    public static abstract class Stub extends android.os.Binder implements aidl.MyAIDLService {

        private static final java.lang.String DESCRIPTOR = "aidl.MyAIDLService";



        /**

         * Construct the stub at attach it to the interface.

         */

        public Stub() {

            this.attachInterface(this, DESCRIPTOR);

        }



        /**

         * Cast an IBinder object into an aidl.MyAIDLService interface,

         * generating a proxy if needed.

         */

        public static aidl.MyAIDLService asInterface(android.os.IBinder obj) {

            if ((obj == null)) {

                return null;

            }

            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

            if (((iin != null) && (iin instanceof aidl.MyAIDLService))) {

                return ((aidl.MyAIDLService) iin);

            }

            return new aidl.MyAIDLService.Stub.Proxy(obj);

        }



        @Override

        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_getString: {

                    data.enforceInterface(DESCRIPTOR);

                    java.lang.String _result = this.getString();

                    reply.writeNoException();

                    reply.writeString(_result);

                    return true;

                }

            }

            return super.onTransact(code, data, reply, flags);

        }



        private static class Proxy implements aidl.MyAIDLService {

            private android.os.IBinder mRemote;



            Proxy(android.os.IBinder remote) {

                mRemote = remote;

            }



            @Override

            public android.os.IBinder asBinder() {

                return mRemote;

            }



            public java.lang.String getInterfaceDescriptor() {

                return DESCRIPTOR;

            }




            @Override

            public java.lang.String getString() throws android.os.RemoteException {

                android.os.Parcel _data = android.os.Parcel.obtain();

                android.os.Parcel _reply = android.os.Parcel.obtain();

                java.lang.String _result;

                try {

                    _data.writeInterfaceToken(DESCRIPTOR);

                    mRemote.transact(Stub.TRANSACTION_getString, _data, _reply, 0);

                    _reply.readException();

                    _result = _reply.readString();

                } finally {

                    _reply.recycle();

                    _data.recycle();

                }

                return _result;

            }

        }



        static final int TRANSACTION_getString = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);

    }



    public java.lang.String getString() throws android.os.RemoteException;

}
위의 코드 는 시스템 에서 생 성 된 것 으로 gen 디 렉 터 리 에서 MyAIDL Service.aidl 시스템 에 따라 MyAIDL Service.java 라 는 종 류 를 생 성 한 것 을 볼 수 있 습 니 다.우 리 는 먼저 이 유형의 모든 방법의 의 미 를 알 아 보 자.
DESCRIPTOR:Binder 의 유일한 표 지 는 현재 Binder 의 클래스 이름 표시 에 사 용 됩 니 다.
asInterface(android.os.IBinder obj):서버 의 Binder 대상 을 클 라 이언 트 에 필요 한 AIDL 인터페이스 형식의 대상 으로 변환 하 는 데 사 용 됩 니 다.이러한 전환 과정 은 프로 세 스 를 구분 합 니 다.클 라 이언 트 와 서버 가 같은 프로 세 스에 있다 면 이 방법 은 서버 의 stub 대상 자 체 를 되 돌려 줍 니 다.그렇지 않 으 면 시스템 패 키 징 후의 Stub.proxy 대상 을 되 돌려 줍 니 다.
asBinder():현재 Binder 대상 을 되 돌려 줍 니 다.
onTransact:이 방법 은 서버 의 Binder 스 레 드 탱크 에서 실 행 됩 니 다.클 라 이언 트 가 크로스 프로 세 스 통신 요청 을 할 때 원 격 요청 은 시스템 바 텀 패 키 징 을 통 해 이 방법 으로 처리 합 니 다.이 방법 을 주의 하 십시오.Public boolean onTransact(int code,android.os.Parcel data,android.os.Parcel reply,int flags),서버 는 code 를 통 해 클 라 이언 트 가 요청 한 목표 방법 이 무엇 인지 확인 할 수 있 습 니 다.이 어 data 에서 목표 방법 에 필요 한 인 자 를 꺼 내 목표 방법 을 실행 합 니 다.대상 방법 이 실행 되면 reply 에 반환 값 을 기록 하 는 것 과 같 습 니 다.이 방법의 집행 과정 은 바로 이렇다.이 방법 이 false 로 돌아 가면 클 라 이언 트 가 실 패 를 요청 할 수 있 기 때문에 우 리 는 이 방법 에서 안전 검증 을 할 수 있 습 니 다.
public java.lang.String getString() throws android.os.RemoteException:
이 방법 은 클 라 이언 트 에서 실 행 됩 니 다.클 라 이언 트 가 이 방법 을 호출 할 때 내부 구현 은 이 렇 습 니 다.먼저 이 방법 에 필요 한 입력 형식 Parcel 대상 을 만 듭 니 다.data,그리고 transact 방법 을 호출 하여 원 격 호출 요청 을 하 는 동시에 현재 스 레 드 가 걸 린 다음 에 서버 의 OnTransact 방법 이 호출 됩 니 다.RPC 과정 이 돌아 올 때 까지 현재 스 레 드 가 계속 실행 되 고reply 에서 되 돌아 오 는 데 이 터 를 읽 습 니 다.
그림:Binder 의 작업 메커니즘

위 에서 분석 한 바 와 같이 우 리 는 Binder 의 작업 메커니즘 을 이 해 했 지만 몇 가지 문 제 를 주의해 야 한다.
1.클 라 이언 트 가 요청 을 할 때 현재 스 레 드 가 걸 려 서 서버 에서 데 이 터 를 되 돌려 줄 때 까지 원 격 방법 이 오래 걸 리 면 UI 스 레 드,즉 메 인 스 레 드 에서 원 격 요청 을 할 수 없습니다.
2.Service 의 Binder 방법 은 온라인 스 레 드 풀 을 실행 하기 때문에 Binder 방법 은 시간 이 걸 리 든 시간 이 걸 리 지 않 든 동기 화 방식 을 사용 해 야 합 니 다.왜냐하면 이것 은 이미 한 스 레 드 에서 실행 되 었 기 때 문 입 니 다.
이상 은 안 드 로 이 드 IPC 체제 의 Binder 작업 체제 에 대한 상세 한 내용 입 니 다.안 드 로 이 드 IPC 체제 의 Binder 작업 체제 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기