android分層學習筆記(四)

來源:互聯網
上載者:User

寫好底層的庫,接下來就是寫應用程式使用或驗證了。
前面也介紹了,應用程式訪問jni庫,有多種方法,最簡單的就是直接調用,其次是用service,再次為service manager
1 直接載入。
    這有點兒像從三樓直接跳下來。其實java本來就有調用原生代碼的介面。android開發還包含有ndk開發,這個就是直接用c來做應用程式。

1.1 testjni1.java
在與framwork同層目錄下,建立app目錄,mkdir app
再在app目錄下,建立dirload/src/com/ask/目錄,產生testjni1.java,內容如下:

package com.ask.testjni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class testjni1 extends Activity
{

    static
    {
        //System.load("/system/lib/libaskgpio.so");
        System.load("/system/lib/libaskgpio");
    }
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Call an API on the library.
        _gpio_init();
        _gpio_set(1);
        _gpio_clr(2);
            
        TextView tv = new TextView(this);
        tv.setText("gpio 1 is set to 1. gpio 2 is set to 0.");
        setContentView(tv);
   }
    private static native boolean _gpio_init();
    private static native boolean _gpio_set(int gpio);
    private static native boolean _gpio_clr(int gpio);
}
說明:System.load("/system/lib/libaskgpio");有實際測試中這樣載入可能不成功,要定居這樣System.load("/system/lib/libaskgpio.so");

1.2 Android.mk編寫,儲存在dirload目錄下

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := user

# This is the target being built.
LOCAL_PACKAGE_NAME := testjni1

# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)

# Link against the current Android SDK.
LOCAL_SDK_VERSION := current

include $(BUILD_PACKAGE)

1.3 再寫AndroidManifest.xml,儲存至dirload目錄下
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ask.testjni1">
    <application>   
        <activity android:name="testjni1">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

最後編譯,將在out/target/product/generic/system/app/產生testjni1.apk檔案。

2 調用service方式
2.1再在app目錄下,建立serviceload/src/com/ask/目錄,產生serviceload.java,內容如下:
package com.ask.serviceload;
import com.ask.server.serviced;  //注意不是GpioService
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class serviceload extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Call an API on the library.
    serviced sd = new serviced();
    sd.GpioSet(1);
    sd.GpioClr(2);     
        TextView tv = new TextView(this);
        tv.setText("gpio 1 is set. gpio 2 is clr.");
        setContentView(tv);
    }
}
這裡new一個serviced,這時將會載入jni的庫,然後調用serviced裡的api函數GpioSet和GpioClr
2.2 編寫Android.mk檔案,儲存至serviceload目錄下
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := user

# This is the target being built.
LOCAL_PACKAGE_NAME := serviceload

# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)

# Link against the current Android SDK.
LOCAL_SDK_VERSION := current

# Also link against our own custom library.
LOCAL_JAVA_LIBRARIES := ask

include $(BUILD_PACKAGE)

2.3 再寫AndroidManifest.xml,儲存至serviceload目錄下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ask.GpioClient">
   
    <application>
   
        <!-- This tells the system about the custom library used by the
             application, so that it can be properly loaded and linked
             to the app when the app is initialized. -->
        <uses-library android:name="com.ask.serviced" />
       
        <activity android:name="serviceload">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

最後編譯,將在out/target/product/generic/system/app/產生serviceload.apk檔案。

2.4 運行此程式由於用到serviceload類,因此還要在/etc/permission下,增加一個permission,如下
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="com.ask.serviced"
                file="/system/framework/ask.jar"/>
    </permissions>
    檔案名稱可為com.ask.serviced.xml

3 通過service manager調用jni
3.1 在app目錄下,建立managerload/src/com/ask/目錄
3.1.1 產生gpio system service類,檔案名稱GpioSystemServer.java
    這個類的產生主要是供managerload調用,內容如下
package com.ask.GpioSystemServer;

import com.ask.server.GpioService;

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 GpioSystemServer extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onStart(Intent intent, int startId) {
        Log.i("GpioSystemServer", "Start GpioService...");

    /* Please also see SystemServer.java for your interests. */
    GpioService gs = new GpioService();

        try {
            ServiceManager.addService("gpio", gs);
        } catch (RuntimeException e) {
            Log.e("GpioSystemServer", "Start GpioService failed.");
        }
    }
}   
3.1.2 產生managerload.java,內容如下:
package com.ask.managerload;
import ask.hardware.GpioManager;
import com.ask.server.GpioService;

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 managerload extends Activity implements View.OnClickListener {
    private GpioManager mGpioManager = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Start LedService in a seperated process.
        startService(new Intent("com.ask.systemserver"));

        Button btn = new Button(this);
        btn.setText("Click to turn gpio 1 set 1");
        btn.setOnClickListener(this);

        setContentView(btn);
    }

    public void onClick(View v) {

        // Get LedManager.
        if (mGpioManager == null) {
        Log.i("LedTest", "Creat a new mGpioManager object.");
        mGpioManager = new GpioManager();
        }

        if (mGpioManager != null) {
        Log.i("managerload", "Got GpioManager object.");
    }

      
        mGpioManager.GpioSet(1);
        TextView tv = new TextView(this);
        tv.setText("gpio 1 is set 1.");
        setContentView(tv);
        }


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

LOCAL_MODULE_TAGS := user

# This is the target being built.
LOCAL_PACKAGE_NAME := managerload

# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)

# Link against the current Android SDK.
LOCAL_SDK_VERSION := current

# Also link against our own custom library.
LOCAL_JAVA_LIBRARIES := ask framework

# We need to assign platform key to use ServiceManager.addService.
LOCAL_CERTIFICATE := platform

include $(BUILD_PACKAGE)

3.4 同2.4一樣,在/etc/permission下增加一個xml檔案。
 運行此程式由於用到serviceload類,因此還要在/etc/permission下,增加一個permission,如下
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="com.ask.server"
                file="/system/framework/ask.jar"/>
    </permissions>
    檔案名稱可為com.ask.GpioService.xml

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.