(3)service (属于Framework层)
文件:frameworks/base/service/java/com/mokoid/server/LedService.java
- package com.mokoid.server;
- import android.util.Config;
- import android.util.Log;
- import android.content.Context;
- import android.os.Binder;
- import android.os.Bundle;
- import android.os.RemoteException;
- import android.os.IBinder;
- import mokoid.hardware.ILedService;
- public final class LedService extends ILedService.Stub {
-
- static {
- System.load("/system/lib/libmokoid_runtime.so");
- }
- public LedService() {
- Log.i("LedService", "Go to get LED Stub...");
- _init();
- }
-
-
-
- public boolean setOn(int led) {
- Log.i("MokoidPlatform", "LED On");
- return _set_on(led);
- }
- public boolean setOff(int led) {
- Log.i("MokoidPlatform", "LED Off");
- return _set_off(led);
- }
- private static native boolean _init();
- private static native boolean _set_on(int led);
- private static native boolean _set_off(int led);
- }
(4)APP 测试程序 (属于APP层)
文件:apps/LedClient/src/com/mokoid/LedClient/LedClient.java
- package com.mokoid.LedClient;
- import com.mokoid.server.LedService;
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.TextView;
-
- public class LedClient extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- LedService ls = new LedService();
- ls.setOn(1);
- ls.setOff(2);
-
- TextView tv = new TextView(this);
- tv.setText("LED 1 is on. LED 2 is off.");
- setContentView(tv);
- }
- }
5、第二种方法:经过Manager调用service
HAL、JNI两层和第一种方法一样,所以后面只分析其他的层次。
(1)Manager (属于Framework层)
APP通过这个Manager和service通讯。
文件:mokoid-read-only /frameworks/base/core/java/mokoid/hardware/LedManager.java
- package mokoid.hardware;
- import android.content.Context;
- import android.os.Binder;
- import android.os.Bundle;
- import android.os.Parcelable;
- import android.os.ParcelFileDescriptor;
- import android.os.Process;
- import android.os.RemoteException;
- import android.os.Handler;
- import android.os.Message;
- import android.os.ServiceManager;
- import android.util.Log;
- import mokoid.hardware.ILedService;
-
-
-
-
- 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;
- }
- }
因为LedService和LedManager在不同的进程,所以要考虑到进程通讯的问题。Manager通过增加一个aidl文件来描述通讯接口。
文件:mokoid-read-only/frameworks/base/core/java/mokoid/hardware/ILedService.aidl
- package mokoid.hardware;
- interface ILedService
- {
- boolean setOn(int led);
- boolean setOff(int led);
- }
-
(2)SystemServer (属于APP层)
文件:mokoid-read-only/apps/LedTest/src/com/mokoid/LedTest/LedSystemServer.java
- package com.mokoid.LedTest;
- import com.mokoid.server.LedService;
- import android.os.IBinder;
- import android.os.ServiceManager;
- import android.util.Log;
- import android.app.Service;
- import android.content.Context;
- import android.content.Intent;
-
- 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...");
-
-
- LedService ls = new LedService();
- try {
- ServiceManager.addService("led", ls);
- } catch (RuntimeException e) {
- Log.e("LedSystemServer", "Start LedService failed.");
- }
- }
- }
(3)APP 测试程序(属于APP层)
文件:mokoid-read-only/apps/LedTest/src/com/mokoid/LedTest/LedTest.java
- package com.mokoid.LedTest;
- import mokoid.hardware.LedManager;
- import com.mokoid.server.LedService;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.TextView;
- import android.widget.Button;
- import android.content.Intent;
- import android.view.View;
-
- public class LedTest extends Activity implements View.OnClickListener {
- private LedManager mLedManager = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- 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) {
-
- if (mLedManager == null) {
- Log.i("LedTest", "Creat a new LedManager object.");
- mLedManager = new LedManager();
- }
- if (mLedManager != null) {
- Log.i("LedTest", "Got LedManager object.");
- }
-
-
-
- mLedManager.LedOn(1);
- TextView tv = new TextView(this);
- tv.setText("LED 1 is On.");
- setContentView(tv);
- }
- }
五、实验中需要注意的问题
将下载后的源码放到你的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
按照以前的实验加入下列代码:
- static int registerMethods(JNIEnv* env) {
- static const char* const kClassName ="com/mokoid/server/LedService";
- jclass clazz;
-
- clazz = env->FindClass(kClassName);
- if (clazz == NULL) {
- LOGE("Can't find class %s\n", kClassName);
- return -1;
- }
-
- if (env->RegisterNatives(clazz, gMethods,
- sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
- {
- LOGE("Failed registering methods for %s\n", kClassName);
- return -1;
- }
-
- return 0;
- }
-
-
-
- jint JNI_OnLoad(JavaVM* vm, void* reserved) {
- JNIEnv* env = NULL;
- jint result = -1;
- LOGI("JNI_OnLoad LED");
- if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- LOGE("ERROR: GetEnv failed\n");
- goto fail;
- }
- assert(env != NULL);
- if (registerMethods(env) != 0) {
- LOGE("ERROR: PlatformLibrary native registration failed\n");
- goto fail;
- }
-
- result = JNI_VERSION_1_4;
- fail:
- return result;
- }
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) |