关于Binder机制及其原理可以阅读《深入理解Android内核设计思想》第6章,不再详述。
此处,仅介绍一个系统service的具体实现示例
实现过程:
1.apk调用的是jar包里的函数
2.服务器上编译生成jar包供apk使用
首先是source命令加载并选择sh脚本,执行mm命令之后会打包生成三个jar包
com.***.tvapi.factory.jar
com.***.factory.jar
com.***.facservice.jar
http://blog.csdn.net/yajun0601/article/details/7309010
3.框架层的结构分析:
1.APK调用FactoryMenuAdapter的函数:
public class ThirdParty {
private final static String TAG = "ThirdParty";
public static FactoryMenuAdapter mFactoryAdapter;
public ThirdParty(Context mContext_) {
ThirdParty.mContext = mContext_;
mFactoryAdapter = FactoryMenuAdapter.getInstance(mContext_);
}
public static void setRGainValue(int value) {
mFactoryAdapter.setRedGainValue(value);
Log.v(TAG, "setRGainValue : " + value);
}
}
2.FactoryMenuAdapter中调用FacService的函数:
public class FactoryMenuAdapter {
private static final String TAG = "FactoryAdapter";
private Context mContext;
private IFacService mService;
private static FactoryMenuAdapter sInstance = null;
private FactoryMenuAdapter(Context context) {
mService = IFacService.Stub.asInterface(ServiceManager
.getService("my_factory"));
mContext = context;
}
public static FactoryMenuAdapter getInstance(Context context) {
if (sInstance == null) {
synchronized (FactoryMenuAdapter.class) {
if (sInstance == null) {
sInstance = new FactoryMenuAdapter(context);
}
}
}
return sInstance;
}
/**
* set red gain value of system
* @param redGainValue red gain value of system
* @return void
*/
public void setRedGainValue(int redGainValue) {
try {
mService.setRedGainValue(redGainValue);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
(这里对IFacService的使用要进行说明)
3.FacService中调用FactoryMenuManager的函数:
public class FacService extends IFacService.Stub {
private static final String TAG = "FacService";
private FactoryMenuManager mFactoryMenuManager;
static final boolean DEBUG = true;
public FacService(Context context) {
mFactoryMenuManager = FactoryMenu.getFactoryMenuManager();
}
@Override
public void setRedGainValue(int redGainValue) throws RemoteException {
// TODO Auto-generated method stub
if (mFactoryMenuManager != null) {
mFactoryMenuManager.setRedGainValue(redGainValue);
}
}
}
(这里用工厂模式,从FactoryMenu获取实例也要进行说明)
4.FactoryMenu中提供getFactoryMenuManager()函数供获取FactoryMenuManager实例
public final class FactoryMenu {
private static final String POLICY_IMPL_CLASS_NAME =
"com.my.tvapi.factory.impl.Policy";
private static final IPolicy sPolicy;
static {
// Pull in the actual implementation of the policy at run-time
try {
Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);
sPolicy = (IPolicy)policyClass.newInstance();
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be loaded", ex);
} catch (InstantiationException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
}
}
// Cannot instantiate this class
private FactoryMenu() {}
public static FactoryMenuManager getFactoryMenuManager() {
return sPolicy.getFactoryMenuManager();
}
}
5.IPolicy是一个接口
public interface IPolicy {
FactoryMenuManager getFactoryMenuManager();
}
6.FactoryMenuManager也是一个接口
public interface FactoryMenuManager {
/**
* set red gain value of system
* @param redGainValue red gain value of system
* @return void
*/
public void setRedGainValue(int redGainValue);
}
7.FactoryMenuManagerImpl是一个继承并实现了FactoryMenuManager接口的类
public class FactoryMenuManagerImpl implements FactoryMenuManager {
private static TvFactoryManager factormanager;
...
public void setRedGainValue(int redGainValue){
factormanager.setAdcRedGain(redGainValue);
}
...
}
8.TvFactoryManager的实现是执行ITvFactory的函数调用
public class TvFactoryManager {
private static ITvFactory mService = null;
...
private static ITvFactory getService() {
if (mService != null) {
return mService;
}
mService = TvManager.getInstance().getTvFactory();
return mService;
}
...
public boolean setAdcRedGain(int redGain) {
ITvFactory service = getService();
try {
service.setAdcRedGain(redGain);
} catch (RemoteException e) {
e.printStackTrace();
}
return false;
}
...
}
9.TvManager通过ServiceManager获取不同的工厂,比如这里是TvFactory,还可以是TvPicture等等。
public class TvManager {
static TvManager mInstance = null;
ITvService mService = null;
public static TvManager getInstance() {
if (mInstance == null) {
synchronized (TvManager.class) {
if (mInstance == null) {
IBinder b = ServiceManager.getService(Context.TV_SERVICE);
mInstance = new TvManager(ITvService.Stub.asInterface(b));
}
}
}
return mInstance;
}
...
public ITvFactory getTvFactory() {
try {
return mService.getTvFactory();
} catch (RemoteException e) {
e.printStackTrace();
return null;
}
}
...
}
10.ServiceManager是在内核之中,通过一个HashMap来查找绑定的服务是否存在,如果不存在就通过静态成员函数getIServiceManager来获取ServiceManager的java远程接口。(可以getService和addService,我们添加系统服务就在这添加)
public final class ServiceManager {
private static IServiceManager sServiceManager;
private static HashMap sCache = new HashMap();
....
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;
}
...
}
11.综上
在8当中调用到了service.setAdcRedGain(redGain);
等价于:
ServiceManager.getService(Context.TV_SERVICE).getTvFactory().setAdcRedGain(redGain);
12.现在看ITvFactory接口,因为ServiceManager.getService(Context.TV_SERVICE).getTvFactory()
就是ITvFactory.getTvFactory();
ITvService中通过getTvFactory()返回一个ITvFactory接口
public interface ITvService extends android.os.IInterface
{
...
@Override
public com.mstar.android.tv.ITvFactory getTvFactory()
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
com.mstar.android.tv.ITvFactory _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getTvFactory, _data,
_reply, 0);
_reply.readException();
_result = com.mstar.android.tv.ITvFactory.Stub
.asInterface(_reply.readStrongBinder());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
...
}
13.ITvFactory这个接口中有setAdcRedGain()的实现
public interface ITvFactory extends android.os.IInterface {
...
@Override
public boolean setAdcRedGain(int redGain)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(redGain);
mRemote.transact(Stub.TRANSACTION_setAdcRedGain, _data,
_reply, 0);
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
...
}
14.到此程序的调用流程就结束了,那么工厂服务又是在什么时候添加的呢?又是什么时候开启的呢?又是怎么查找的呢?
第二部分
系统服务的添加地点、开启时机、和获取
15.自定义系统服务的添加地点
前面提到ServiceManager的时候,说过可以通过addService函数来添加系统服务。
在SystemService中开启了一个ServerThread线程,在ServiceThread线程中添加的服务
public class SystemServer {
private static final String TAG = "SystemServer";
public static final int FACTORY_TEST_OFF = 0;
public static final int FACTORY_TEST_LOW_LEVEL = 1;
public static final int FACTORY_TEST_HIGH_LEVEL = 2;
static Timer timer;
static final long SNAPSHOT_INTERVAL = 60 * 60 * 1000; // 1hr
// The earliest supported time. We pick one day into 1970, to
// give any timezone code room without going into negative time.
private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
native public static void init1(String[] args);
public static void main(String[] args) {
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it
// shortly.
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server",
null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more memory!
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
Environment.setUserRequired(true);
System.loadLibrary("android_servers");
init1(args);
}
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
}
线程如下:
class ServerThread extends Thread {
...
Public void run(){
...
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
// MStar Android Patch Begin
if (!"1".equals(SystemProperties.get("mstar.disable.tvservice"))) {
try {
Slog.i(TAG, "TV Service");
tv = new TvService(context);
ServiceManager.addService(Context.TV_SERVICE, tv);
} catch (Throwable e) {
reportWtf("starting TV Service", e);
}
try {
Slog.i(TAG, "xxTvService");
xxTvService = new xxTvService(context);
ServiceManager.addService("xx_tv", xxTvService);
} catch (Throwable e) {
Log.e(TAG, "failuer to start xxTvService");
}
}
...
}
...
}
16.系统服务的开启时机
AndroidRuntime.cpp中有这么一段话
if (argv[1].equals("start-system-server")) {
startSystemServer();
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
startSystemServer()在Zygote上fork了一个进程com.android.server.SystemServer.()
17,系统服务的获取
ServiceManager.getService(Context.TV_SERVICE).getTvFactory();
总结:
如何在Android系统中添加一个系统服务,并通过Binder机制实现APK对其进行的跨进程远程调用