使用QtCreator加速Android NDK开发调试

pygd5401 8年前
   <p>为APP开发JNI接口以及NDK动态库的时候,需要频繁修改和调试C/C++代码,如果在eclipse或AndroidStudio开发的话,需要1)clean项目,2)ndk build 3)生成APK,启动调试,实际会卸载已安装APK再装一遍,这个过程相当耗时,快则7秒左右,慢则十几秒以上,有没有可能不需要重新安装APK,只需要替换它的so库,重启APP就能自动加载生效?即:</p>    <ul>     <li> <p>执行ndk-build生成so</p> </li>     <li> <p>替换APP在手机上已安装的so库</p> </li>     <li> <p>重启APP</p> </li>    </ul>    <p>经过摸索发现可以,整个过程时间缩短为3秒左右。但替换so需要root权限,如果没有root权限怎么办?以下介绍在不需要root权限的环境下实现的方法。</p>    <p>第一步:先将so文件push到sdcard上:</p>    <pre>  adb push libkplayer.so /sdcard/</pre>    <p>第二步:进入shell,并且换APP的身份:</p>    <pre>  adb shell  run-as com.xxx.jkplayer  #APP包名</pre>    <p>这时shell自动切换到/data/data/com.xxx.jkplayer目录下,此目录是可写的,而原来打包在APP里的so库存放在/data/data/com.xxx.jkplayer/lib/下是不可写,所以解决的方法是将修改好的so库copy到/data/data/com.xxx.jkplayer,这需要在JAVA层稍为修改一下加载库的方法:</p>    <pre>  //System.loadLibrary("jkplayer");  System.load("/data/data/com.xxx.jkplayer/libjkplayer.so");</pre>    <p>重新编译和安装APK,这时启动时会提示loadLibrary失败,没关系,做完下一步就可以了。</p>    <p>第三步:从/sdcard上copy过来并赋予可执行权限:</p>    <pre>  cp /sdcard/libjkplayer.so .  #当前目录在/data/data/com.xxx.jkplayer  chmod 0755 libjkplayer.so </pre>    <p>现在重新启动APP,就可以成功把/data/data/com.xxx.jkplayer/libjkplayer.so load起来,下次我们只需要替换掉这个so,重启APP就可以了,而不需要点AndroidStudio调试按钮了。</p>    <p>我们当然希望写一个脚本来自动实现替换so并重启APP的动作,启动APP:</p>    <pre>  adb shell am start -n com.xxx.jkplayer/com.xxx.jkplayer.MainActivity</pre>    <p>重启之前,可以先强行停止APP:</p>    <pre>  adb shell am force-stop com.xxx.jkplayer</pre>    <p>将这些脚本和ndk-build等组合在一起,每次修改完C/C++代码后,执行脚本,只需要3秒左右APP已经重启就绪。下面我介绍如何为QtCreator IDE配置这些脚本,并且只需要点一个run按钮或ctrl+r就能直接跑起这个脚本,还能显示编译错误和点击定位错误,还能在QtCreator中看到Android的log输出。</p>    <p>为什么使用QtCreator(不需要装QtSDK)?因为它用来写C/C++代码,轻量级跨平台,代码补全高亮不在话下,书签、代码大纲、编辑器分栏、快捷键都挺好使。 好吧,真正是因为我一直用它,所以觉得顺手。</p>    <p>ndk-build编译错误提示,点击错误跳转到源代码处</p>    <p><img src="https://simg.open-open.com/show/eeac394002df1d6156c21cf2a2ad759c.png"></p>    <p>ndk-build的编译输出窗口,也可以通过配置将logcat的日志显示到此窗口来。</p>    <p><img src="https://simg.open-open.com/show/231f66355656644091f53646e0482a51.png"></p>    <p>JNI API 自动补全:</p>    <p><img src="https://simg.open-open.com/show/31e1e902dde9a470dd27fbf07a255305.png"></p>    <p>经常与JNI打资产,如果靠手工查手册就欲哭无泪了-_-~~也可以配置使得NDK里的库函数和头文件都可以补全,代码阅读时点击跳转。</p>    <p>下面介绍配置过程。</p>    <p>第一步:import jni目录,完成后,保存所有,QtCreator的工程文件也会保存在import目录下</p>    <p><img src="https://simg.open-open.com/show/ecd30161dc485de99fa799def0eea25c.png"></p>    <p>第二步:进入项目属性,删除默认的构建步骤(ctrl+b时调用),添加自己的:</p>    <p><img src="https://simg.open-open.com/show/bf72ef51db3b718a2498e0e3090f15eb.png"></p>    <p>其中的 %{buildDir}\build.bat 指的是Qt工程(xxxx.qtcreator)所在目录下的build.bat脚本,内容为:</p>    <pre>  $NDK\ndk-build    -c jni</pre>    <p>NDK为指向ndk sdk根目录的环境变量, -c 参数指向你jni工程目录,即里面存放c/c++/Android.mk等,如果Qt工程建在jni目录下, -c jni 不需要。</p>    <p>clear.bat的内容:</p>    <pre>  $NDK\ndk-build -c jni clear</pre>    <p>第三步:添加自定义的执行步骤(ctrl+r时调用):</p>    <p><img src="https://simg.open-open.com/show/877875622d59a3e4a4110f30f975f79a.png"></p>    <p>run.bat:</p>    <pre>  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</pre>    <p>executable.bat:</p>    <pre>  adb shell "logcat -c && logcat -v time | grep -i xxx" #将logcat输出到QtCreator上来</pre>    <p>实际使用发现这样打印出来的每行log都被追加了一个空行。当然,你也可以使用AndroidStudio的日志查看器。OK,现在已经可以用了,编写代码,ctrl+r一下,编译、部署so、重启APP,一步到位。</p>    <p>最后附上代码补全设置:</p>    <p><img src="https://simg.open-open.com/show/bc270f002d3852fd9b5ea899bb0d49d0.png"></p>    <p>保存后,QtCreator会自动reload,编辑器就立刻高亮JNI和NDK函数,按住ctrl键,将鼠标移到符号上点击就可以跳转,alt+左箭头返回。</p>    <p> </p>    <p>来自: <a href="/misc/goto?guid=4959670822019400625" rel="nofollow">https://segmentfault.com/a/1190000004946441</a></p>