使用QtCreator加速Android NDK開發調試
為APP開發JNI接口以及NDK動態庫的時候,需要頻繁修改和調試C/C++代碼,如果在eclipse或AndroidStudio開發的話,需要1)clean項目,2)ndk build 3)生成APK,啟動調試,實際會卸載已安裝APK再裝一遍,這個過程相當耗時,快則7秒左右,慢則十幾秒以上,有沒有可能不需要重新安裝APK,只需要替換它的so庫,重啟APP就能自動加載生效?即:
-
執行ndk-build生成so
-
替換APP在手機上已安裝的so庫
-
重啟APP
經過摸索發現可以,整個過程時間縮短為3秒左右。但替換so需要root權限,如果沒有root權限怎么辦?以下介紹在不需要root權限的環境下實現的方法。
第一步:先將so文件push到sdcard上:
adb push libkplayer.so /sdcard/
第二步:進入shell,并且換APP的身份:
adb shell run-as com.xxx.jkplayer #APP包名
這時shell自動切換到/data/data/com.xxx.jkplayer目錄下,此目錄是可寫的,而原來打包在APP里的so庫存放在/data/data/com.xxx.jkplayer/lib/下是不可寫,所以解決的方法是將修改好的so庫copy到/data/data/com.xxx.jkplayer,這需要在JAVA層稍為修改一下加載庫的方法:
//System.loadLibrary("jkplayer"); System.load("/data/data/com.xxx.jkplayer/libjkplayer.so");
重新編譯和安裝APK,這時啟動時會提示loadLibrary失敗,沒關系,做完下一步就可以了。
第三步:從/sdcard上copy過來并賦予可執行權限:
cp /sdcard/libjkplayer.so . #當前目錄在/data/data/com.xxx.jkplayer chmod 0755 libjkplayer.so
現在重新啟動APP,就可以成功把/data/data/com.xxx.jkplayer/libjkplayer.so load起來,下次我們只需要替換掉這個so,重啟APP就可以了,而不需要點AndroidStudio調試按鈕了。
我們當然希望寫一個腳本來自動實現替換so并重啟APP的動作,啟動APP:
adb shell am start -n com.xxx.jkplayer/com.xxx.jkplayer.MainActivity
重啟之前,可以先強行停止APP:
adb shell am force-stop com.xxx.jkplayer
將這些腳本和ndk-build等組合在一起,每次修改完C/C++代碼后,執行腳本,只需要3秒左右APP已經重啟就緒。下面我介紹如何為QtCreator IDE配置這些腳本,并且只需要點一個run按鈕或ctrl+r就能直接跑起這個腳本,還能顯示編譯錯誤和點擊定位錯誤,還能在QtCreator中看到Android的log輸出。
為什么使用QtCreator(不需要裝QtSDK)?因為它用來寫C/C++代碼,輕量級跨平臺,代碼補全高亮不在話下,書簽、代碼大綱、編輯器分欄、快捷鍵都挺好使。 好吧,真正是因為我一直用它,所以覺得順手。
ndk-build編譯錯誤提示,點擊錯誤跳轉到源代碼處
ndk-build的編譯輸出窗口,也可以通過配置將logcat的日志顯示到此窗口來。
JNI API 自動補全:
經常與JNI打資產,如果靠手工查手冊就欲哭無淚了-_-~~也可以配置使得NDK里的庫函數和頭文件都可以補全,代碼閱讀時點擊跳轉。
下面介紹配置過程。
第一步:import jni目錄,完成后,保存所有,QtCreator的工程文件也會保存在import目錄下
第二步:進入項目屬性,刪除默認的構建步驟(ctrl+b時調用),添加自己的:
其中的 %{buildDir}\build.bat 指的是Qt工程(xxxx.qtcreator)所在目錄下的build.bat腳本,內容為:
$NDK\ndk-build -c jni
NDK為指向ndk sdk根目錄的環境變量, -c 參數指向你jni工程目錄,即里面存放c/c++/Android.mk等,如果Qt工程建在jni目錄下, -c jni 不需要。
clear.bat的內容:
$NDK\ndk-build -c jni clear
第三步:添加自定義的執行步驟(ctrl+r時調用):
run.bat:
adb shell am force-stop com.xxx.jkplayer adb push libs\armeabi-v7a\libjkplayer.so /sdcard/ && adb shell "run-as com.xxx.jkplayer cp -v /sdcard/libjkplayer.so ." && adb shell "run-as com.xxx.jkplayer chmod 0755 libjkplayer.so" && adb shell am start -n com.xxx.jkplayer/com.xxx.jkplayer.MainActivity
executable.bat:
adb shell "logcat -c && logcat -v time | grep -i xxx" #將logcat輸出到QtCreator上來
實際使用發現這樣打印出來的每行log都被追加了一個空行。當然,你也可以使用AndroidStudio的日志查看器。OK,現在已經可以用了,編寫代碼,ctrl+r一下,編譯、部署so、重啟APP,一步到位。
最后附上代碼補全設置:
保存后,QtCreator會自動reload,編輯器就立刻高亮JNI和NDK函數,按住ctrl鍵,將鼠標移到符號上點擊就可以跳轉,alt+左箭頭返回。