为什么ITelephony.aidl有效?

我看到一些SOpost讨论了如何以程序方式结束电话,例如, 这个 。 是的,人们专注于结果,但没有人真正解释它为什么起作用的原因

我尝试了代码,效果很好。 但是我想了解更多关于底下发生的事情的细节? 为什么通过创建ITelephony.aidl ,我们的项目中暴露了android隐藏的内部ITelephony接口? 我们自己如何创建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(); 

Solutions Collecting From Web of "为什么ITelephony.aidl有效?"

实际上,没有必要将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() 

在幕后,这一切都使用Javareflection来访问私有(即:未公开记录)的方法。 您可以通过阅读开源(即:公开的)Android源代码来弄清楚它们有哪些方法以及它们的作用。 一旦你知道它是什么以及它做了什么,你就可以使用reflection来实现它,即使它是“隐藏的”。

TelephonyManager类是使用远程服务实现的。 如果您想请求TelephonyManager为您做某事,您可以在TelephonyManager上调用一个方法(这是公开记录的部分),并在内部调用远程电话服务来实际完成工作。 这是使用AIDL完成的,AIDL是一种“远程过程调用”。 远程服务可以执行未通过TelephonyManager类公开公开的内容。 你在这里做的是使用getITelephony()获取“远程过程调用”接口的客户端。 这将返回ITelephonytypes的对象。 该类有一个名为endCall()的方法。 一旦我们有了ITelephonytypes的对象,我们就可以得到它的Class对象,然后从Class中获取方法endCall() 。 一旦我们有了这个方法,我们就可以访问它而不是调用它。 方法endCall()位于远程过程调用的客户端。 该方法现在向电话管理器服务(在远程服务器中运行)发送消息并要求它结束呼叫。

由于ITelephony.aidl的源代码是公开可用的,因此您可以将源代码放在项目中,并且IDE将从ITelephony.java生成ITelephony.java (其中包含远程过程调用的客户端)。 然后,您可以import它,您的IDE现在将了解ITelephony类及其方法。 这允许编译器在编译项目时生成正确的字节代码。 当您在Android设备上运行此代码时,您调用Android框架以获取ITelephony对象,然后将其转换为com.android.internal.telephony.ITelephony 。 从那时起,只要ITelephony.java的Java代码与返回的ITelephony对象的实际类定义匹配,就可以使用生成的ITelephony.java访问对象的方法和字段。 如果类定义不匹配,VM将抛出适当的exception。

我希望这回答了你的问题。 我不确定你已经知道多少这个,所以也许我提到了你已经知道的东西。 如果是这样,抱歉。 如果不清楚,请说明您不明白的内容。