ǰÑÔ
FrameworkÊÇÒ»¸öÖмä²ã£¬Ëü¶Ô½ÓÁ˵ײãʵÏÖ£¬·â×°Á˸´ÔÓµÄÄÚ²¿Âß¼£¬²¢Ìṩ¹©ÍⲿʹÓõĽӿڡ£Framework²ãÊÇÓ¦ÓóÌÐò¿ª·¢µÄ»ù´¡¡£
Binder Framework²ã·ÖΪC++ºÍJavaÁ½¸ö²¿·Ö£¬ÎªÁË´ïµ½¹¦Äܵĸ´Óã¬Öмäͨ¹ýJNI½øÐÐÏνӡ£
Binder FrameworkµÄC++²¿·Ö£¬Í·ÎļþλÓÚÕâ¸ö·¾¶£º/frameworks/native/include/binder/£¬ÊµÏÖλÓÚÕâ¸ö·¾¶£º/frameworks/native/libs/binder/
¡£Binder¿â×îÖÕ»á±àÒë³ÉÒ»¸ö¶¯Ì¬Á´½Ó¿â£ºlibbinder.so£¬¹©ÆäËû½ø³ÌÁ´½ÓʹÓá£
ΪÁ˱ãÓÚ˵Ã÷£¬ÏÂÎÄÖÐÎÒÃǽ«Binder Framework µÄC++²¿·Ö³ÆÖ®Îªlibbinder¡£
Ö÷Òª½á¹¹
libbinderÖУ¬½«ÊµÏÖ·ÖΪProxyºÍNativeÁ½¶Ë¡£Proxy¶ÔÓ¦ÁËÉÏÎÄÌáµ½µÄClient¶Ë£¬ÊÇ·þÎñ¶ÔÍâÌṩµÄ½Ó¿Ú¡£¶øNativeÊÇ·þÎñʵÏÖµÄÒ»¶Ë£¬¶ÔÓ¦ÁËÉÏÎÄÌáµ½µÄServer¶Ë¡£ÀàÃûÖдøÓÐСд×ÖĸpµÄ£¨ÀýÈçBpInterface£©£¬¾ÍÊÇÖ¸Proxy¶Ë¡£ÀàÃû´øÓÐСд×ÖĸnµÄ£¨ÀýÈçBnInterface£©£¬¾ÍÊÇÖ¸Native¶Ë¡£
Proxy´ú±íÁ˵÷Ó÷½£¬Í¨³£Óë·þÎñµÄʵÏÖ²»ÔÚͬһ¸ö½ø³Ì£¬Òò´ËÏÂÎÄÖУ¬ÎÒÃÇÒ²³ÆProxy¶ËΪ¡°Ô¶³Ì¡±¶Ë¡£Native¶ËÊÇ·þÎñʵÏÖµÄ×ÔÉí£¬Òò´ËÏÂÎÄÖУ¬ÎÒÃÇÒ²³ÆNative¶ËΪ¡±±¾µØ¡°¶Ë¡£
ÕâÀÎÒÃÇÏȶÔlibbinderÖеÄÖ÷ÒªÀà×öÒ»¸ö¼òҪ˵Ã÷£¬Á˽âÒ»ÏÂËüÃǵĹØÏµ£¬È»ºóÔÙÏêϸµÄ½²½â¡£

ÏÂͼÃèÊöÁËÕâЩÀàÖ®¼äµÄ¹ØÏµ£º
ÁíÍâ˵Ã÷һϣ¬Binder·þÎñµÄʵÏÖÀࣨͼÖÐ×ÏÉ«²¿·Ö£©Í¨³£¶¼»á×ñÊØÏÂÃæµÄÃüÃû¹æÔò£º
1.·þÎñµÄ½Ó¿ÚʹÓÃI×Öĸ×÷Ϊǰ׺
2.Ô¶³Ì½Ó¿ÚʹÓÃBp×÷Ϊǰ׺
3.±¾µØ½Ó¿ÚʹÓÃBn×÷Ϊǰ׺

¿´ÁËÉÏÃæÕâЩ½éÉÜ£¬Äã¿ÉÄÜ»¹ÊDz»Ì«ÈÝÒ×Àí½â¡£²»¹ý²»Òª½ô£¬ÏÂÃæÎÒÃÇ»áÖð²½²ð·Ö½²½âÕâЩÄÚÈÝ¡£
ÔÚÕâ·ùͼÖУ¬Ç³»ÆÉ«²¿·ÖµÄ½á¹¹ÊÇ×îÄÑÀí½âµÄ£¬Òò´ËÎÒÃÇÏÈ´ÓËüÃÇ×ÅÊÖ¡£
ÎÒÃÇÏÈÀ´¿´¿´IBinderÕâ¸öÀà¡£Õâ¸öÀàÃèÊöÁËËùÓÐÔÚBinderÉÏ´«µÝµÄ¶ÔÏó£¬Ëü¼ÈÊÇBinder±¾µØ¶ÔÏóBBinderµÄ¸¸À࣬ҲÊÇBinderÔ¶³Ì¶ÔÏóBpBinderµÄ¸¸Àà¡£Õâ¸öÀàÖеÄÖ÷Òª·½·¨ËµÃ÷ÈçÏ£º

BpBinderµÄʵÀý´ú±íÁËÔ¶³ÌBinder£¬Õâ¸öÀàµÄ¶ÔÏ󽫱»¿Í»§¶Ëµ÷Óá£ÆäÖÐhandle·½·¨»á·µ»ØÖ¸ÏòBinder·þÎñʵÏÖÕߵľä±ú£¬Õâ¸öÀà×îÖØÒª¾ÍÊÇÌṩÁËtransact·½·¨£¬Õâ¸ö·½·¨»á½«Ô¶³Ìµ÷ÓõIJÎÊý·â×°ºÃ·¢Ë͵ÄBinderÇý¶¯¡£
ÓÉÓÚÿ¸öBinder·þÎñͨ³£¶¼»áÌṩ¶à¸ö·þÎñ½Ó¿Ú£¬¶øÕâ¸ö·½·¨ÖеÄuint32_t code²ÎÊý¾ÍÊÇÓÃÀ´¶Ô·þÎñ½Ó¿Ú½øÐбàºÅÇø·ÖµÄ¡£Binder·þÎñµÄÿ¸ö½Ó¿Ú¶¼ÐèÒªÖ¸¶¨Ò»¸öΨһµÄcode£¬Õâ¸öcodeÒªÔÚProxyºÍNative¶ËÅä¶ÔºÃ¡£µ±¿Í»§¶Ë½«ÇëÇó·¢Ë͵½·þÎñ¶ËµÄʱºò£¬·þÎñ¶Ë¸ù¾ÝÕâ¸öcode£¨onTransact·½·¨ÖУ©À´Çø·Öµ÷ÓÃÄĸö½Ó¿Ú·½·¨¡£
BBinderµÄʵÀý´ú±íÁ˱¾µØBinder£¬ËüÃèÊöÁË·þÎñµÄÌṩ·½£¬ËùÓÐBinder·þÎñµÄʵÏÖÕß¶¼Òª¼Ì³ÐÕâ¸öÀࣨµÄ×ÓÀࣩ£¬Ôڼ̳ÐÀàÖУ¬×îÖØÒªµÄ¾ÍÊÇʵÏÖonTransact·½·¨£¬ÒòΪÕâ¸ö·½·¨ÊÇËùÓÐÇëÇóµÄÈë¿Ú¡£Òò´Ë£¬Õâ¸ö·½·¨ÊǺÍBpBinderÖеÄtransact·½·¨¶ÔÓ¦µÄ£¬Õâ¸ö·½·¨Í¬ÑùÒ²ÓÐÒ»¸öuint32_t
code²ÎÊý£¬ÔÚÕâ¸ö·½·¨µÄʵÏÖÖУ¬ÓÉ·þÎñÌṩÕßͨ¹ýcode¶ÔÇëÇóµÄ½Ó¿Ú½øÐÐÇø·Ö£¬È»ºóµ÷ÓþßÌåʵÏÖ·þÎñµÄ·½·¨¡£
IBinderÖж¨ÒåÁËuint32_t codeÔÊÐíµÄ·¶Î§£º
FIRST_CALL_TRANSACTION = 0x00000001, LAST_CALL_TRANSACTION = 0x00ffffff,
|
Binder·þÎñÒª±£Ö¤×Ô¼ºÌṩµÄÿ¸ö·þÎñ½Ó¿ÚÓÐÒ»¸öΨһµÄcode£¬ÀýÈçij¸öBinder·þÎñ¿ÉÒÔ½«£ºadd½Ó¿ÚcodeÉèΪ1£¬minus½Ó¿ÚcodeÉèΪ2£¬multiple½Ó¿ÚcodeÉèΪ3£¬divide½Ó¿ÚcodeÉèΪ4£¬µÈµÈ¡£
½²ÍêÁËIBinder£¬BpBinderºÍBBinderÈý¸öÀ࣬ÎÒÃÇÔÙÀ´¿´¿´BpReBase£¬IInterface£¬BpInterfaceºÍBnInterface¡£
ÿ¸öBinder·þÎñ¶¼ÊÇΪÁËij¸ö¹¦ÄܶøÊµÏֵģ¬Òò´ËÆä±¾Éí»á¶¨ÒåÒ»Ì×½Ó¿Ú¼¯£¨Í¨³£ÊÇC++µÄÒ»¸öÀࣩÀ´ÃèÊö×Ô¼ºÌṩµÄËùÓй¦ÄÜ¡£¶øBinder·þÎñ¼ÈÓÐ×ÔÉíʵÏÖ·þÎñµÄÀ࣬ҲҪÓиø¿Í»§¶Ë½ø³Ìµ÷ÓõÄÀࡣΪÁ˱ãÓÚ¿ª·¢£¬ÕâÁ½ÖÐÀàÀïÃæµÄ·þÎñ½Ó¿ÚÓ¦µ±ÊÇÒ»Öµģ¬ÀýÈ磺¼ÙÉè·þÎñʵÏÖ·½ÌṩÁËÒ»¸ö½Ó¿ÚΪadd(int
a, int b)µÄ·þÎñ·½·¨£¬ÄÇôÆäÔ¶³Ì½Ó¿ÚÖÐÒ²Ó¦µ±ÓÐÒ»¸öadd(int a, int b)·½·¨¡£Òò´ËΪÁËʵÏÖ·½±ã£¬±¾µØÊµÏÖÀàºÍÔ¶³Ì½Ó¿ÚÀàÐèÒªÓÐÒ»¸ö¹«¹²µÄÃèÊö·þÎñ½Ó¿ÚµÄ»ùÀࣨ¼´ÉÏͼÖеÄIXXXService£©À´¼Ì³Ð¡£¶øÕâ¸ö»ùÀàͨ³£ÊÇIInterfaceµÄ×ÓÀ࣬IInterfaceµÄ¶¨ÒåÈçÏ£º
class IInterface : public virtual RefBase { public: IInterface(); static sp<IBinder> asBinder(const IInterface*); static sp<IBinder> asBinder(const sp<IInterface>&);
protected:
virtual ~IInterface();
virtual IBinder* onAsBinder() = 0;
}; |
Ö®ËùÒÔÒª¼Ì³Ð×ÔIInterfaceÀàÊÇÒòΪÕâ¸öÀàÖж¨ÒåÁËonAsBinderÈÃ×ÓÀàʵÏÖ¡£onAsBinderÔÚ±¾µØ¶ÔÏóµÄʵÏÖÀàÖзµ»ØµÄÊDZ¾µØ¶ÔÏó£¬ÔÚÔ¶³Ì¶ÔÏóµÄʵÏÖÀàÖзµ»ØµÄÊÇÔ¶³Ì¶ÔÏó¡£onAsBinder·½·¨±»Á½¸ö¾²Ì¬·½·¨asBinder·½·¨µ÷Óá£ÓÐÁËÕâЩ½Ó¿ÚÖ®ºó£¬ÔÚ´úÂëÖбã¿ÉÒÔÖ±½Óͨ¹ýIXXX::asBinder·½·¨»ñÈ¡µ½²»ÓÃÇø·Ö±¾µØ»¹ÊÇÔ¶³ÌµÄIBinder¶ÔÏó¡£Õâ¸öÔÚ¿ç½ø³Ì´«µÝBinder¶ÔÏóµÄʱºòÓкܴóµÄ×÷Óã¨ÒòΪ²»ÓÃÇø·Ö¾ßÌåϸ½Ú£¬Ö»ÒªÖ±½Óµ÷Óúʹ«µÝ¾ÍºÃ£©¡£
ÏÂÃæ£¬ÎÒÃÇÀ´¿´Ò»ÏÂBpInterfaceºÍBnInterfaceµÄ¶¨Ò壺
template<typename INTERFACE> class BnInterface : public INTERFACE, public BBinder { public: virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
};
// ----------------------------------------------------------------------
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote);
protected:
virtual IBinder* onAsBinder();
}; |
ÕâÁ½¸öÀà¶¼ÊÇÄ£°åÀ࣬ËüÃÇÔڼ̳Ð×ÔINTERFACEµÄ»ù´¡Éϸ÷×Լ̳ÐÁËÁíÍâÒ»¸öÀà¡£ÕâÀïµÄINTERFACE±ãÊÇÎÒÃÇBinder·þÎñ½Ó¿ÚµÄ»ùÀà¡£ÁíÍ⣬BnInterface¼Ì³ÐÁËBBinderÀ࣬ÓÉ´Ë¿ÉÒÔͨ¹ý¸´Ð´onTransact·½·¨À´ÌṩʵÏÖ¡£BpInterface¼Ì³ÐÁËBpRefBase£¬Í¨¹ýÕâ¸öÀàµÄremote·½·¨¿ÉÒÔ»ñÈ¡µ½Ö¸Ïò·þÎñʵÏÖ·½µÄ¾ä±ú¡£ÔÚ¿Í»§¶Ë½Ó¿ÚµÄʵÏÖÀàÖУ¬Ã¿¸ö½Ó¿ÚÔÚ×é×°ºÃ²ÎÊýÖ®ºó£¬¶¼»áµ÷ÓÃremote()->transactÀ´·¢ËÍÇëÇ󣬶øÕâÀïÆäʵ¾ÍÊǵ÷ÓõÄBpBinderµÄtransact·½·¨£¬ÕâÑùÇëÇó±ãͨ¹ýBinderµ½´ïÁË·þÎñʵÏÖ·½µÄonTransactÖС£Õâ¸ö¹ý³ÌÈçÏÂͼËùʾ£º

»ùÓÚBinder¿ò¼Ü¿ª·¢µÄ·þÎñ£¬³ýÁËÂú×ãÉÏÎÄÌáµ½µÄÀàÃû¹æÔòÖ®Í⣬»¹ÐèÒª×ñÊØÆäËûһЩ¹²Í¬µÄ¹æÔ¼£º
ΪÁ˽øÐзþÎñµÄÇø·Ö£¬Ã¿¸öBinder·þÎñÐèÒªÖ¸¶¨Ò»¸öΨһµÄ±êʶ£¬Õâ¸ö±êʶͨ¹ýgetInterfaceDescriptor·µ»Ø£¬ÀàÐÍÊÇÒ»¸ö×Ö·û´®¡£Í¨³££¬Binder·þÎñ»áÔÚÀàÖж¨Òåstatic
const android::String16 descriptor;ÕâÑùÒ»¸ö³£Á¿À´ÃèÊöÕâ¸ö±êʶ·û£¬È»ºóÔÚgetInterfaceDescriptor·½·¨Öзµ»ØÕâ¸ö³£Á¿¡£
ΪÁ˱ãÓÚµ÷ÓÃÕß»ñÈ¡µ½µ÷Óýӿڣ¬·þÎñ½Ó¿ÚµÄ¹«¹²»ùÀàÐèÒªÌṩһ¸öandroid::sp<IXXX>
asInterface·½·¨À´·µ»Ø»ùÀà¶ÔÏóÖ¸Õë¡£
ÓÉÓÚÉÏÃæÌáµ½µÄÕâÁ½µã¶ÔÓÚËùÓÐBinder·þÎñµÄʵÏÖÂß¼¶¼ÊÇÀàËÆµÄ¡£ÎªÁ˼ò»¯¿ª·¢ÕßµÄÖØ¸´¹¤×÷£¬ÔÚlibbinderÖУ¬¶¨ÒåÁËÁ½¸öºêÀ´¼ò»¯ÕâÐ©ÖØ¸´¹¤×÷£¬ËüÃÇÊÇ£º
#define DECLARE_META_INTERFACE(INTERFACE) \ static const android::String16 descriptor; \ static android::sp<I##INTERFACE> asInterface( \ const android::sp<android::IBinder>& obj); \ virtual const android::String16& getInterfaceDescriptor() const; \ I##INTERFACE(); \ virtual ~I##INTERFACE(); \
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
\
const android::String16 I##INTERFACE::descriptor(NAME);
\
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const {
\
return I##INTERFACE::descriptor; \
} \
android::sp<I##INTERFACE> I##INTERFACE::asInterface(
\
const android::sp<android::IBinder>&
obj) \
{ \
android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } |
ÓÐÁËÕâÁ½¸öºêÖ®ºó£¬¿ª·¢ÕßÖ»ÒªÔÚ½Ó¿Ú»ùÀࣨIXXX£©Í·ÎļþÖУ¬Ê¹ÓÃDECLARE_META_INTERFACEºê±ãÍê³ÉÁËÐèÒªµÄ×é¼þµÄÉùÃ÷¡£È»ºóÔÚcppÎļþÖÐʹÓÃIMPLEMENT_META_INTERFACE±ãÍê³ÉÁËÕâЩ×é¼þµÄʵÏÖ¡£
BinderµÄ³õʼ»¯
ÔÚ½²½âBinderÇý¶¯µÄʱºòÎÒÃǾÍÌáµ½£ºÈκÎʹÓÃBinder»úÖÆµÄ½ø³Ì¶¼±ØÐëÒª¶Ô/dev/binderÉ豸½øÐÐopenÒÔ¼°mmapÖ®ºó²ÅÄÜʹÓã¬Õⲿ·ÖÂß¼ÊÇËùÓÐʹÓÃBinder»úÖÆ½ø³Ì¹²Í¬µÄ¡£¶ÔÓÚÕâÖÖ¹²Í¬Âß¼µÄ·â×°±ãÊÇFramework²ãµÄÖ°ÔðÖ®Ò»¡£libbinderÖУ¬ProcessStateÀà·â×°ÁËÕâ¸öÂß¼£¬Ïà¹Ø´úÂë¼ûÏÂÎÄ¡£
ÕâÀïÊÇProcessState¹¹Ô캯Êý£¬ÔÚÕâ¸öº¯ÊýÖУ¬³õʼ»¯mDriverFDµÄʱºòµ÷ÓÃÁËopen_driver·½·¨´ò¿ªbinderÉ豸£¬È»ºóÓÖÔÚº¯ÊýÌåÖУ¬Í¨¹ýmmap½øÐÐÄÚ´æÓ³Éä¡£
ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER) , mThreadCountDecrement(PTHREAD_COND_INITIALIZER) , mExecutingThreadsCount(0) , mMaxThreads(DEFAULT_MAX_BINDER_THREADS) , mStarvationStartTimeMs(0) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThreadPoolStarted(false) , mThreadPoolSeq(1) { if (mDriverFD >= 0) { mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0); if (mVMStart == MAP_FAILED) { // *sigh* ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n"); close(mDriverFD); mDriverFD = -1; } }
LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder
driver could not be opened. Terminating.");
}
|
open_driverµÄº¯ÊýʵÏÖÈçÏÂËùʾ¡£ÔÚÕâ¸öº¯ÊýÖÐÍê³ÉÁËÈý¸ö¹¤×÷£º
1.Ê×ÏÈͨ¹ýopenϵͳµ÷Óôò¿ªÁËdev/binderÉ豸
2.È»ºóͨ¹ýioctl»ñÈ¡BinderʵÏֵİ汾ºÅ£¬²¢¼ì²éÊÇ·ñÆ¥Åä
3.×îºóͨ¹ýioctlÉèÖýø³ÌÖ§³ÖµÄ×î´óÏß³ÌÊýÁ¿
¹ØÓÚÕⲿ·ÖÂß¼±³ºóµÄ´¦Àí£¬ÔÚ½²½âBinderÇý¶¯µÄʱºò£¬ÎÒÃÇÒѾ½²½â¹ýÁË¡£
static int open_driver() { int fd = open("/dev/binder", O_RDWR | O_CLOEXEC); if (fd >= 0) { int vers = 0; status_t result = ioctl(fd, BINDER_VERSION, &vers); if (result == -1) { ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); close(fd); fd = -1; } if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { ALOGE("Binder driver protocol does not match user space protocol!"); close(fd); fd = -1; } size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1) { ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); } } else { ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); } return fd; }
|
ProcessStateÊÇÒ»¸öSingleton£¨µ¥Àý£©ÀàÐ͵ÄÀ࣬ÔÚÒ»¸ö½ø³ÌÖУ¬Ö»»á´æÔÚÒ»¸öʵÀý¡£Í¨¹ýProcessState::self()½Ó¿Ú»ñÈ¡Õâ¸öʵÀý¡£Ò»µ©»ñÈ¡Õâ¸öʵÀý£¬±ã»áÖ´ÐÐÆä¹¹Ô캯Êý£¬ÓÉ´ËÍê³ÉÁ˶ÔÓÚBinderÉ豸µÄ³õʼ»¯¹¤×÷¡£
¹ØÓÚBinder´«µÝÊý¾ÝµÄ´óСÏÞÖÆ
ÓÉÓÚBinderµÄÊý¾ÝÐèÒª¿ç½ø³Ì´«µÝ£¬²¢ÇÒ»¹ÐèÒªÔÚÄÚºËÉÏ¿ª±Ù¿Õ¼ä£¬Òò´ËÔÊÐíÔÚBinderÉÏ´«µÝµÄÊý¾Ý²¢²»ÊÇÎÞÎÞÏÞ´óµÄ¡£mmapÖÐÖ¸¶¨µÄ´óС±ãÊǶÔÊý¾Ý´«µÝµÄ´óСÏÞÖÆ£º
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2)) // 1M - 8k
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
|
ÕâÀïÎÒÃÇ¿´µ½£¬ÔÚ½øÐÐmmapµÄʱºò£¬Ö¸¶¨ÁË×î´ósizeΪBINDER_VM_SIZE£¬¼´ 1M ¨C 8kµÄ´óС¡£
Òò´ËÎÒÃÇÔÚ¿ª·¢¹ý³ÌÖУ¬Ò»´ÎBinderµ÷ÓõÄÊý¾Ý×ܺͲ»Äܳ¬¹ýÕâ¸ö´óС¡£
¶ÔÓÚÕâ¸öÇøÓòµÄ´óС£¬ÎÒÃÇÒ²¿ÉÒÔÔÚÉ豸ÉϽøÐÐÈ·ÈÏ¡£ÕâÀïÎÒÃÇ»¹Ö®Ç°Ìáµ½µÄsystem_serverΪÀý¡£ÉÏÃæÎÒÃǽ²½âÁËͨ¹ýprocfsÀ´»ñȡӳÉäµÄÄÚ´æµØÖ·£¬³ý´ËÖ®Í⣬ÎÒÃÇÒ²¿ÉÒÔͨ¹ýshowmapÃüÁÀ´È·¶¨Õâ¿éÇøÓòµÄ´óС£¬Ïà¹ØÃüÁîÈçÏ£º
angler:/ # ps | grep system_server system 1889 526 2353404 135968 SyS_epoll_ 72972eeaf4 S system_server angler:/ # showmap 1889 | grep "/dev/binder" 1016 4 4 0 0 4 0 0 1 /dev/binder
|
ÕâÀï¿ÉÒÔ¿´µ½£¬Õâ¿éÇøÓòµÄ´óСÕýÊÇ 1M ¨C 8K = 1016k¡£
Tips: ͨ¹ýshowmapÃüÁî¿ÉÒÔ¿´µ½½ø³ÌµÄÏêϸÄÚ´æÕ¼ÓÃÇé¿ö¡£ÔÚʵ¼ÊµÄ¿ª·¢¹ý³ÌÖУ¬µ±ÎÒÃÇÒª¶Ôij¸ö½ø³Ì×öÄÚ´æÕ¼Ó÷ÖÎöµÄʱºò£¬Õâ¸öÃüÁîÊÇÏ൱ÓÐÓõġ£½¨Òé¶ÁÕß³¢ÊÔͨ¹ýshowmapÃüÁî²é¿´system_server»òÆäËû¸ÐÐËȤ½ø³ÌµÄÍêÕûmap£¬¿´¿´ÕâЩ½ø³Ì¶¼ÒÀÀµÁËÄÄЩ¿â»òÕßÄ£¿é£¬ÒÔ¼°ÄÚ´æÕ¼ÓÃÇé¿öÊÇÔõÑùµÄ¡£
ÓëÇý¶¯µÄͨÐÅ
ÉÏÎÄÌáµ½ProcessStateÊÇÒ»¸öµ¥ÀýÀ࣬һ¸ö½ø³ÌÖ»ÓÐÒ»¸öʵÀý¡£¶ø¸ºÔðÓëBinderÇý¶¯Í¨ÐŵÄIPCThreadStateÒ²ÊÇÒ»¸öµ¥ÀýÀà¡£µ«Õâ¸öÀ಻ÊÇÒ»¸ö½ø³ÌÖ»ÓÐÒ»¸öʵÀý£¬¶øÊÇÒ»¸öÏß³ÌÓÐÒ»¸öʵÀý¡£
IPCThreadState¸ºÔðÁËÓëÇý¶¯Í¨ÐŵÄϸ½Ú´¦Àí¡£Õâ¸öÀàÖеĹؼü¼¸¸ö·½·¨ËµÃ÷ÈçÏ£º

BpBinder::transact·½·¨ÔÚ·¢ËÍÇëÇóµÄʱºò£¬Æäʵ¾ÍÊÇÖ±½Óµ÷ÓÃÁËIPCThreadState¶ÔÓ¦µÄ·½·¨À´·¢ËÍÇëÇóµ½BinderÇý¶¯µÄ£¬Ïà¹Ø´úÂëÈçÏ£º
status_t BpBinder::transact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (mAlive) { status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); if (status == DEAD_OBJECT) mAlive = 0; return status; }
return DEAD_OBJECT;
} |
¶øIPCThreadState::transact·½·¨Ö÷ÒªÂß¼ÈçÏ£º
status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
if (err == NO_ERROR) {
err = writeTransactionData(BC_TRANSACTION, flags,
handle, code, data, NULL);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
} else {
err = waitForResponse(NULL, NULL);
}
return err;
} |
Õâ¶Î´úÂëÓ¦¸Ã»¹ÊDZȽϺÃÀí½âµÄ£ºÊ×ÏÈͨ¹ýwriteTransactionDataдÈëÊý¾Ý£¬È»ºóͨ¹ýwaitForResponseµÈ´ý·µ»Ø½á¹û¡£TF_ONE_WAY±íʾ´Ë´ÎÇëÇóÊǵ¥ÏòµÄ£¬¼´£º²»ÓÃÕæÕýµÈ´ý½á¹û¼´¿É·µ»Ø¡£
¶øwriteTransactionData·½·¨Æäʵ¾ÍÊÇÔÚ×é×°binder_transaction_dataÊý¾Ý£º
Hello World!status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer) { binder_transaction_data tr;
tr.target.ptr = 0; /* Don't pass uninitialized
stack data to a remote process */
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
const status_t err = data.errorCheck();
if (err == NO_ERROR) {
tr.data_size = data.ipcDataSize();
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
tr.data.ptr.offsets = data.ipcObjects();
} else if (statusBuffer) {
tr.flags |= TF_STATUS_CODE;
*statusBuffer = err;
tr.data_size = sizeof(status_t);
tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
tr.offsets_size = 0;
tr.data.ptr.offsets = 0;
} else {
return (mLastError = err);
}
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
|
¶ÔÓÚbinder_transaction_dataÔÚ½²½âBinderÇý¶¯µÄʱºòÎÒÃÇÒѾÏêϸ½²½â¹ýÁË¡£¶øÕâÀïµÄParcelÎÒÃÇ»¹²»Á˽⣬ÄÇô½ÓÏÂÀ´ÎÒÃÇÂíÉϾÍÀ´¿´Ò»ÏÂÕâ¸öÀà¡£
Êý¾Ý°ü×°Æ÷£ºParcel
BinderÉÏÌṩµÄÊÇ¿ç½ø³ÌµÄ·þÎñ£¬Ã¿¸ö·þÎñ°üº¬Á˲»Í¬µÄ½Ó¿Ú£¬Ã¿¸ö½Ó¿ÚµÄ²ÎÊýÊýÁ¿ºÍÀàÐͶ¼²»Ò»Ñù¡£ÄÇôµ±¿Í»§¶ËÏëÒªµ÷Ó÷þÎñ¶ËµÄ½Ó¿Ú£¬²ÎÊýÊÇÈçºÎ¿ç½ø³Ì´«µÝ¸ø·þÎñ¶ËµÄÄØ£¿³ý´ËÖ®Í⣬·þÎñ¶ËÏëÒª¸ø¿Í»§¶Ë·µ»Ø½á¹û£¬½á¹ûÓÖÊÇÈçºÎ´«µÝ»ØÀ´µÄÄØ£¿
ÕâЩÎÊÌâµÄ´ð°¸¾ÍÊÇ£ºParcel¡£Parcel¾ÍÏñÒ»¸ö°ü×°Æ÷£¬µ÷ÓÃÕß¿ÉÒÔÒÔÈÎÒâ˳ÐòÍùÀïÃæ·ÅÈëÐèÒªµÄÊý¾Ý£¬ËùÓÐдÈëµÄÊý¾Ý¾ÍÏñÊDZ»´ò³ÉÒ»¸öÕûÌåµÄ°ü£¬È»ºó¿ÉÒÔÖ±½ÓÔÚBindeÉÏ´«Êä¡£
ParcelÌṩÁËËùÓлù±¾ÀàÐ͵ÄдÈëºÍ¶Á³ö½Ó¿Ú£¬ÏÂÃæÊÇÆäÖеÄÒ»²¿·Ö£º
... status_t writeInt32(int32_t val); status_t writeUint32(uint32_t val); status_t writeInt64(int64_t val); status_t writeUint64(uint64_t val); status_t writeFloat(float val); status_t writeDouble(double val); status_t writeCString(const char* str); status_t writeString8(const String8& str);
status_t readInt32(int32_t *pArg) const;
uint32_t readUint32() const;
status_t readUint32(uint32_t *pArg) const;
int64_t readInt64() const;
status_t readInt64(int64_t *pArg) const;
uint64_t readUint64() const;
status_t readUint64(uint64_t *pArg) const;
float readFloat() const;
status_t readFloat(float *pArg) const;
double readDouble() const;
status_t readDouble(double *pArg) const;
intptr_t readIntPtr() const;
status_t readIntPtr(intptr_t *pArg) const;
bool readBool() const;
status_t readBool(bool *pArg) const;
char16_t readChar() const;
status_t readChar(char16_t *pArg) const;
int8_t readByte() const;
status_t readByte(int8_t *pArg) const;
// Read a UTF16 encoded string, convert to UTF8
status_t readUtf8FromUtf16(std::string* str) const;
status_t readUtf8FromUtf16(std::unique_ptr<std::string>*
str) const;
const char* readCString() const;
... |
Òò´Ë¶ÔÓÚ»ù±¾ÀàÐÍ£¬¿ª·¢Õß¿ÉÒÔÖ±½Óµ÷ÓýӿÚдÈëºÍ¶Á³ö¡£¶ø¶ÔÓÚ·Ç»ù±¾ÀàÐÍ£¬ÐèÒªÓÉ¿ª·¢Õß½«Æä²ð·Ö³É»ù±¾ÀàÐÍÈ»ºóдÈëµ½ParcelÖУ¨¶Á³öµÄʱºòÒ²ÊÇÒ»Ñù£©¡£
Parcel»á½«ËùÓÐдÈëµÄÊý¾Ý½øÐдò°ü£¬Parcel±¾Éí¿ÉÒÔ×÷Ϊһ¸öÕûÌåÔÚ½ø³Ì¼ä´«µÝ¡£½ÓÊÕ·½ÔÚÊÕµ½ParcelÖ®ºó£¬Ö»Òª°´Ð´ÈëͬÑùµÄ˳Ðò¶Á³ö¼´¿É¡£
Õâ¸ö¹ý³Ì£¬ºÍÎÒÃÇÏÖʵÉú»îÖмÄËͰü¹ü×ö·¨ÊÇÒ»ÑùµÄ£ºÎÒÃǽ«ÐèÒª¼ÄË͵İü¹ü·Åµ½Ó²Ö½ºÐÖн»¸ø¿ìµÝ¹«Ë¾¡£¿ìµÝ¹«Ë¾½«ËùÓеİü¹ü½øÐдò°ü£¬È»ºó¼¯Öзŵ½ÔËÊä³µÖÐË͵½Ä¿µÄµØ£¬µ½ÁËÄ¿µÄµØÖ®ºóÈ»ºóÔÙ½øÐвð·Ö¡£
Parcel¼È°üº¬C++²¿·ÖµÄʵÏÖ£¬Ò²Í¬Ê±ÌṩÁËJavaµÄ½Ó¿Ú£¬Öмäͨ¹ýJNIÏνӡ£Java²ãµÄ½Ó¿ÚÆäʵ½ö½öÊÇÒ»²ã°ü×°£¬ÕæÕýµÄʵÏÖ¶¼ÊÇλÓÚC++²¿·ÖÖУ¬ËüÃǵĹØÏµÈçÏÂͼËùʾ£º

ÌØ±ðÐèҪ˵Ã÷һϵÄÊÇ£¬ParcelÀà³ýÁË¿ÉÒÔ´«µÝ»ù±¾Êý¾ÝÀàÐÍ£¬»¹¿ÉÒÔ´«µÝBinder¶ÔÏó£º
status_t Parcel::writeStrongBinder(const sp<IBinder>& val){ return flatten_binder(ProcessState::self(), val, this); }
|
Õâ¸ö·½·¨Ð´ÈëµÄÊÇsp<IBinder>ÀàÐ͵ĶÔÏ󣬶øIBinder¼È¿ÉÄÜÊDZ¾µØBinder£¬Ò²¿ÉÄÜÊÇÔ¶³ÌBinder£¬ÕâÑùÎÒÃǾͲ»¿ÉÒÔ²»ÓùØÐľßÌåϸ½ÚÖ±½Ó½øÐÐBinder¶ÔÏóµÄ´«µÝ¡£
ÕâÒ²ÊÇΪʲôIInterfaceÖж¨ÒåÁËÁ½¸öasBinderµÄstatic·½·¨£¬Èç¹ûÄã²»¼ÇµÃÁË£¬Çë»ØÒäÒ»ÏÂÕâÁ½¸ö·½·¨£º
static sp<IBinder> asBinder(const IInterface*); static sp<IBinder> asBinder(const sp<IInterface>&);
|
¶ø¶ÔÓÚBinderÇý¶¯£¬ÎÒÃÇÇ°ÃæÒѾ½²½â¹ý£ºBinderÇý¶¯²¢²»ÊÇÕæµÄ½«¶ÔÏóÔÚ½ø³Ì¼äÐòÁл¯´«µÝ£¬¶øÊÇÓÉBinderÇý¶¯Íê³ÉÁ˶ÔÓÚBinder¶ÔÏóÖ¸ÕëµÄ½âÊͺͷÒ룬ʹµ÷ÓÃÕß¿´ÆðÀ´¾ÍÏñÔÚ½ø³Ì¼ä´«µÝ¶ÔÏóÒ»Ñù¡£
Framework²ãµÄÏ̹߳ÜÀí
ÔÚ½²½âBinderÇý¶¯µÄʱºò£¬ÎÒÃǾͽ²½â¹ýÇý¶¯ÖжÔÓ¦Ï̵߳ĹÜÀí¡£ÕâÀïÎÒÃÇÔÙÀ´¿´¿´£¬Framework²ãÊÇÈçºÎÓëÇý¶¯²ã¶Ô½Ó½øÐÐÏ̹߳ÜÀíµÄ¡£
ProcessState::setThreadPoolMaxThreadCount ·½·¨ÖУ¬»áͨ¹ýBINDER_SET_MAX_THREADSÃüÁîÉèÖýø³ÌÖ§³ÖµÄ×î´óÏß³ÌÊýÁ¿£º
#define DEFAULT_MAX_BINDER_THREADS 15
status_t ProcessState::setThreadPoolMaxThreadCount(size_t
maxThreads) {
status_t result = NO_ERROR;
if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads)
!= -1) {
mMaxThreads = maxThreads;
} else {
result = -errno;
ALOGE("Binder ioctl to set max threads failed:
%s", strerror(-result));
}
return result;
}
|
ÓÉ´ËÇý¶¯±ãÖªµÀÁ˸ÃBinder·þÎñÖ§³ÖµÄ×î´óÏß³ÌÊý¡£Çý¶¯ÔÚÔËÐйý³ÌÖУ¬»á¸ù¾ÝÐèÒª£¬²¢ÔÚûÓг¬¹ýÉÏÏÞµÄÇé¿öÏ£¬Í¨¹ýBR_SPAWN_LOOPERÃüÁî֪ͨ½ø³Ì´´½¨Ị̈߳º
IPCThreadStateÔÚÊÕµ½BR_SPAWN_LOOPERÇëÇóÖ®ºó£¬±ã»áµ÷ÓÃProcessState::spawnPooledThreadÀ´´´½¨Ị̈߳º
status_t IPCThreadState::executeCommand(int32_t cmd) { ... case BR_SPAWN_LOOPER: mProcess->spawnPooledThread(false); break; ... }
|
Ïß³ÌÔÚrunÖ®ºó£¬»áµ÷ÓÃthreadLoop½«×ÔÉíÌí¼ÓµÄÏ̳߳ØÖУº
virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain); return false; }
|
¶øIPCThreadState::joinThreadPool·½·¨ÖУ¬»á¸ù¾Ýµ±Ç°Ïß³ÌÊÇ·ñÊÇÖ÷Ï̷߳¢ËÍBC_ENTER_LOOPER»òÕßBC_REGISTER_LOOPERÃüÁî¸æÖªÇý¶¯Ïß³ÌÒѾ´´½¨Íê±Ï¡£Õû¸öµ÷ÓÃÁ÷³ÌÈçÏÂͼËùʾ£º

C++ Binder·þÎñ¾ÙÀý
µ¥´¿µÄÀíÂÛ֪ʶҲÐí²¢²»ÄÜÈÃÎÒÃǷdz£ºÃµÄÀí½â£¬ÏÂÃæÎÒÃÇÒÔÒ»¸ö¾ßÌåµÄBinder·þÎñÀý×ÓÀ´½áºÏÉÏÎĵÄ֪ʶ½øÐн²½â¡£
ÏÂÃæÒÔPowerManagerΪÀý£¬À´¿´¿´C++µÄBinder·þÎñÊÇÈçºÎʵÏֵġ£
ÏÂͼÊÇPowerManager C++²¿·ÖµÄʵÏÖÀàͼ£¨PowerManagerÒ²ÓÐJava²ãµÄ½Ó¿Ú£¬µ«ÎÒÃÇÕâÀï¾Í²»ÌÖÂÛÁË£©¡£

ͼÖÐBinder FrameworkÖеÄÀàÎÒÃÇÔÚÉÏÎÄÖÐÒѾ½éÉܹýÁË£¬¶øPowerManagerÏà¹ØµÄËĸöÀ࣬±ãÊÇÔÚFrameworkµÄ»ù´¡ÉÏ¿ª·¢µÄ¡£
IPowerManager¶¨ÒåÁËPowerManagerËùÓжÔÍâÌṩµÄ¹¦Äܽӿڣ¬Æä×ÓÀà¶¼¼Ì³ÐÁËÕâЩ½Ó¿Ú¡£
BpPowerManagerÊÇÌṩ¸ø¿Í»§¶Ëµ÷ÓõÄÔ¶³Ì½Ó¿Ú
BnPowerManagerÖÐÖ»ÓÐÒ»¸öonTransact·½·¨£¬¸Ã·½·¨¸ù¾ÝÇëÇóµÄcodeÀ´¶Ô½Óÿ¸öÇëÇ󣬲¢Ö±½Óµ÷ÓÃPowerManagerÖжÔÓ¦µÄ·½·¨
PowerManagerÊÇ·þÎñÕæÕýµÄʵÏÖ
ÔÚIPowerManager.hÖУ¬Í¨¹ýDECLARE_META_INTERFACE(PowerManager);ÉùÃ÷һЩBinder±ØÒªµÄ×é¼þ¡£ÔÚIPowerManager.cppÖУ¬Í¨¹ýIMPLEMENT_META_INTERFACE(PowerManager,
"android.os.IPowerManager");ºêÀ´½øÐÐʵÏÖ¡£
±¾µØÊµÏÖ£ºNative¶Ë
·þÎñµÄ±¾µØÊµÏÖÖ÷Òª¾ÍÊÇʵÏÖBnPowerManagerºÍPowerManagerÁ½¸öÀ࣬PowerManagerÊÇBnPowerManagerµÄ×ÓÀ࣬Òò´ËÔÚBnPowerManagerÖе÷ÓÃ×ÔÉíµÄvirtual·½·¨Æäʵ¶¼ÊÇÔÚ×ÓÀàPowerManagerÀàÖÐʵÏֵġ£
BnPowerManagerÀàÒª×öµÄ¾ÍÊǸ´Ð´onTransact·½·¨£¬Õâ¸ö·½·¨µÄÖ°ÔðÊÇ£º¸ù¾ÝÇëÇóµÄcodeÇø·Ö¾ßÌåµ÷ÓõÄÊÇÄǸö½Ó¿Ú£¬È»ºó°´Ë³Ðò´ÓParcelÖжÁ³ö´ò°üºÃµÄ²ÎÊý£¬½Ó×ŵ÷ÓÃÁô´ý×ÓÀàʵÏÖµÄÐ麯Êý¡£ÐèҪעÒâµÄÊÇ£ºÕâÀï´ÓParcel¶Á³ö²ÎÊýµÄ˳ÐòÐèÒªºÍBpPowerManagerÖÐдÈëµÄ˳ÐòÍêȫһÖ£¬·ñÔò¶Á³öµÄÊý¾Ý½«ÊÇÎÞЧµÄ¡£
µçÔ´·þÎñ°üº¬Á˺ü¸¸ö½Ó¿Ú¡£ËäȻÿ¸ö½Ó¿ÚµÄʵÏÖÂß¼¸÷²»Ò»Ñù£¬µ«´ÓBinder¿ò¼ÜµÄ½Ç¶ÈÀ´¿´£¬ËüÃǵÄʵÏֽṹÊÇÒ»Ñù¡£¶øÕâÀïÎÒÃDz¢²»¹ØÐĵçÔ´·þÎñµÄʵÏÖϸ½Ú£¬Òò´ËÎÒÃÇÈ¡ÆäÖÐÒ»¸ö·½·¨¿´ÆäʵÏÖ·½Ê½¼´¿É¡£
Ê×ÏÈÎÒÃÇÀ´¿´Ò»ÏÂBnPowerManager::onTransactÖеĴúÂëÆ¬¶Î£º
status_t BnPowerManager::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { ... case IPowerManager::REBOOT: { CHECK_INTERFACE(IPowerManager, data, reply); bool confirm = data.readInt32(); String16 reason = data.readString16(); bool wait = data.readInt32(); return reboot(confirm, reason, wait); } ... } }
|
Õâ¶Î´úÂëÖÐÎÒÃÇ¿´µ½ÁËʵÏÖÖÐÊÇÈçºÎ¸ù¾ÝcodeÇø·Ö½Ó¿Ú£¬²¢Í¨¹ýParcel¶Á³öµ÷ÓòÎÊý£¬È»ºóµ÷ÓþßÌå·þÎñ·½µÄ¡£
¶øPowerManagerÕâ¸öÀà²ÅÕæÕýÊÇ·þÎñʵÏֵı¾Ì壬reboot·½·¨ÕæÕýʵÏÖÁËÖØÆôµÄÂß¼£º
status_t PowerManager::reboot(bool confirm, const String16& reason, bool wait) { const std::string reason_str(String8(reason).string()); if (!(reason_str.empty() || reason_str == kRebootReasonRecovery)) { LOG(WARNING) << "Ignoring reboot request with invalid reason \"" << reason_str << "\""; return BAD_VALUE; }
LOG(INFO) << "Rebooting with reason
\"" << reason_str << "\"";
if (!property_setter_->SetProperty(ANDROID_RB_PROPERTY,
kRebootPrefix + reason_str)) {
return UNKNOWN_ERROR;
}
return OK;
}
|
ͨ¹ýÕâÑù½á¹¹µÄÉè¼Æ£¬½«¿ò¼ÜÏà¹ØµÄÂß¼£¨BnPowerManagerÖеÄʵÏÖ£©ºÍÒµÎñ±¾ÉíµÄÂß¼£¨PowerManagerÖеÄʵÏÖ£©³¹µ×·ÖÀ뿪ÁË£¬±£Ö¤Ã¿Ò»¸öÀà¶¼·Ç³£µÄ¡°¸É¾»¡±£¬ÕâÒ»µãÊǺÜÖµµÃÎÒÃÇÔÚ×öÈí¼þÉè¼ÆÊ±Ñ§Ï°µÄ¡£
·þÎñµÄ·¢²¼
·þÎñʵÏÖÍê³ÉÖ®ºó£¬²¢²»ÊÇÁ¢¼´¾ÍÄÜÈñðÈËʹÓõġ£ÉÏÎÄÖУ¬ÎÒÃǾÍ˵µ½¹ý£ºËùÓÐÔÚBinderÉÏ·¢²¼µÄ·þÎñ±ØÐëҪע²áµ½ServiceManagerÖвÅÄܱ»ÆäËûÄ£¿é»ñÈ¡ºÍʹÓ᣶øÔÚBinderServiceÀàÖУ¬ÌṩÁËpublishAndJoinThreadPool·½·¨À´¼ò»¯·þÎñµÄ·¢²¼£¬Æä´úÂëÈçÏ£º
static void publishAndJoinThreadPool(bool allowIsolated = false) { publish(allowIsolated); joinThreadPool(); }
static status_t publish(bool allowIsolated =
false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
...
static void joinThreadPool() {
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
IPCThreadState::self()->joinThreadPool();
} |
Óɴ˿ɼû£¬Binder·þÎñµÄ·¢²¼ÆäʵÓÐÈý¸ö²½Ö裺
1.ͨ¹ýIServiceManager::addServiceÔÚServiceManagerÖнøÐзþÎñµÄ×¢²á
2.ͨ¹ýProcessState::startThreadPoolÆô¶¯Ï̳߳Ø
3.ͨ¹ýIPCThreadState::joinThreadPool½«Ö÷Ï̼߳ÓÈëµÄBinderÖÐ
Ô¶³Ì½Ó¿Ú£ºProxy¶Ë
ProxyÀàÊǹ©¿Í»§¶ËʹÓõġ£BpPowerManagerÐèҪʵÏÖIPowerManagerÖеÄËùÓнӿڡ£
ÎÒÃÇ»¹ÊÇÒÔÉÏÎÄÌáµ½µÄreboot½Ó¿ÚΪÀý£¬À´¿´¿´BpPowerManager::reboot·½·¨ÊÇÈçºÎʵÏֵģº
virtual status_t reboot(bool confirm, const String16& reason, bool wait) { Parcel data, reply; data.writeInterfaceToken(IPowerManager::getInterfaceDescriptor()); data.writeInt32(confirm); data.writeString16(reason); data.writeInt32(wait); return remote()->transact(REBOOT, data, &reply, 0); }
|
Õâ¶Î´úÂëºÜ¼òµ¥£¬Âß¼¾ÍÊÇ£ºÍ¨¹ýParcelдÈëµ÷ÓòÎÊý½øÐдò°ü£¬È»ºóµ÷ÓÃremote()->transact½«ÇëÇó·¢ËͳöÈ¥¡£
ÆäʵBpPowerManagerÖÐÆäËû·½·¨£¬ÉõÖÁËùÓÐÆäËûBpXXXÖÐËùÓеķ½·¨£¬ÊµÏÖ¶¼ÊǺÍÕâ¸ö·½·¨Ò»ÑùµÄÌ×·¡£¾ÍÊÇ£ºÍ¨¹ýParcel´ò°üÊý¾Ý£¬Í¨¹ýremote()->transact·¢ËÍÊý¾Ý¡£¶øÕâÀïµÄremote()·µ»ØµÄÆäʵ¾ÍÊÇBpBinder¶ÔÏó£¬Óɴ˾ÓÉIPCThreadState½«Êý¾Ý·¢Ë͵½ÁËÇý¶¯²ã¡£Èç¹ûÄãÒѾ²»¼ÇµÃ£¬ÇëÖØÐ¿´Ò»ÏÂÏÂÃæÕâ·ùͼ£º

ÁíÍ⣬ÐèҪһϵÄÊÇ£¬ÕâÀïµÄREBOOT¾ÍÊÇÇëÇóµÄcode£¬¶øÕâ¸öcodeÊÇÔÚIPowerManagerÖж¨ÒåºÃµÄ£¬ÕâÑù×ÓÀà¿ÉÒÔÖ±½ÓʹÓ㬲¢±£Ö¤ÊÇÒ»Öµģº
enum { ACQUIRE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION, ACQUIRE_WAKE_LOCK_UID = IBinder::FIRST_CALL_TRANSACTION + 1, RELEASE_WAKE_LOCK = IBinder::FIRST_CALL_TRANSACTION + 2, UPDATE_WAKE_LOCK_UIDS = IBinder::FIRST_CALL_TRANSACTION + 3, POWER_HINT = IBinder::FIRST_CALL_TRANSACTION + 4, UPDATE_WAKE_LOCK_SOURCE = IBinder::FIRST_CALL_TRANSACTION + 5, IS_WAKE_LOCK_LEVEL_SUPPORTED = IBinder::FIRST_CALL_TRANSACTION + 6, USER_ACTIVITY = IBinder::FIRST_CALL_TRANSACTION + 7, WAKE_UP = IBinder::FIRST_CALL_TRANSACTION + 8, GO_TO_SLEEP = IBinder::FIRST_CALL_TRANSACTION + 9, NAP = IBinder::FIRST_CALL_TRANSACTION + 10, IS_INTERACTIVE = IBinder::FIRST_CALL_TRANSACTION + 11, IS_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 12, SET_POWER_SAVE_MODE = IBinder::FIRST_CALL_TRANSACTION + 13, REBOOT = IBinder::FIRST_CALL_TRANSACTION + 14, SHUTDOWN = IBinder::FIRST_CALL_TRANSACTION + 15, CRASH = IBinder::FIRST_CALL_TRANSACTION + 16, };
|
·þÎñµÄ»ñÈ¡
ÔÚ·þÎñÒѾ·¢²¼Ö®ºó£¬¿Í»§¶Ë¸ÃÈçºÎ»ñÈ¡Æä·þÎñ½Ó¿ÚÈ»ºó¶ÔÆä·¢³öÇëÇóµ÷ÓÃÄØ£¿
ºÜÏÔÈ»£¬¿Í»§¶ËÓ¦¸Ãͨ¹ýBpPowerManagerµÄ¶ÔÏóÀ´ÇëÇóÆä·þÎñ¡£µ«¿´Ò»ÑÛBpPowerManagerµÄ¹¹Ô캯Êý£¬ÎÒÃǻᷢÏÖ£¬Ëƺõû·¨Ö±½Ó´´½¨Ò»¸öÕâÀàµÄ¶ÔÏó£¬ÒòΪÕâÀïÐèÒªÒ»¸ösp<IBinder>ÀàÐ͵IJÎÊý¡£
BpPowerManager(const sp<IBinder>& impl) : BpInterface<IPowerManager>(impl) { }
|
ÄÇôÕâ¸ösp<IBinder>²ÎÊýÎÒÃǸôÓÄÄÀï»ñÈ¡ÄØ£¿
»ØÒäÒ»ÏÂÇ°ÃæµÄÄÚÈÝ£ºProxyÆäʵÊǰüº¬ÁËÒ»¸öÖ¸ÏòServerµÄ¾ä±ú£¬ËùÓеÄÇëÇó·¢ËͳöÈ¥µÄʱºò¶¼ÐèÒª°üº¬Õâ¸ö¾ä±ú×÷Ϊһ¸ö±êʶ¡£¶øÏëÒªÄõ½Õâ¸ö¾ä±ú£¬ÎÒÃÇ×ÔȻӦµ±Ïëµ½ServiceManager¡£ÎÒÃÇÔÙ¿´Ò»ÏÂServiceManagerµÄ½Ó¿Ú×ÔÈ»¾ÍÖªµÀÕâ¸ösp<IBinder>¸ÃÈçºÎ»ñÈ¡ÁË£º
/** * Retrieve an existing service, blocking for a few seconds * if it doesn't yet exist. */ virtual sp<IBinder> getService( const String16& name) const = 0;
/**
* Retrieve an existing service, non-blocking.
*/
virtual sp<IBinder> checkService( const
String16& name) const = 0;
|
ÕâÀïµÄÁ½¸ö·½·¨¶¼¿ÉÒÔ»ñÈ¡·þÎñ¶ÔÓ¦µÄsp<IBinder>¶ÔÏó£¬Ò»¸öÊÇ×èÈûʽµÄ£¬ÁíÍâÒ»¸ö²»ÊÇ¡£´«µÝµÄ²ÎÊýÊÇÒ»¸ö×Ö·û´®£¬Õâ¸ö¾ÍÊÇ·þÎñÔÚaddServerʱ¶ÔÓ¦µÄ×Ö·û´®£¬¶ø¶ÔÓÚPowerManagerÀ´Ëµ£¬Õâ¸ö×Ö·û´®¾ÍÊÇ¡±power¡±¡£Òò´Ë£¬ÎÒÃÇ¿ÉÒÔͨ¹ýÏÂÃæÕâÐдúÂë´´½¨³öBpPowerManagerµÄ¶ÔÏó¡£
sp<IBinder> bs = defaultServiceManager()->checkService(serviceName); sp<IPowerManager> pm = new BpPowerManager(bs);
|
µ«ÕâÑù×ö»¹»á´æÔÚÒ»¸öÎÊÌ⣺BpPowerManagerÖеķ½·¨µ÷ÓÃÊǾÓÉÇý¶¯È»ºó¿ç½ø³Ìµ÷Óõġ£Í¨³£Çé¿öÏ£¬µ±ÎÒÃǵĿͻ§¶ËÓëPowerManager·þÎñËùÔڵĽø³Ì²»ÊÇͬһ¸ö½ø³ÌµÄʱºò£¬ÕâÑùµ÷ÓÃÊÇûÓÐÎÊÌâµÄ¡£ÄǼÙÉèÎÒÃǵĿͻ§¶ËÓָպúÍPowerManager·þÎñÔÚͬһ¸ö½ø³Ì¸ÃÈçºÎ´¦ÀíÄØ£¿
Õë¶ÔÕâ¸öÎÊÌ⣬Binder FrameworkÌṩµÄ½â¾ö·½·¨ÊÇ£ºÍ¨¹ýinterface_castÕâ¸ö·½·¨À´»ñÈ¡·þÎñµÄ½Ó¿Ú¶ÔÏó£¬ÓÉÕâ¸ö·½·¨±¾Éí¸ù¾ÝÊÇ·ñÊÇÔÚͬһ¸ö½ø³Ì£¬À´×Ô¶¯È·¶¨·µ»ØÒ»¸ö±¾µØBinder»¹ÊÇÔ¶³ÌBinder¡£interface_castÊÇÒ»¸öÄ£°å·½·¨£¬ÆäÔ´ÂëÈçÏ£º
template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
|
µ÷ÓÃÕâ¸ö·½·¨µÄʱºòÎÒÃÇÐèÒªÖ¸¶¨Binder·þÎñµÄIInterface£¬Òò´Ë¶ÔÓÚPowerManager£¬ÎÒÃÇÐèÒªÕâÑù»ñÈ¡ÆäBinder½Ó¿Ú¶ÔÏó£º
const String16 serviceName("power"); sp<IBinder> bs = defaultServiceManager()->checkService(serviceName); if (bs == NULL) { return NAME_NOT_FOUND; } sp<IPowerManager> pm = interface_cast<IPowerManager>(bs);
|
ÎÒÃÇÔÙ»ØÍ·¿´Ò»ÏÂinterface_castÕâ¸ö·½·¨Ì壬ÕâÀïÊÇÔÚµ÷ÓÃINTERFACE::asInterface(obj)£¬¶ø¶ÔÓÚIPowerManagerÀ´Ëµ£¬Æäʵ¾ÍÊÇIPowerManager::asInterface(obj)¡£ÄÇôIPowerManager::asInterfaceÕâ¸ö·½·¨ÊÇÄÄÀﶨÒåµÄÄØ£¿
Õâ¸öÕýÊÇÉÏÎÄÌáµ½µÄDECLARE_META_INTERFACEºÍIMPLEMENT_META_INTERFACEÁ½¸öºêËùÆðµÄ×÷Óá£IMPLEMENT_META_INTERFACEºê°üº¬ÁËÏÂÃæÕâ¶Î´úÂ룺
android::sp<I##INTERFACE>
I##INTERFACE::asInterface(
const android::sp<android::IBinder>&
obj)
{
android::sp<I##INTERFACE>
intr;
if (obj != NULL) {
intr = static_cast<I##INTERFACE*>(
obj->queryLocalInterface(
I##INTERFACE::descriptor).get());
if (intr == NULL) {
intr = new Bp##INTERFACE(obj);
}
}
return intr;
}
|
ÕâÀïÎÒÃǽ«¡°##INTERFACE¡±Í¨¹ý¡°PowerManager¡±´úÌæ£¬µÃµ½µÄ½á¹û¾ÍÊÇ£º
android::sp<IPowerManager> IPowerManager::asInterface( const android::sp<android::IBinder>& obj) { android::sp<IPowerManager> intr; if (obj != NULL) { intr = static_cast<IPowerManager*>( obj->queryLocalInterface( IPowerManager::descriptor).get()); if (intr == NULL) { intr = new BpPowerManager(obj); } } return intr; }
|
Õâ¸ö±ãÊÇIPowerManager::asInterface·½·¨µÄʵÏÖ£¬Õâ¶ÎÂß¼µÄº¬Òå¾ÍÊÇ£º
Ïȳ¢ÊÔͨ¹ýqueryLocalInterface¿´¿´Äܹ»»ñµÃ±¾µØBinder£¬Èç¹ûÊÇÔÚ·þÎñËùÔÚ½ø³Ìµ÷Óã¬×ÔÈ»ÄÜ»ñÈ¡±¾µØBinder£¬·ñÔò½«·µ»ØNULL
Èç¹û»ñÈ¡²»µ½±¾µØBinder£¬Ôò´´½¨²¢·µ»ØÒ»¸öÔ¶³ÌBinder¡£
Óɴ˱£Ö¤ÁË£ºÎÒÃÇÔÚ½ø³ÌÄÚ²¿µÄµ÷Óã¬ÊÇÖ±½Óͨ¹ý·½·¨µ÷ÓõÄÐÎʽ¡£¶ø²»ÔÚͬһ¸ö½ø³ÌµÄʱºò£¬²Åͨ¹ýBinder½øÐÐ¿ç½ø³ÌµÄµ÷Óá£
C++²ãµÄServiceManager
ǰÎÄÒѾÁ½´Î½éÉܹýServiceManagerÁË£¬ÎÒÃÇÖªµÀÕâ¸öÄ£¿é¸ºÔðÁËËùÓÐBinder·þÎñµÄ¹ÜÀí£¬²¢ÇÒÒ²¿´µ½ÁËBinderÇý¶¯ÖжÔÓÚÕâ¸öÄ£¿éµÄʵÏÖ¡£¿ÉÒÔ˵ServiceManagerÊÇÕû¸öBinder
IPCµÄ¿ØÖÆÖÐÐĺͽ»Í¨ÊàŦ¡£ÕâÀïÎÒÃǾÍÀ´¿´Ò»ÏÂÕâ¸öÄ£¿éµÄ¾ßÌåʵÏÖ¡£
ServiceManagerÊÇÒ»¸ö¶ÀÁ¢µÄ¿ÉÖ´ÐÐÎļþ£¬ÔÚÉ豸ÖеĽø³ÌÃû³ÆÊÇ/system/bin/servicemanager£¬Õâ¸öÒ²ÊÇÆä¿ÉÖ´ÐÐÎļþµÄ·¾¶¡£
ServiceManagerʵÏÖÔ´ÂëµÄλÓÚÕâ¸ö·¾¶£ºframeworks/native/cmds/servicemanager/£¬Æämainº¯ÊýµÄÖ÷ÒªÄÚÈÝÈçÏ£º
int main() { struct binder_state *bs;
bs = binder_open(128*1024);
if (!bs) {
ALOGE("failed to open binder driver\n");
return -1;
}
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n",
strerror(errno));
return -1;
}
...
binder_loop(bs, svcmgr_handler);
return 0;
} |
Õâ¶Î´úÂëºÜ¼òµ¥£¬Ö÷Òª×öÁËÈý¼þÊÂÇ飺
binder_open(128*1024); ÊÇ´ò¿ªBinder£¬²¢Ö¸¶¨»º´æ´óСΪ128k£¬ÓÉÓÚServiceManagerÌṩµÄ½Ó¿ÚºÜ¼òµ¥£¨ÏÂÎĻὲµ½£©£¬Òò´Ë²¢²»ÐèÒªÆÕͨ½ø³ÌÄÇô¶à£¨1M
¨C 8K£©µÄ»º´æ
binder_become_context_manager(bs) ʹ×Ô¼º³ÉΪContext Manager¡£ÕâÀïµÄContext
ManagerÊÇBinderÇý¶¯ÀïÃæµÄÃû³Æ£¬µÈͬÓÚServiceManager¡£binder_become_context_managerµÄ·½·¨ÊµÏÖÖ»ÓÐÒ»ÐдúÂ룺ioctl(bs->fd,
BINDER_SET_CONTEXT_MGR, 0); ¿´¹ýBinderÇý¶¯²¿·Ö½âÎöµÄÄÚÈÝ£¬ÕâÐдúÂëÓ¦¸ÃºÜÈÝÒ×Àí½âÁË
binder_loop(bs, svcmgr_handler); ÊÇÔÚLooperÉÏÑ»·£¬µÈ´ýÆäËûÄ£¿éÇëÇó·þÎñ
service_manager.cÖеÄʵÏÖÓëÆÕͨBinder·þÎñµÄʵÏÖÓÐЩ²»Ò»Ñù£º²¢Ã»ÓÐͨ¹ý¼Ì³Ð½Ó¿ÚÀàÀ´ÊµÏÖ£¬¶øÊÇͨ¹ý¼¸¸öcÓïÑԵĺ¯ÊýÀ´Íê³ÉÁËʵÏÖ¡£Õâ¸öÎļþÖеÄÖ÷Òª·½·¨ÈçÏ£º

ServiceManagerÖУ¬Í¨¹ýsvcinfo½á¹¹ÌåÀ´ÃèÊöÒѾע²áµÄBinder·þÎñ£º
struct svcinfo { struct svcinfo *next; uint32_t handle; struct binder_death death; int allow_isolated; size_t len; uint16_t name[0]; };
|
nextÊÇÒ»¸öÖ¸Õ룬ָÏòÏÂÒ»¸ö·þÎñ£¬Í¨¹ýÕâ¸öÖ¸Õ뽫ËùÓзþÎñ´®³ÉÁËÁ´±í¡£handleÊÇÖ¸ÏòBinder·þÎñµÄ¾ä±ú£¬Õâ¸ö¾ä±úÊÇÓÉBinderÇý¶¯·Ò룬ָÏòÁËBinder·þÎñµÄʵÌ壨²Î¼ûÇý¶¯ÖУºBinderÖеġ°ÃæÏò¶ÔÏó¡±£©£¬nameÊÇ·þÎñµÄÃû³Æ¡£
ServiceManagerµÄʵÏÖÂß¼²¢²»¸´ÔÓ£¬Õâ¸öÄ£¿é¾ÍºÃÏñÔÚÕû¸öϵͳÉÏÌṩÁËÒ»¸öÈ«¾ÖµÄHashMap¶øÒÑ£ºÍ¨¹ý·þÎñÃû³Æ½øÐзþÎñ×¢²á£¬È»ºóÔÙͨ¹ý·þÎñÃû³ÆÀ´²éÕÒ¡£¶øÕæÕý¸´ÔÓµÄÂß¼Æäʵ¶¼ÊÇÔÚBinderÇý¶¯ÖÐʵÏÖÁË¡£
ServiceManagerµÄ½Ó¿Ú
Ô´Âë·¾¶£º
frameworks/native/include/binder/IServiceManager.h frameworks/native/libs/binder/IServiceManager.cpp
|
ServiceManagerµÄC++½Ó¿Ú¶¨ÒåÈçÏ£º
class IServiceManager : public IInterface { public: DECLARE_META_INTERFACE(ServiceManager);
virtual sp<IBinder> getService( const
String16& name) const = 0;
virtual sp<IBinder> checkService( const
String16& name) const = 0;
virtual status_t addService( const String16&
name,
const sp<IBinder>& service,
bool allowIsolated = false) = 0;
virtual Vector<String16> listServices()
= 0;
enum {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,
LIST_SERVICES_TRANSACTION,
};
}; |
ÕâÀïÎÒÃÇ¿´µ½£¬ServiceManagerÌṩµÄ½Ó¿ÚÖ»ÓÐËĸö£¬ÕâËĸö½Ó¿Ú˵Ã÷ÈçÏ£º

ÕâÆäÖУ¬×îºóÒ»¸ö½Ó¿ÚÊÇΪÁ˵÷ÊÔ¶øÌṩµÄ¡£Í¨¹ýadb shellÁ¬½Óµ½É豸ÉÏÖ®ºó£¬¿ÉÒÔͨ¹ýÊäÈëservice
list Êä³öËùÓÐ×¢²áµÄ·þÎñÁÐ±í¡£ÕâÀservice¡±¿ÉÖ´ÐÐÎļþÆäʵ¾ÍÊÇͨ¹ýµ÷ÓÃlistServices½Ó¿Ú»ñÈ¡µ½·þÎñÁбíµÄ¡£
serviceÃüÁîµÄÔ´Âë·¾¶ÔÚÕâÀframeworks/native/cmds/service
service listµÄÊä³ö¿´ÆðÀ´ÏñÏÂÃæÕâÑù(Ò»´ÎÊä³ö¿ÉÄÜÓÐÒ»°Ù¶à¸ö·þÎñ£¬ÕâÀïÊ¡ÂÔÁË)£º
255|angler:/ # service list Found 125 services: 0 sip: [android.net.sip.ISipService] 1 nfc: [android.nfc.INfcAdapter] 2 carrier_config: [com.android.internal.telephony.ICarrierConfigLoader] 3 phone: [com.android.internal.telephony.ITelephony] 4 isms: [com.android.internal.telephony.ISms] 5 iphonesubinfo: [com.android.internal.telephony.IPhoneSubInfo] 6 simphonebook: [com.android.internal.telephony.IIccPhoneBook] 7 telecom: [com.android.internal.telecom.ITelecomService] 8 isub: [com.android.internal.telephony.ISub] 9 contexthub_service: [android.hardware.location.IContextHubService] 10 dns_listener: [android.net.metrics.IDnsEventListener] 11 connmetrics: [android.net.IIpConnectivityMetrics] 12 connectivity_metrics_logger: [android.net.IConnectivityMetricsLogger] 13 bluetooth_manager: [android.bluetooth.IBluetoothManager] 14 imms: [com.android.internal.telephony.IMms] 15 media_projection: [android.media.projection.IMediaProjectionManager] 16 launcherapps: [android.content.pm.ILauncherApps] 17 shortcut: [android.content.pm.IShortcutService] 18 fingerprint: [android.hardware.fingerprint.IFingerprintService] 19 trust: [android.app.trust.ITrustManager] 20 media_router: [android.media.IMediaRouterService] ...
|
ÆÕͨµÄBinder·þÎñÎÒÃÇÐèҪͨ¹ýServiceManagerÀ´»ñÈ¡½Ó¿Ú²ÅÄܵ÷Óã¬ÄÇôServiceManagerµÄ½Ó¿ÚÓÐÈçºÎ»ñµÃÄØ£¿ÔÚlibbinderÖУ¬ÌṩÁËÒ»¸ödefaultServiceManager·½·¨À´»ñÈ¡ServiceManagerµÄProxy£¬²¢ÇÒÕâ¸ö·½·¨²»ÐèÒª´«Èë²ÎÊý¡£ÔÒòÎÒÃÇÔÚÇý¶¯ÆªÖÐÒ²ÒѾ½²¹ýÁË£ºBinderµÄʵÏÖÖУ¬ÎªServiceManagerÁôÁËÒ»¸öÌØÊâµÄλÖ㬲»ÐèÒªÏñÆÕͨ·þÎñÄÇÑùͨ¹ý±êʶȥ²éÕÒ¡£defaultServiceManager´úÂëÈçÏ£º
sp<IServiceManager> defaultServiceManager() { if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
} |
½áÊøÓï
±¾ÎÄÎÒÃÇÏêϸ½²½âÁËBinder Framework C++²ãµÄʵÏÖ¡£
µ«¶ÔÓÚAndroid App¿ª·¢ÕßÀ´Ëµ£¬¾ø´ó²¿·ÖÇé¿ö϶¼ÊÇÔÚÓÃJavaÓïÑÔ¿ª·¢¡£ÄÇô£¬ÔÚÏÂһƪÎÄÕÂÖУ¬ÎÒ¾ÍÀ´Ïêϸ½²½âBinder
Framework Java²ãµÄʵÏÖ¡£²¢ÇÒÒ²»á½²½âAIDLÓëBinderµÄ¹ØÏµ£¬¾´ÇëÆÚ´ý¡£
|