android平台中編寫jni模組的方法(1)

來源:互聯網
上載者:User

本文主要來記錄一下偶對android平台下面jni技術的研究心得體會,一來是備忘,二來也為後來者節省一些獨自摸索的時間。

一直在忙 著project方面的事情,聽到一個朋友提起說偶的blog很久沒有更新了。所以今天抽一些時間上來寫點東西。沒辦法,隨著手機行業的競爭日趨白熱化, 加上google,apple,palm之流的公司攪局,在手機領域的從業者的空閑時間越來越少,競爭也日趨白熱化。

閑話少敘,開始進入正題:
1、介紹一下命令列開發的方法
由於用c/c++習慣了,所以對eclipse的使用很是不習慣,還是決定用命令列(makefile類似)的方式進行編譯、開發(偶個人比較癡迷emacs)。
如果是java平台的話自然要選用ant了,關於linux下面android sdk的安裝以及環境變數的設定在此偶就不再贅述了,

偶選用的工作環境如下:
軟體環境:android-sdk-linux_x86_1.5_r1,jdk 1.6.0_12,slackware 12.1G,
硬體環境:lenvo sl400(辦公本本),android g1(已被破解,並刷入cupcake 1.5的版本)

(1)建立項目
wayne@wayne:~/works/workspace$android create project --target 2 --package com.twm --activity JniTest --path /home/wayne/works/workspace/JniTest

這裡面的android是1.5版本的sdk提供的一個指令碼工 具,需要注意的是參數--target(謝天謝地,google總算可以在一個sdk裡面同時支援1.1版本和1.5版本的android軟體開發 了),--target取值為1的時候代表產生的項目是android 1.1版本的工程,--target取值為2的時候代表產生的項目是android 1.5版本的工程,在上面的命令列中,我們建立的是取值為2的for 1.5版本的android應用程式項目。

(2)編譯項目
cd JniTest
ant debug
接著會看到如下的輸出:
Buildfile: build.xml
    [setup] Project Target: Android 1.5
    [setup] API level: 3

dirs:
     [echo] Creating output directories if needed...

resource-src:
     [echo] Generating R.java / Manifest.java from the resources...

aidl:
     [echo] Compiling aidl files into Java classes...

compile:
    [javac] Compiling 1 source file to /home/wayne/works/workspace/JniTest/bin/classes

dex:
     [echo] Converting compiled files and external libraries into bin/classes.dex...

package-resources:
     [echo] Packaging resources
 [aaptexec] Creating full resource package...

debug:
[apkbuilder] Creating .JniTest-debug.apk and signing it with a debug key...
[apkbuilder] Using keystore: /home/wayne/.android/debug.keystore

BUILD SUCCESSFUL
Total time: 6 seconds

ok,如果看到了類似偶的畫面,就代表你的命令列編譯環境編譯沒有問題。
下面就是驗證一下了:
cd bin
ls
如果看到了JniTest-debug.apk,呵呵,代表你的安裝包已經產生了(注意這裡是debug版本的安裝包,此時你可以啟動模擬器,然後用adb install,然後到模擬器上看看hello world的效果。汗,是不是太容易了?!)

(3)產生release版本的安裝包
剛剛是產生了debug版本的安裝包,那麼我們要產生release版本的該如何做呢?很容易,回到JniTest目錄,運行如下命令:
ant release
會看到如下輸出:
Buildfile: build.xml
    [setup] Project Target: Android 1.5
    [setup] API level: 3

dirs:
     [echo] Creating output directories if needed...

resource-src:
     [echo] Generating R.java / Manifest.java from the resources...

aidl:
     [echo] Compiling aidl files into Java classes...

compile:
    [javac] Compiling 1 source file to /home/wayne/works/workspace/JniTest/bin/classes

dex:
     [echo] Converting compiled files and external libraries into bin/classes.dex...

package-resources:
     [echo] Packaging resources
 [aaptexec] Creating full resource package...

release:
[apkbuilder] Creating .JniTest-unsigned.apk for release...
     [echo] All generated packages need to be signed with jarsigner before they are published.

BUILD SUCCESSFUL
Total time: 4 seconds

ok,這個時候請注意,這裡面有這樣一句:
[apkbuilder] Creating .JniTest-unsigned.apk for release...
 [echo] All generated packages need to be signed with jarsigner before they are published.
看來是產生了一個叫做JniTest-unsigned.apk的發布版安裝包,而且很“貼心”地告訴我們這個包需要做jarsigner的簽名(NND,都怪nokia帶了一個壞頭,現在給手機寫個稍微有點用處的程式無論什麼平台都要簽名。。。很不爽)

(4)為release版本的apk製作簽名
keytool -genkey -v -keystore waynechen.keystore -alias wayne -keyalg RSA -validity 10000
這裡是用了linux的一個工具來產生一個用於標明身份的key(anyway,偶的測試手機自然是被破解和刷過多次的,但是有一點可以肯定,不簽名即使是破解過的android G1也不能安裝那個unsigned的apk)。
上述命令運行完畢後,會產生一個叫做waynechen.keystore的簽名檔案,為了下一步jarsinger做準備。

(5)為unsigned的apk安裝包簽名
這個jarsigner不是android sdk提供的工具,而是jdk裡面提供的工具,因此,找不到這個工具的朋友可以查看jdk的bin路徑是否已經加入到當前的path裡面。
jarsigner -verbose -keystore waynechen.keystore JniTest-unsigned.apk wayne
簽過名以後的檔案仍然叫做JniTest-unsigned.apk,不過此時的apk檔案可是已經簽過名的了,可以在真機上面安裝。

好了,到此為止已經聒噪了一大堆通過命令列編譯android代碼的方法了,使用eclipse ide做開發的朋友可以直接跳過上述步驟(靠,現在才說,拍死你。。。)

2.jni的基本工作原理
(1)java的本質
想 搞明白jni的本質,還要從java的本質說起。從本質上來說,java這門語言就是一門指令碼語言(這是偶的個人理解,希望java大俠們不要用板磚拍 我),它的運行完全依賴於指令碼引擎對java的代碼進行解釋和執行(當然了,現代的java已經先進許多,可以從原始碼編譯成.class之類的中間格式 的二進位檔案,這種處理會大大地加快java指令碼的運行速度,但是基本的執行方式仍然不變,由指令碼引擎(我們稱之為JVM)來執行,與python、 perl之類的純指令碼相比,它只是把指令碼變成了二進位格式而已。另外就是java本身對物件導向的概念支援得很好,擁有完善的功能庫可供調用,把這個指令碼 引擎移植到所有平台上,那麼這個指令碼自然就實現所謂的“跨平台”了)。絕大多數的指令碼引擎都支援一個很顯著的特性,就是可以通過c/c++編寫模組,在腳 本中調用這些模組,以此來類比java,也是一樣的,java一定要提供一種在指令碼中調用c/c++編寫的模組的機制,才能稱得上是一個相對完善的指令碼引 擎。

(2)android中的java
android平台從本質上是 由arm-linux作業系統 和一個叫做dalvik的java虛擬機器組成的。所有在android模擬器上面看到的那些華麗的介面,都是用java語言編寫的(參見android平 台原始碼的frameworks/base目錄)。目前看來dalvik只是提供了一個標準的支援jni調用的java虛擬機器環境。android平台中 所有的硬體相關的操作均是採用jni技術進行了封裝,由java去調用jni模組,而jni模組使用c/c++調用android本身的arm- linux底層驅動。

例如,frameworks/base/libs/ui目錄下面有一個叫做“EGLDisplaySurface.cpp”的檔案,裡面的:
status_t EGLDisplaySurface::mapFrameBuffer()函數中,就有直接對android的arm-linux中的framebuffer的初始化代碼。

這也更加印證了,android其實是依靠java+jni建立起來的王國。hoho,如此一來,就凸顯出jni在android開發中的重要性(當然,一些簡單的小程式是完全可以只用java就搞定的).

本想寫一篇文章就記錄下來jni的編寫和調試方法的。。。
結果一不小心跑題了,把一些周邊的入門性的知識介紹了那麼多,只好下一篇再繼續說了。

相關文章

聯繫我們

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