原本前面文章有寫如何簡化外部工具javah來產生jni需要的c語言header file,最近呼叫jni有需要傳入AssetManagrt,原本的參數沒有傳入java 的AssetManager classes的原型因此會遇到Error: Cannot determine signature for AssetManager的錯誤,這時候在之前寫的javah引用參數 "-v -jni -d $ModuleFileDir$\src\main\jni $FileClass$"小改一下,把sdk的使用版本內的android.jar給傳入就可以,改寫成"-v -jni -d $ModuleFileDir$\src\main\jni -classpath E:\AndroidSdk\platforms\android-16\android.jar;. $FileClass$",因為我專案設定的minisdk是16,所以我就用android-16的android.jar當成解讀java classes的參數填入,這樣設定好,跑一下設定的javah外部工具,這樣就會產生需要的jni c語言header file了。
- 7月 16 週六 201620:24
Error: Cannot determine signature for AssetManager
- 6月 30 週四 201609:57
NDK無法使用c++11特性to_string函數的用法
在NDK中寫一些東西,剛好遇到要把int、long 轉成string,原本是要用c++11的函數 to_string來自動轉格式, 編譯參數也指定c++11了,但是NDK就是說找不到這個函數,問問google大神才發現NDK沒有實作出全部的c++11特性出來,網路上剛好有人寫了一個函數就拿來用 程式碼如下:
#include <string>
#include <sstream>
template <typename T>
std::string to_string(T value)
{
std::ostringstream os ;
os << value ;
return os.str() ;
}
int main()
{
std::string perfect = to_string(5) ;
}
#include <string>
#include <sstream>
template <typename T>
std::string to_string(T value)
{
std::ostringstream os ;
os << value ;
return os.str() ;
}
int main()
{
std::string perfect = to_string(5) ;
}
- 6月 16 週四 201620:14
NDK裡__android_log_print參數uint64_t編譯告警問題
今天用到一個read去讀取eventfd,結果想看看內容,用__android_log_print要顯示出內容,發現內容值的型態是uint64_t,編譯出現了這樣的告警:
warning: format '%lld' expects argument of type 'long long int', but argument 5 has type 'uint64_t {aka long unsigned int}' [-Wformat=]
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
warning: format '%lld' expects argument of type 'long long int', but argument 5 has type 'uint64_t {aka long unsigned int}' [-Wformat=]
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
- 6月 15 週三 201621:46
NDK編譯遇到error: 'SYS_clock_gettime' was not declared in this scope
因為需要用到不受NTP影響的抓取系統時間函數,因此呼叫syscall(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, &ts);
結果遇到了error: 'SYS_clock_gettime' was not declared in this scope的編譯錯誤,查了一下NDK的版本原始碼,發現APP_PLATFORM := android-21可以正常呼叫,android-21以前的版本沒有SYS_clock_gettime的定義,查一下android-16的linux-syscalls.h內容,他是定義成__NR_clock_gettime,因為我的minSDK是android-16,所以就改成syscall(__NR_clock_gettime, CLOCK_MONOTONIC_RAW, &ts); 就可以編譯成功了,測試函數也正常。
結果遇到了error: 'SYS_clock_gettime' was not declared in this scope的編譯錯誤,查了一下NDK的版本原始碼,發現APP_PLATFORM := android-21可以正常呼叫,android-21以前的版本沒有SYS_clock_gettime的定義,查一下android-16的linux-syscalls.h內容,他是定義成__NR_clock_gettime,因為我的minSDK是android-16,所以就改成syscall(__NR_clock_gettime, CLOCK_MONOTONIC_RAW, &ts); 就可以編譯成功了,測試函數也正常。
- 6月 15 週三 201615:22
NDK編譯發生fatal error: sys/eventfd.h: No such file or directory
因為C++方面用到eventfd,所以按慣例引入宣告檔#include <sys/eventfd.h>,沒想到NDK編譯出現fatal error: sys/eventfd.h: No such file or directory這樣的錯誤,查了一下,在Application.mk裡放一行編譯參數就可以了,參數如下:
APP_PLATFORM := android-16
APP_PLATFORM := android-16
- 5月 26 週四 201613:46
Android Studio中Button的text都是大寫
在Button的XML宣告中增加:
android:textAllCaps="false"
android:textAllCaps="false"
- 5月 21 週六 201617:36
android studio增加javap工具

進入android studio的External tools設定,然後按一下+號,然後填入Name、Description、Program、Parameters、Working directory等需要填入的值。
Name: 填入工具會顯示的名稱,"javap"還滿容易看懂.
- 5月 18 週三 201621:08
jstring 轉成char的方法
以下資料是做個紀錄
//C++ code
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
//Get the native string from javaString
const char *nativeString = env->GetStringUTFChars(javaString, 0);
//Do something with the nativeString
//DON'T FORGET THIS LINE!!!
env->ReleaseStringUTFChars(javaString, nativeString);
}
//C++ code
extern "C"
JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj, jstring javaString)
{
//Get the native string from javaString
const char *nativeString = env->GetStringUTFChars(javaString, 0);
//Do something with the nativeString
//DON'T FORGET THIS LINE!!!
env->ReleaseStringUTFChars(javaString, nativeString);
}
- 5月 10 週二 201609:10
ndk-build常用參數紀錄
NDK是一套用來實現APP執行原生碼(native-code)的工具,白話點講就是把c/c++的語法按參數和不同CPU編譯成二進制CPU碼.以下是遇到的參數說明.
NDK_LIBS_OUT: 指定編譯好的lib檔(.so)要放哪裡.範例: ndk-build NDK_LIBS_OUT=../jniLibs
NDK_LIBS_OUT: 指定編譯好的lib檔(.so)要放哪裡.範例: ndk-build NDK_LIBS_OUT=../jniLibs
- 4月 29 週五 201615:30
minSdkVersion,targetSdkVersion,target說明
1.檔案AndroidManifest.xml
<uses-sdk android:minSdkVersion="19" />
<uses-sdk android:targetSdkVersion="23" />
有關裡面的數字是代表Android的版本,詳細說明可以看
http://developer.android.com/intl/zh-tw/guide/topics/manifest/uses-sdk-element.html
minSdkVersion就是說這個APP所支援的最小版本,會影響安裝或是app store檢查到手機上版本不相容而不能下載安裝。不過這是開發者的設定,無關實際上是不是能真的在minSdkVersion設定的範圍外或範圍內平台執行。
<uses-sdk android:minSdkVersion="19" />
<uses-sdk android:targetSdkVersion="23" />
有關裡面的數字是代表Android的版本,詳細說明可以看
http://developer.android.com/intl/zh-tw/guide/topics/manifest/uses-sdk-element.html
minSdkVersion就是說這個APP所支援的最小版本,會影響安裝或是app store檢查到手機上版本不相容而不能下載安裝。不過這是開發者的設定,無關實際上是不是能真的在minSdkVersion設定的範圍外或範圍內平台執行。
