上一章介绍了直接调用Service来操作硬件的方法,如果我们再优化一下结构,通过一个Manager来调用这个Service的方法,可能会更好。这样Service就可以跑在后台,由于这时候service和manager是两个进程,所以只能通过IPC来进行通信。我们在上一篇看到
public final class LedService extends ILedService.Stub { }, ILedService.Stub就是
ILedService.aidl由aidl工具自动生成的类。
我们现在看看manager是如何实现的:
frameworks/base/core/java/mokoid/hardware/ILedService.aidl
- package mokoid.hardware;
- interface ILedService
- {
- boolean setOn(int led);
- boolean setOff(int led);
- }
该aidl文件最后能被aidl工具自动生成ILedService.java文件,提供了remotable的LedService可用的接口setOn和setOff.
frameworks/base/core/java/mokoid/hardware/LedManager.java
- public class LedManager
- {
- private static final String TAG = "LedManager";
- private ILedService mLedService;
- public LedManager() {
- mLedService = ILedService.Stub.asInterface(
- ServiceManager.getService("led"));
- if (mLedService != null) {
- Log.i(TAG, "The LedManager object is ready.");
- }
- }
- public boolean LedOn(int n) {
- boolean result = false;
- try {
- result = mLedService.setOn(n);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in LedManager.LedOn:", e);
- }
- return result;
- }
- public boolean LedOff(int n) {
- boolean result = false;
- try {
- result = mLedService.setOff(n);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in LedManager.LedOff:", e);
- }
- return result;
- }
- }
首先调用 mLedService = ILedService.Stub.asInterface(ServiceManager.getService("led")); 得到远端的led service, 然后通过mLedService.setOn和mLedService.setOff来调用service的接口,从而操作硬件。
最后我们看看使用这种方法对应的应用程序代码:
apps/LedTest/src/com/mokoid/LedTest/LedSystemServer.java
- public class LedSystemServer extends Service {
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- public void onStart(Intent intent, int startId) {
- Log.i("LedSystemServer", "Start LedService...");
- /* Please also see SystemServer.java for your interests. */
- LedService ls = new LedService();
- try {
- ServiceManager.addService("led", ls);
- } catch (RuntimeException e) {
- Log.e("LedSystemServer", "Start LedService failed.");
- }
- }
- }
上面的代码实现了android的一个后台service,通过ServiceManager.addService把LedService加入到service中,这样就可以通过远程调用该service。
apps/LedTest/src/com/mokoid/LedTest/LedTest.java
- public class LedTest extends Activity implements View.OnClickListener {
- private LedManager mLedManager = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // Start LedService in a seperated process.
- startService(new Intent("com.mokoid.systemserver"));
- Button btn = new Button(this);
- btn.setText("Click to turn LED 1 On");
- btn.setOnClickListener(this);
- setContentView(btn);
- }
- public void onClick(View v) {
- // Get LedManager.
- if (mLedManager == null) {
- Log.i("LedTest", "Creat a new LedManager object.");
- mLedManager = new LedManager();
- }
- if (mLedManager != null) {
- Log.i("LedTest", "Got LedManager object.");
- }
- /** Call methods in LedService via proxy object
- * which is provided by LedManager.
- */
- mLedManager.LedOn(1);
- TextView tv = new TextView(this);
- tv.setText("LED 1 is On.");
- setContentView(tv);
- }
- }
上面代码首先启动了上面的service,然后当用户点击按钮时,会得到ledManager的实例,然后通过ledManager的接口LedOn点亮led。