android分層學習筆記(三)

來源:互聯網
上載者:User

對於應用程式訪問jni庫,是可以直接存取,即寫個active,然後調用System.load函數,jni庫載入進來,然後直接調用其中的api函數,從而實現操作硬體功能。但這不是android所規範的作法。
一般來說在framework寫一些中間東西,我們稱之為服務service。
關於android中的服務概念在android應用程式編寫教程中,都會提及到,其中都提到服務的生命週期,此處不詳細展開。

接下就著重點放在這個服務的實現上。

1 gpio serviced
  在service目錄下建立framework/service/java/com/ask/serviced/目錄,即
  cd framework
  mkdir -p service/java/com/ask/serviced
 
  再建立serviced.java檔案,檔案名稱應該就是類名。
 內容如下:
package com.ask.server;          //產生的包名為com.ask.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;
public final class serviced
{
    static
    {
        System.load("/system/lib/libaskgpio.so");  //載入jni庫檔案
    }

    public serviced()
    {
        Log.i("GpioService", "Go to get Gpio Stub...");
        _gpio_init();
    }

    /*
     * Ctop Gpio native methods.
     */
    public boolean GpioSet(int gpio)
    {
        Log.i("AskPlatform", "Gpio set");
        return _gpio_set(gpio);
    }

    public boolean GpioClr(int gpio)
    {
        Log.i("AskPlatform", "Gpio clr");
        return _gpio_clr(gpio);
    }

    private static native boolean _gpio_init();
    private static native boolean _gpio_set(int gpio);
    private static native boolean _gpio_clr(int gpio);
}
其中:
     private static native boolean _gpio_init();
    private static native boolean _gpio_set(int gpio);
    private static native boolean _gpio_clr(int gpio);
    是聲明libaskgpio.so庫中的函數,這樣才可以給java程式調用。
Android.mk的編寫,內容如下:
LOCAL_PATH := $(call my-dir)
# the library
# =============================================================
include $(CLEAR_VARS)

LOCAL_SRC_FILES := /
            $(call all-subdir-java-files)

LOCAL_MODULE_TAGS := eng

LOCAL_MODULE := ask

include $(BUILD_JAVA_LIBRARY)

# The JNI component
include $(CLEAR_VARS)
include $(call all-makefiles-under,$(LOCAL_PATH))
儲存到framework目錄下

在應用程式中,要加入一些permissions才能使用這個java包,這個將在下節的應用程式中說明。

2 gpio service manager
在1中所描述的是service 可供應用程式直接調用,而在android,對於應用程式中,更規範的做法是通過service manager來調用管理service。即應用程式通過mangger訪問jni庫
這裡面會涉及到aidl,aidl,可簡單認為是一個介面。在編譯過程中,會將aidl檔案,編譯成java檔案,產生一個介面。

首先在在framework目錄建立core/java/ask/hardware/目錄
 即cd framework目錄
   mkdir -p core/java/ask/hardware/
建立GpioManager.java檔案和IGpioService.aidl檔案
GpioManager.java內容如下:

package ask.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 ask.hardware.IGpioService;

/**
 * Class that lets you access the Ctop GpioService.
 */
public class GpioManager
{
    private static final String TAG = "GpioManager";
    private IGpioService mGpioService;

    public GpioManager()
    {
   
        mGpioService = IGpioService.Stub.asInterface(ServiceManager.getService("Gpio"));  //擷取gpio的service,

        if (mGpioService != null)
        {
                Log.i(TAG, "The GpioManager object is ready.");
        }
    }

    public boolean GpioSet(int n)
    {
        boolean result = false;

        try
        {
            result = mGpioService.GpioSet(n);
        }
        catch (RemoteException e)
        {
            Log.e(TAG, "RemoteException in GpioManager.Gpio set:", e);
        }
        return result;
    }

    public boolean GpioClr(int n)
    {
        boolean result = false;

        try
        {
            result = mGpioService.GpioClr(n);
        }
        catch (RemoteException e)
        {
            Log.e(TAG, "RemoteException in GpioManager.Gpio clr:", e);
        }
        return result;
    }
}
其中: mGpioService = IGpioService.Stub.asInterface(ServiceManager.getService("Gpio"));是擷取gpio的service,這時gpio service不是1中所編寫的gpio service內容,要重要編寫,稍後給出。

IGpioService.aidl的內容如下:這個比較簡單
package ask.hardware;
interface IGpioService
{
    boolean GpioSet(int gpio);
    boolean GpioClr(int gpio);
}
產生ask.hardware與GpioManager產生的包是一致的。

最後縮寫gpioservice代碼
    這個與1所編寫的 gpio serviced,類似。如下:
    在framework/service目錄下建立java/com/ask/service/目錄,即
    cd framework
    mkdir -p service/java/com/ask/service
    cd service/java/com/ask/service
    在此目錄下建立GpioSerivce.java,內容如下
   
 package com.ask.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 ask.hardware.IGpioService;

public final class GpioService extends IGpioService.Stub
{

    static
    {
        System.load("/system/lib/libaskgpio.so");
    }

    public GpioService()
    {
        Log.i("GpioService", "Go to get Gpio Stub...");
        _gpio_init();
    }

    /*
     * Ctop Gpio native methods.
     */
    public boolean GpioSet(int gpio)
    {
        Log.i("CTOPPlatform", "Gpio set");
        return _gpio_set(gpio);
    }

    public boolean GpioClr(int gpio)
    {
        Log.i("CTOPPlatform", "Gpio clr");
        return _gpio_clr(gpio);
    }

    private static native boolean _gpio_init();
    private static native boolean _gpio_set(int gpio);
    private static native boolean _gpio_clr(int gpio);

應該說GpioService類與serviced類是比較相似的,只是GpioService繼承於IGpioService.Stub。

Android.mk檔案的編寫
LOCAL_PATH := $(call my-dir)

# the library
# =============================================================
include $(CLEAR_VARS)

LOCAL_SRC_FILES := /
            $(call all-subdir-java-files)

LOCAL_MODULE_TAGS := eng

LOCAL_MODULE := ask

# AIDL
LOCAL_SRC_FILES += /
            core/java/ask/hardware/IGpioService.aidl

include $(BUILD_JAVA_LIBRARY)

# The JNI component
include $(CLEAR_VARS)
include $(call all-makefiles-under,$(LOCAL_PATH))

儲存此檔案到framework目錄下

然後編譯。

兩種的service目錄結構如下:
framework-|
                  |->core->java->ask->hardware-|
                  |                                                  |->GpioManager.java
                  |                                                 |->IGpioService.aid
                  |->service-|
                  |             |->java->com->ask-|
                  |             |                              |->service->GpioService.java
                  |             |                              |->serviced->serviced.java
                  |             |->jni->|
                  |                         |->Android.mk
                  |                         |->com_ask_gpio.cpp
                  |->Android.mk
         
 最後make的時候可以在out/target/product/generic/system/framework目錄下看到ask.jar包。
 
 注,以上兩種service方式在framework目錄下的Android.mk檔案是可以一樣的。當然獨立編譯是最好的,因為我們沒有必要用同時用兩種方法來實現一個功能,擇其善者而用之。
 
 待續為應用程式編寫

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.