1. 程式人生 > >android反射呼叫 .

android反射呼叫 .

PowerManager類並沒有提供關機的shutdown介面,而是通過IBinder這種Android中特有的通訊模式,與PowerManagerService 類進行通訊。PowerManagerService是PowerManager 類中定義的介面的具體實現,並進一步呼叫Power 類來與下一層進行通訊. 在PowerManagerService實現了shutdown介面,power服務實現了關機功能 
PowerManager的實現通過IPowerManager來呼叫Power服務的介面。 IPowerManager是AIDL檔案自動生成的類,便於遠端通訊。IPowerManage.aidl檔案目錄


framework/base/core/java/android/os/IPowerManage.aidl

IPowerManager實現了shutdown介面,所以,如果我們能夠獲得Power服務的IBinder,通過反射呼叫shutdown方法就能實現關機功能。 
需要注意的是,ServiceManager管理著系統的服務程式,它儲存著所有服務的IBinder,通過服務名就能獲取到這個服務的IBinder。 
但ServiceManager這個類也是HIDE的,也需要反射進行呼叫。兩次,通過兩次反射呼叫,就能呼叫power服務實現的關機功能。

try {
                         
                        //獲得ServiceManager類
                        Class<!--?--> ServiceManager = Class
                           .forName("android.os.ServiceManager");
                         
                        //獲得ServiceManager的getService方法
                        Method getService = ServiceManager.getMethod("getService", java.lang.String.class);
                         
                        //呼叫getService獲取RemoteService
                        Object oRemoteService = getService.invoke(null,Context.POWER_SERVICE);
                         
                        //獲得IPowerManager.Stub類
                        Class<!--?--> cStub = Class
                           .forName("android.os.IPowerManager$Stub");
                        //獲得asInterface方法
                        Method asInterface = cStub.getMethod("asInterface", android.os.IBinder.class);
                        //呼叫asInterface方法獲取IPowerManager物件
                        Object oIPowerManager = asInterface.invoke(null, oRemoteService);
                        //獲得shutdown()方法
                        Method shutdown = oIPowerManager.getClass().getMethod("shutdown",boolean.class,boolean.class);
                        //呼叫shutdown()方法
                        shutdown.invoke(oIPowerManager,false,true);           
                   
              } catch (Exception e) {         
                   Log.e(TAG, e.toString(), e);        
              }