本文介紹了如何使用VisualStudio高效開發調試AndroidNDK,分享給大家,具體如下:
場景
常見的做法是:
1. 使用編輯器或者編譯器編寫C++代碼。
2. 使用NDK命令編譯SO。
3. 重新打包APK,或者直接替換APK中的SO文件再重簽名。
4. 安裝到手機。
5. 運行。
6. 崩潰。
7. 排錯。
如此往復,有限的時間和精力在無限的編譯和調試之中全部都耗完。
當然會問:為啥不用AndroidStudio自帶的NDK開發,試過,不好用。這里推薦一種方法,搭建很簡單,使用起來很方便又節省時間,分享給大家。
步驟
以vs2008為例(高版本亦可,不知道vs2017是不是對NDK開發支持的很好了,一直沒敢嘗試)
新建VS解決方案,添加源碼
新建一個空的解決方案,然后把自己編寫的c++的頭文件和源文件都添加進來。


設置VS工程屬性
項目屬性“常規”-“配置類型”修改為“生成文件”:

添加頭文件包含,啟動自動代碼完成
這里主要是把NDK開發的include目錄包含進來, 打開vs“工具”-“選項”-“項目和解決方案”-“VC++目錄”,設置包含文件目錄新增“D:/ndk/platforms/android-19/arch-x86/usr/include”:

手動把D:/ndk/platforms/android-19/arch-x86/usr/include目錄下的jni.h拖入VS中打開,此時VAX開始自動索引,這時候JNI開發相關的關鍵字便可以正常識別了。使用自動提示寫起來就比較快速,而且也不容易出錯。

配置自動化腳本

其中build.bat腳本:
set dir=%~dp0set modulename=testset modulefile=../libs/armeabi/lib%modulename%.socd /d %dir%call ./ndk.batif exist %modulefile% ( copy %modulefile% ../main/jniLibs/armeabi/lib%modulename%.so call ./debug.bat com.bigsing.hooktest)
編譯成功后會根據JNI在AndroidStudio項目工程的位置把SO文件復制到對應的libs目錄下。最重要的步驟就是后面調用debug.bat的腳本地方,后面再說。
其中clean.bat腳本:
set dir=%~dp0set ndk=d:/Android/ndk/ndk-build.cmdcd /d %dir%if exist %ndk% ( %ndk% clean)else ( ndk-build clean)
這個是清理用的。
其中debug.bat腳本需要一個參數,就是你當前測試APK的包名,注意我上面調用的方式是:==call ./debug.bat com.bigsing.hooktest==,需要你測試的APP已經在手機中安裝過,腳本會刪除已經存在的SO文件,然后導入新編譯好的SO。
set dir=%~dp0set package=%1%set modulename=testset modulefile=../libs/armeabi/lib%modulename%.soset destso=/data/data/%package%/lib/lib%modulename%.socd /d %dir%echo offif exist %modulefile% ( echo 1.delete old file: %destso% adb shell "su -c ' rm %destso%'" echo 2.push so to /data/local/tmp adb push %dir%%modulefile% /data/local/tmp/lib%modulename%.so echo 3.copy so to /data/data/%package%/lib adb shell "su -c ' cp /data/local/tmp/lib%modulename%.so /data/data/%package%/lib'" echo 4.chmod 755 so adb shell "su -c ' chmod 755 /data/data/%package%/lib/lib%modulename%.so'" echo success echo u can rm other data here... adb shell "su -c ' rm -r /data/data/%package%/databases'" adb shell "su -c ' rm -r /data/data/%package%/shared_prefs'" adb shell "su -c ' rm -r /data/data/%package%/cache'")else ( echo error! file not found: %dir%%modulefile%)echo on
編譯
在VS里直接按F7會執行編譯操作,便會調用【生成命令行】build.bat,如果代碼編寫得沒有問題,則會產生如下類似日志:
1>------ 已啟動生成: 項目: HookTest, 配置: Debug Win32 ------1>正在執行生成文件項目操作1>[armeabi] Compile++ thumb: test <= test.cpp1>[armeabi] SharedLibrary : libtest.so1>[armeabi] Install : libtest.so => libs/armeabi/libtest.so1>已復制 1 個文件。1>1.delete old file: /data/data/com.bigsing.hooktest/lib/libtest.so1>2.push so to /data/local/tmp1>[ 78%] /data/local/tmp/libtest.so1>[100%] /data/local/tmp/libtest.so1>f:/svnlocal/hooktest/app/src/jni/../libs/armeabi/libtest.so: 1 file pushed. 3.3 MB/s (83248 bytes in 0.024s)1>3.copy so to /data/data/com.bigsing.hooktest/lib1>4.chmod 755 so1>success1>生成日志保存在“file://f:/svnlocal/hooktest/app/src/jni/src/Debug/BuildLog.htm”1>HookTest - 0 個錯誤,0 個警告========== 生成: 成功 1 個,失敗 0 個,最新 0 個,跳過 0 個 ==========
如果編譯出錯,會產生如下類似日志:
1>------ 已啟動生成: 項目: HookTest, 配置: Debug Win32 ------1>正在執行生成文件項目操作1>[armeabi] Compile++ thumb: test <= test.cpp1>f:/svnlocal/hooktest/app/src//jni/src/test.cpp: In function '_jstring* Java_com_bigsing_hooktest_NativeHandler_getString(JNIEnv*, jclass, jobject, jint, jstring)':1>f:/svnlocal/hooktest/app/src//jni/src/test.cpp:35:1: error: expected unqualified-id before '}' token1> }1> ^1>f:/svnlocal/hooktest/app/src//jni/src/test.cpp:35:1: error: expected ';' before '}' token1>f:/svnlocal/hooktest/app/src//jni/src/test.cpp: In function '_jstring* getInfo(JNIEnv*, jclass, jobject, jint, jstring)':1>f:/svnlocal/hooktest/app/src//jni/src/test.cpp:73:2: error: expected unqualified-id before '}' token1> }else if((int)paramInt == 2){1> ^1>f:/svnlocal/hooktest/app/src//jni/src/test.cpp:73:2: error: expected ';' before '}' token1>make.exe: *** [f:/svnlocal/hooktest/app/src//obj/local/armeabi/objs/test/src/test.o] Error 11>生成日志保存在“file://f:/svnlocal/hooktest/app/src/jni/src/Debug/BuildLog.htm”1>HookTest - 4 個錯誤,0 個警告========== 生成: 成功 0 個,失敗 1 個,最新 0 個,跳過 0 個 ==========其實很容易找到出錯的源碼文件及對應的行號。
節省了哪些時間?
1、蹩腳編輯器開發C++浪費的時間
借助VS和VAX強大的索引和自動完成代碼來節省開發時間,保證代碼的正確性。
2、重新編譯APK的時間
整個過程不需要重新編譯AndroidStudio工程。
3、重新簽名的時間
整個過程不需要簽名APK包。
4、安裝APK的時間
只需安裝一次APK包,后面調試測試的時候均無需安裝APK包。
原理與總結
只要APK安裝一次之后,它的SO路徑就固定了,就在/data/data/包名/lib/下,因此我們可以在編譯成功后,把原SO文件刪除,然后把新編譯的SO文件push到lib目錄下,最后重新運行一下APP就會加載新的SO了。
如果擔心數據緩存會對測試造成影響,則可以在腳本中編寫刪除緩存文件的命令(上面的腳本會刪除cache、database、shared_prefs目錄),如果有需要還可以編寫自動殺死已經在運行的APP并自動打開的命令。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答