Chinaunix首页 | 论坛 | 博客
  • 博客访问: 849557
  • 博文数量: 168
  • 博客积分: 5431
  • 博客等级: 大校
  • 技术积分: 1560
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-22 11:56
文章存档

2015年(2)

2014年(1)

2013年(12)

2012年(12)

2011年(15)

2010年(5)

2009年(16)

2008年(41)

2007年(64)

分类: LINUX

2011-04-25 20:29:59

3service  属于Framework

文件:frameworks/base/service/java/com/mokoid/server/LedService.java

  1. package com.mokoid.server;  
  2. import android.util.Config;  
  3. import android.util.Log;  
  4. import android.content.Context;  
  5. import android.os.Binder;  
  6. import android.os.Bundle;  
  7. import android.os.RemoteException;  
  8. import android.os.IBinder;  
  9. import mokoid.hardware.ILedService;  
  10. public final class LedService extends ILedService.Stub {  
  11. //对于这种直接模式不需要进程通讯,所以可以不加extends ILedService.Stub,此处加上主要是为了后面的第二种模式.  
  12.     static {  
  13.         System.load("/system/lib/libmokoid_runtime.so");//加载jni的动态库  
  14.     }  
  15.     public LedService() {  
  16.         Log.i("LedService""Go to get LED Stub...");  
  17.     _init();  
  18.     }  
  19.     /* 
  20.      * Mokoid LED native methods. 
  21.      */  
  22.     public boolean setOn(int led) {  
  23.         Log.i("MokoidPlatform""LED On");  
  24.     return _set_on(led);  
  25.     }  
  26.     public boolean setOff(int led) {  
  27.         Log.i("MokoidPlatform""LED Off");  
  28.     return _set_off(led);  
  29.     }  
  30.     private static native boolean _init();          //声明jni库可以提供的方法  
  31.     private static native boolean _set_on(int led);  
  32.     private static native boolean _set_off(int led);  
  33. }  
 

4APP 测试程序 (属于APP

文件:apps/LedClient/src/com/mokoid/LedClient/LedClient.java

 

  1. package com.mokoid.LedClient;  
  2. import com.mokoid.server.LedService;// 导入Framework层的LedService  
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class LedClient extends Activity {  
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         // Call an API on the library.  
  12.     LedService ls = new LedService();  //实例化LedService  
  13.     ls.setOn(1);                       //通过LedService提供的方法,控制底层硬件  
  14.     ls.setOff(2);  
  15.           
  16.         TextView tv = new TextView(this);  
  17.         tv.setText("LED 1 is on. LED 2 is off.");  
  18.         setContentView(tv);  
  19.     }  
  20. }  

5、第二种方法经过Manager调用service

    HALJNI两层和第一种方法一样所以后面只分析其他的层次。

1Manager 属于Framework

    APP通过这个Managerservice通讯。

文件:mokoid-read-only /frameworks/base/core/java/mokoid/hardware/LedManager.java

 

  1. package mokoid.hardware;  
  2. import android.content.Context;  
  3. import android.os.Binder;  
  4. import android.os.Bundle;  
  5. import android.os.Parcelable;  
  6. import android.os.ParcelFileDescriptor;  
  7. import android.os.Process;  
  8. import android.os.RemoteException;  
  9. import android.os.Handler;  
  10. import android.os.Message;  
  11. import android.os.ServiceManager;  
  12. import android.util.Log;  
  13. import mokoid.hardware.ILedService;  
  14.   
  15. /* 
  16.  * Class that lets you access the Mokoid LedService. 
  17.  */  
  18. public class LedManager  
  19. {  
  20.     private static final String TAG = "LedManager";  
  21.     private ILedService mLedService;  
  22.     public LedManager() {  
  23.         mLedService = ILedService.Stub.asInterface(ServiceManager.getService("led"));  
  24. /* 
  25. *这一步是关键,利用ServiceManager获取到LedService,从而调用它提供的方法。这要求LedService必 
  26. *须已经添加到了ServiceManager中,这个过程将在App中的一个service进程中完成。 
  27. */  
  28.     if (mLedService != null) {  
  29.             Log.i(TAG, "The LedManager object is ready.");  
  30.     }  
  31.     }  
  32.     public boolean LedOn(int n) {  
  33.         boolean result = false;  
  34.         try {  
  35.             result = mLedService.setOn(n);  
  36.         } catch (RemoteException e) {  
  37.             Log.e(TAG, "RemoteException in LedManager.LedOn:", e);  
  38.         }  
  39.         return result;  
  40.     }  
  41.     public boolean LedOff(int n) {  
  42.         boolean result = false;  
  43.         try {  
  44.             result = mLedService.setOff(n);  
  45.         } catch (RemoteException e) {  
  46.             Log.e(TAG, "RemoteException in LedManager.LedOff:", e);  
  47.         }  
  48.         return result;  
  49.     }  
  50. }  
  

因为LedServiceLedManager在不同的进程,所以要考虑到进程通讯的问题。Manager通过增加一个aidl文件来描述通讯接口。

文件mokoid-read-only/frameworks/base/core/java/mokoid/hardware/ILedService.aidl

  1. package mokoid.hardware;  
  2. interface ILedService  
  3. {  
  4.     boolean setOn(int led);  
  5.     boolean setOff(int led);  
  6. }  
  7. //系统的aidl工具会将ILedService.aidl文件ILedService.java文件,实现了ILedService  
  

2SystemServer 属于APP

文件:mokoid-read-only/apps/LedTest/src/com/mokoid/LedTest/LedSystemServer.java

  1. package com.mokoid.LedTest;  
  2. import com.mokoid.server.LedService;  
  3. import android.os.IBinder;  
  4. import android.os.ServiceManager;  
  5. import android.util.Log;  
  6. import android.app.Service;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9.   
  10. public class LedSystemServer extends Service {  
  11. //注意这里的Service是APP中的概念,代表一个后台进程。注意区别和Framework中的service的概念。  
  12.     @Override  
  13.     public IBinder onBind(Intent intent) {  
  14.         return null;  
  15.     public void onStart(Intent intent, int startId) {  
  16.         Log.i("LedSystemServer""Start LedService...");  
  17.   
  18.     /* Please also see SystemServer.java for your interests. */  
  19.     LedService ls = new LedService();  
  20.         try {  
  21.             ServiceManager.addService("led", ls);  //将LedService添加到ServiceManager中  
  22.         } catch (RuntimeException e) {  
  23.             Log.e("LedSystemServer""Start LedService failed.");  
  24.         }  
  25.     }  
  26. }  

3APP 测试程序属于APP

文件:mokoid-read-only/apps/LedTest/src/com/mokoid/LedTest/LedTest.java

  1. package com.mokoid.LedTest;  
  2. import mokoid.hardware.LedManager;  
  3. import com.mokoid.server.LedService;  
  4. import android.app.Activity;  
  5. import android.os.Bundle;  
  6. import android.util.Log;  
  7. import android.widget.TextView;  
  8. import android.widget.Button;  
  9. import android.content.Intent;  
  10. import android.view.View;  
  11.   
  12. public class LedTest extends Activity implements View.OnClickListener {  
  13.     private LedManager mLedManager = null;  
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         // Start LedService in a seperated process.  
  18.         startService(new Intent("com.mokoid.systemserver"));//开启后台进程  
  19.         Button btn = new Button(this);  
  20.         btn.setText("Click to turn LED 1 On");  
  21.      btn.setOnClickListener(this);  
  22.         setContentView(btn);  
  23.     }  
  24.     public void onClick(View v) {  
  25.         // Get LedManager.  
  26.         if (mLedManager == null) {  
  27.         Log.i("LedTest""Creat a new LedManager object.");  
  28.         mLedManager = new LedManager();  //实例化Framework层中的Manager  
  29.         }      
  30.         if (mLedManager != null) {  
  31.         Log.i("LedTest""Got LedManager object.");  
  32.      }  
  33.         /** Call methods in LedService via proxy object  
  34.          * which is provided by LedManager.  
  35.          */  
  36.         mLedManager.LedOn(1);  
  37.         TextView tv = new TextView(this);  
  38.         tv.setText("LED 1 is On.");  
  39.         setContentView(tv);  
  40.     }  
  41. }  

五、实验中需要注意的问题

将下载后的源码放到你的android源码目录下然后编译系统。本实验用的android版本为2.1。实验的过程中大致出现过以下几个问题:

1、中没有生成LedClient.apk或LedTest.apk用程序

编译完成后,没有在目标系统的system/app/目录下找到LedClient.apk或LedTest应用程序。只有通过单独编译LedClient或LedTest才能在目标目录中生成。方法如下:

#mmm  mokoid-read-only/apps/LedTest/ 

检查原因后发现mokoid-read-only/apps/LedTest/Android.mk 

LOCAL_MODULES_TAGS :=user

而我们的s5pc100系统在配置时tapas时选择的是eng,所以没有装载到目标系统

所以修改LedTest和LedClient的Android.mk

LOCAL_MODULES_TAGS :=user  eng

再次编译即可自动装载到目标系统/system/app/目录下。

2、后没有图标,找不到应用程序

    目标系统启动后找不到两个应用程序的图标。细阅读logcat出的信息发现

E/PackageManager( 2717): Package com.mokoid.LedClient requires unavailable shared library com.mokoid.server; failing!

原因是找不到 com.mokoid.server检查mokoid-read-only/frameworks/base/Android.mk发现系统将LedManager和LedService编译成 mokoid.jar文件。为了让应用程序可以访问到这个库,需要通过com.mokoid.server.xml 来设定其对应关系。解决方法:拷贝com.mokoid.server.xml到目标系统的system/etc/permissions/目录下

此时两个应用的程序的图标都正常出现了。

3提示找不到 JNI_OnLoad

按照以前的实验加入下列代码:

  1. static int registerMethods(JNIEnv* env) {  
  2.     static const charconst kClassName ="com/mokoid/server/LedService";  
  3.     jclass clazz;   
  4.         /* look up the class */  
  5.         clazz = env->FindClass(kClassName);  
  6.         if (clazz == NULL) {  
  7.             LOGE("Can't find class %s\n", kClassName);  
  8.             return -1;  
  9.         }  
  10.             /* register all the methods */  
  11.         if (env->RegisterNatives(clazz, gMethods,  
  12.                     sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)  
  13.         {  
  14.             LOGE("Failed registering methods for %s\n", kClassName);  
  15.             return -1;  
  16.         }  
  17.     /* fill out the rest of the ID cache */  
  18.         return 0;  
  19. }   
  20. /* 
  21.  * This is called by the VM when the shared library is first loaded. 
  22.  */   
  23. jint JNI_OnLoad(JavaVM* vm, void* reserved) {  
  24.         JNIEnv* env = NULL;  
  25.         jint result = -1;  
  26.         LOGI("JNI_OnLoad LED");  
  27.         if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {  
  28.             LOGE("ERROR: GetEnv failed\n");  
  29.             goto fail;  
  30.         }  
  31.         assert(env != NULL);  
  32.         if (registerMethods(env) != 0) {  
  33.             LOGE("ERROR: PlatformLibrary native registration failed\n");  
  34.             goto fail;  
  35.         }  
  36.         /* success -- return valid version number */      
  37.         result = JNI_VERSION_1_4;  
  38. fail:  
  39.         return result;  
  40. }   

4需要针对你的目平台修改HAL的Makefile

修改mokoid-read-only/hardware/modules/led/Android.mk

LOCAL_MODULE := led.default

5、在eclipse编译不了LedSystemServer.java

原因是程序中要用到ServiceManager.addService,这需要系统权限。

解决方法可以把应用程序放入Android源码中编译,并确保以下两点:

    1在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。

    2修改Android 加入LOCAL_CERTIFICATE := platform.

当然:mokoid工程源码中已经做了这些。

阅读(2598) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~