顯示具有 android 標籤的文章。 顯示所有文章
顯示具有 android 標籤的文章。 顯示所有文章

2012年7月18日 星期三

Android之JNI

就如我第一篇android說的,我不是很關心android如何應用這樣的機制去寫作應用程式,但是本身卻對機制的原理相當感興趣,如果想要學會如何使用NDK做JNI可以參考參考資料,步驟大概如這張圖

針對JNI在Android上大概分成三層Java/App<=>JNI Lyaer<=>Native
因為有些動作只能在Native完成,所以不得不使用C語言,但是使用者介面又是以Java構成,要使兩者可以溝通就是透過JNI的機制
首先看Java code,必須使用System.loadLibrary載入相對應的share object(.so),對於native function則使用native關鍵字標示出來
 在java內已經宣告了java這邊的介面,用native表明到時候要透過JNI去呼叫Native程式,這時候用javah來編譯出C++ header file,使用JDK工具以特定格式去產生Native function的介面,這樣JNI才會認得兩邊的接口/介面,JNI這位中間人,就是依賴這樣的規則才能為兩邊牽線,下面是javah產生出來的.h檔案
跟著就是自行產生.cpp檔案,實作.h的介面

當呼叫System.loadLibrary的時候JNI會呼叫JNI_OnLoad函數,並且剖析share object(JNIEXPORT關鍵字做的手腳,export某些symbol),並且動態的將這些method註冊到JNI中,java code呼叫某個native method的時候其實是去尋找JNI中註冊表的method,來做呼叫

由於兩種程式語言的基本type並不相同,在兩者之間傳遞資料變成一件很重要的事情,所以如何對應呢?
<type>=>j<type>,如boolean(java)=>jboolean(c++),支援的type有boolean、byte、char、short、int、long、float、double

那麼如何在Native裡面呼叫java的某個物件的某個方法呢?其實如果熟悉Java Reflection這問題會容易解的多。
JNIEnv包含了JNI_OnLoad的時候做的資訊以及JVM的資訊,透過JNIEnv可以找到對應的class,再透過對應的class找出method與field,建構適當的signature就可執行某個object的method,跟Reflection的工作是大同小異的。


另外有個地方要注意的是,預設的狀況在Native並不會增加reference count,也就是說如果再Native functionm用static variable參考到某個object,並不表示下次來,這個object還會存在。可以使用env->NewGlobalRef(some_java_object)來取得global reference,但是要注意,這個global reference會使得garbage collect無法回收該物件,需要使用env->DeleteGlobalRef(some_java_object)來歸還


Native的exception是由JNI回報的,但是C++的異常蠻明顯不大相容於java,且處理很容易讓程式當掉,這時候JNIEnv可能用ExceptionOccured、ExceptionClear、ThrowNew報告異常

參考文件:
http://cheng-min-i-taiwan.blogspot.tw/2011/05/java-native-interface-jni-androidndk.html
http://blog.csdn.net/nicholas6lee/article/details/7324087
http://gyht0808.iteye.com/blog/763435
http://my.unix-center.net/~Simon_fu/?p=833

2012年7月17日 星期二

android架構

在Android架構,總共是由5個部份來組成。分別是:
(1)Applications(應用程式)
(2)Application Framework(應用程式架構)
(3)Libraries(函式庫)
(4)Android Runtime(Android執行環境)
(5)Linux Kernel(Linux核心)
大多數的網路資訊引用了類似這樣的圖形
我注意到比較有趣的是Binder (IPC) driver被嵌入了kernel,印象中這是android創建的IPC機制。許多人也知道android上的app開發大多是java,也就是java透過application framework在與底層的JNI以及Native的library做溝通,而我感興趣的就是底層的部分(application framework以下)
為何會對這部分有興致,主要想要操作camera以及最近遇到一個有人release出來的ICS版本,但是SD卡卻無法順利掛載,開始追蹤Vold這個deamon(android藉由uevent實作出來的一個動態掛載volumn的機制),或許就是為了喝牛奶養了一條牛吧XD
最後補上一個camera個架構圖
參考資料:
http://my.opera.com/ozzyyngwie/blog/android-an-open-mobile-platform
http://www.kandroid.org/online-pdk/guide/camera.html

2012年3月7日 星期三

android開發的第一步

很單純(應該吧)使用android sdk加上eclipse

  • 先下載sun的java sdk,我使用的是之前的1.6版本
  • 先到http://developer.android.com/sdk/index.html下載SDK starter,我下載的是installer_r16-windows.exe,這個會從網路下載SDK完整的套件下來安裝到電腦,以windows來說,會安裝到c:/Programming Files/Android/android-sdk
  • 過程中可能會詢問啥htcPhone或者MotoDEV之類的,我一律按下取消,可能是HTC或者Moto開發者特有的API吧,但是需要帳號密碼,沒有這個需求,就把它關閉了
  • 過程會詢問要安裝哪個平台,我選擇的2.3的平台
  • 跟著下載eclipse for java(此時eclipse classic為3.7),執行後,選擇[Help]=>[Install New Software],在裡面新增來源http://dl-ssl.google.com/android/eclipse/site.xml,跟著安裝Android DDMS & Android Development Tools
  • 安裝完畢eclipse會詢問要不要重新開啟,重開啟之後,選擇android SDK路徑,就是前幾步安裝的路徑
  • 接下來就可以在New Project裡面選擇[Android Project],跟著填寫相關資訊,就完成了一個基本的Project
  • 在工具列上面會有個Icon,類似一個機器人貼在一個機器內,[Open Android Virtual Devices Management],在裡面新增一個device
接下來可以打開Project,可以在裡面輸入code了,類似底下

package firsttask.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class FirstSimpleActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv=new TextView(this);
        tv.setText("hello , world!");
        setContentView(R.layout.main);
    }
}

跟著按下[run],他會詢問要執行哪個,選擇[android application],因為模擬器的關係,模擬器模擬一個很慢速cpu的模擬器,跑得很慢orz,可以去上個廁所再回來,因為再好的機器也快不起來
接著就會看到