使用使用"mmm frameworks/base/"命令编译
frameworks/base/core/java/android/os/
ILedService.aidl文件,在out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/目录下会生成ILedService.java文件,内容如下:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: frameworks/base/./core/java/android/os/ILedService.aidl
*/
package android.os;
/** {@hide} */
public interface ILedService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.os.ILedService
{
private static final java.lang.String DESCRIPTOR = "android.os.ILedService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.os.ILedService interface,
* generating a proxy if needed.
*/
public static android.os.ILedService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.os.ILedService))) {
return ((android.os.ILedService)iin);
}
return new android.os.ILedService.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_ledCtrl:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.ledCtrl(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.os.ILedService
{
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 int ledCtrl(int which, int status) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(which);
_data.writeInt(status);
mRemote.transact(Stub.TRANSACTION_ledCtrl, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_ledCtrl = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public int ledCtrl(int which, int status) throws android.os.RemoteException;
}在前面生成apk的文章中,通过
iLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));来获得一个ILedService对象,之后就可以通过这个对象的ledCtrl方法来操作LED。本文中,使用java的反射机制来生成apk,MainActivity.java源码如下:
package mobiletek.ledreflect;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;
import android.os.IBinder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainActivity extends AppCompatActivity {
private boolean ledon = false;
private Button button = null;
Object proxy = null;
Method ledCtrl = null;
private CheckBox checkBoxLed1 = null;
private CheckBox checkBoxLed2 = null;
private CheckBox checkBoxLed3 = null;
private CheckBox checkBoxLed4 = null;
int []ledctrl = {0x12, 0x34, 0x56, 0x78};
class MyButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
ledon = !ledon;
if (ledon) {
button.setText("ALL OFF");
checkBoxLed1.setChecked(true);
checkBoxLed2.setChecked(true);
checkBoxLed3.setChecked(true);
checkBoxLed4.setChecked(true);
try {
for (int i = 0; i < 4; i++)
ledCtrl.invoke(proxy, ledctrl[i], 1);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
else {
button.setText("ALL ON");
checkBoxLed1.setChecked(false);
checkBoxLed2.setChecked(false);
checkBoxLed3.setChecked(false);
checkBoxLed4.setChecked(false);
try {
for (int i = 0; i < 4; i++)
ledCtrl.invoke(proxy, ledctrl[i], 0);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
public void onCheckboxClicked(View view) {
// Is the view now checked?
boolean checked = ((CheckBox) view).isChecked();
// Check which checkbox was clicked
try {
switch(view.getId()) {
case R.id.LED1:
if (checked) {
Toast.makeText(getApplicationContext(), "LED1 on", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[0], 1);
}
else {
Toast.makeText(getApplicationContext(), "LED1 off", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[0], 0);
}
break;
case R.id.LED2:
if (checked) {
Toast.makeText(getApplicationContext(), "LED2 on", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[1], 1);
}
else {
Toast.makeText(getApplicationContext(), "LED2 off", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[1], 0);
}
break;
case R.id.LED3:
if (checked) {
Toast.makeText(getApplicationContext(), "LED3 on", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[2], 1);
}
else {
Toast.makeText(getApplicationContext(), "LED3 off", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[2], 0);
}
break;
case R.id.LED4:
if (checked) {
Toast.makeText(getApplicationContext(), "LED4 on", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[3], 1);
}
else {
Toast.makeText(getApplicationContext(), "LED4 off", Toast.LENGTH_SHORT).show();
ledCtrl.invoke(proxy, ledctrl[3], 0);
}
break;
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.BUTTON);
try {
Method getService = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
Object ledService = getService.invoke(null, "led");
Method asInterface = Class.forName("android.os.ILedService$Stub").getMethod("asInterface", IBinder.class);
proxy = asInterface.invoke(null, ledService);
ledCtrl = Class.forName("android.os.ILedService$Stub$Proxy").getMethod("ledCtrl", int.class, int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
checkBoxLed1 = (CheckBox) findViewById(R.id.LED1);
checkBoxLed2 = (CheckBox) findViewById(R.id.LED2);
checkBoxLed3 = (CheckBox) findViewById(R.id.LED3);
checkBoxLed4 = (CheckBox) findViewById(R.id.LED4);
button.setOnClickListener(new MyButtonListener());
}
}在onCreate方法中,首先通过下面两行代码将
ILedService.Stub.asInterface(ServiceManager.getService("led"));实参替换掉:
Method getService = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
Object ledService = getService.invoke(null, "led");
ServiceManager.getService("led")被替换为ledService,
ServiceManager的getService方法在frameworks/base/core/java/android/os/ServiceManager.java文件中定义:
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}通过proxy = asInterface.invoke(null, ledService);返回IBinder对象,再向上转换为Object对象。接下来通过下面两行,调用ILedService接口的内部类Stub的asInterface方法获得ILedService对象proxy,再向上转换为Object对象:
Method asInterface = Class.forName("android.os.ILedService$Stub").getMethod("asInterface", IBinder.class);
proxy = asInterface.invoke(null, ledService);最后通过ledCtrl = Class.forName("android.os.ILedService$Stub$Proxy").getMethod("ledCtrl", int.class, int.class);获得
ILedService接口的内部类Stub的内部类Proxy的ledCtrl方法,之后就可以通过ledCtrl.invoke来操作LED,由于ledCtrl方法没有用static声明,所以调用时需要传入一个实例化对象,例如:ledCtrl.invoke(proxy, ledctrl[0], 1);