Mel*_*lon 28 performance android aidl android-intent telephonymanager
我看到一些SO帖子讨论了如何以程序方式结束电话,例如,这个.是的,人们专注于结果,但没有人真正解释它为什么起作用的原因?
我尝试了代码,效果很好.但是我想了解更多关于底下发生的事情的细节?为什么通过创建ITelephony.aidl,ITelephony我们的项目中暴露了android隐藏的内部接口?我们如何创建ITelephony.aidl和自动生成的java(/gen/ITelephony.java)链接到 android的ITelephony界面?是否只是因为名称匹配(包名和援助文件名)?
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
//Why does the android internal ITelephony interface is exposed after created the ITelephony.aidl?
com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm);
telephonyService.endCall();
Run Code Online (Sandbox Code Playgroud)
Dav*_*ser 81
实际上,添加ITelephony.aidl到您的项目是没有必要的,这只是一个方便.你也可以这样做:
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); // Get its class
m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
m.setAccessible(true); // Make it accessible
m.invoke(telephonyService); // invoke endCall()
Run Code Online (Sandbox Code Playgroud)
在幕后,这一切都使用Java反射来访问私有(即:未公开记录)的方法.通过阅读开源(即:公开可用的)Android源代码,您可以找出哪些方法及其功能.一旦你知道它是什么以及它做了什么,你就可以使用反射来实现它,即使它是"隐藏的".
的TelephonyManager类是使用远程服务中实现.如果您想要请求TelephonyManager为您做某事,您可以调用一个方法TelephonyManager(这是公开记录的部分),并在内部调用远程电话服务来实际完成工作.这是使用AIDL完成的,AIDL是一种"远程过程调用".远程服务可以执行未通过TelephonyManager类公开公开的事情.你在这里做的是使用"远程过程调用"接口的客户端getITelephony().这将返回一个类型的对象ITelephony.这个类有一个名为的方法endCall().一旦我们有了类型的对象ITelephony,我们就可以得到它的Class对象,然后获取方法endCall()来自班级.一旦我们有了这个方法,我们就可以访问它而不是调用它.该方法endCall()位于远程过程调用的客户端.该方法现在向电话管理器服务(在远程服务器中运行)发送消息并要求它结束呼叫.
由于该源代码ITelephony.aidl是公开可用的,因此您可以将源代码放在项目中,并且IDE将生成ITelephony.java(包含远程过程调用的客户端)ITelephony.aidl.然后你就可以了import,你的IDE现在就会知道这个ITelephony类及其方法.这允许编译器在编译项目时生成正确的字节代码.当您在Android设备上运行此代码时,您可以调用Android框架来获取ITelephony对象,然后将其转换为com.android.internal.telephony.ITelephony.从那时起,ITelephony.java只要您拥有的Java代码ITelephony与返回的实际类定义匹配,就可以使用生成的方法访问对象的方法和字段.ITelephony宾语.如果类定义不匹配,VM将抛出适当的异常.
我希望这回答了你的问题.我不确定你对此有多了解,所以也许我提到了你已经知道的东西.如果是这样,抱歉.如果不清楚,请说明您不理解的内容.