Android NDK开发-一个初级程序

<div id="article_content" class="article_content">

<p>NDK开发,其实是为了项目需要调用底层的一些C/C++的一些东西;另外就是为了效率更加高些。如果你在Eclipse+ADT下开发过NDK就能体会到要么是配置NDK还要下载Cygwin,配置Cygwin ,然后需要编译生成,相当的蛋疼。要么是直接用Eclipse开发,但是前期配置也是一堆;真心蛋疼。但是现在在AS上Eclipse能做到的这边都OK,这边有的Eclipse上没有的,而且Google亲生的支持下只会越来越比Eclipse下开发NDK更加牛逼,所以你还不准备上手吗?</p>


<p>在AS开发NDK JNI也需要配置,不过相当Easy。第一步就是去官方下载个NDK包就可以了,像我的直接放在D盘就行了。关于怎么下载安装看这里 <a href="http://developer.android.com/tools/sdk/ndk/index.html#Revisions">AD NDK</a>会有介绍。</p>


<p>第二步就是就是直接写代码了。哈哈,你没听错,是这样的,方便吧?至于下载下来的NDK怎么和AS工程关联,也就是一行配置的问题,后文有说明带你一步一步体验。</p>


<p>But,还是要有个but,<a href="http://lib.csdn.net/base/android" class="replace_word" title="Android知识库" target="_blank" style="color:#df3434; font-weight:bold;">Android</a> Studio还不是个壮年,尤其在NDK开发中,所以本文只是工具性的演示,实质是教会大家NDK开发。</p>






<h2 id="lets-go">Let’s Go!!!</h2>


<p>在AS中新建一个Project,然后再新建一个class为NdkJniUtils,在内部声明native方法(jni使用的定义,后面系列教程会细说)。</p>






<pre class="prettyprint" name="code"><code class="language-java hljs  has-numbering"><span class="hljs-keyword">package</span> io.github.yanbober.ndkapplication;


<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NdkJniUtils</span> {</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">native</span> String <span class="hljs-title">getCLanguageString</span>();
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><div class="save_code tracking-ad" data-mod="popu_249" data-garbage="true"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul></pre>


<p>在工程主文件Activity中写入如下代码调运JNI的东西显示在UI上。</p>






<pre class="prettyprint" name="code"><code class="language-java hljs  has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ActionBarActivity</span> {</span>
    <span class="hljs-keyword">private</span> TextView mTextView;


    <span class="hljs-annotation">@Override</span>
    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mTextView = (TextView) <span class="hljs-keyword">this</span>.findViewById(R.id.test);


        NdkJniUtils jni = <span class="hljs-keyword">new</span> NdkJniUtils();


        mTextView.setText(jni.getCLanguageString());
    }
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><div class="save_code tracking-ad" data-mod="popu_249" data-garbage="true"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul></pre>


<p>然后build project得到其中中间文件,我们关注的是.class文件。编译OK以后生成的class文件在AS工程的如下目录:</p>


<pre><code>NDKApplication\app\build\intermediates\classes\debug
</code></pre>


<p>然后接下来的步骤就是根据生成的class文件,利用javah生成对应的 .h头文件。</p>


<p>点开AS的Terminal标签,默认进入到该项目的app文件夹下。我在windows平台下输入如下命令跳转到class中间文件生成路径:</p>


<pre><code>xxxxx\app&gt; cd build\intermediates\classes\debug
</code></pre>


<p>然后执行如下javah命令生成h文件。</p>


<pre><code>xxxxx\debug&gt; javah -jni io.github.yanbober.ndkapplication.NdkJniUtils
</code></pre>


<p>执行完之后你可以在文件夹NDKApplication\app\build\intermediates\classes\debug下看见生成的 .h头文件为:</p>


<pre><code>io_github_yanbober_ndkapplication_NdkJniUtils.h
</code></pre>


<p>其内容为:</p>






<pre class="prettyprint" name="code"><code class="language-c++ hljs vala has-numbering"><span class="hljs-comment" data-garbage="true">/* DO NOT EDIT THIS FILE - it is machine generated */</span>
<span class="hljs-preprocessor">#include &lt;jni.h&gt;</span>
<span class="hljs-comment" data-garbage="true">/* Header for class io_github_yanbober_ndkapplication_NdkJniUtils */</span>


<span class="hljs-preprocessor">#ifndef _Included_io_github_yanbober_ndkapplication_NdkJniUtils</span>
<span class="hljs-preprocessor">#define _Included_io_github_yanbober_ndkapplication_NdkJniUtils</span>
<span class="hljs-preprocessor">#ifdef __cplusplus</span>
extern <span class="hljs-string">"C"</span> {
<span class="hljs-preprocessor">#endif</span>
<span class="hljs-comment" data-garbage="true">/*
 * Class:     io_github_yanbober_ndkapplication_NdkJniUtils
 * Method:    getCLanguageString
 * Signature: ()Ljava/lang/String;
 */</span>
JNIEXPORT jstring<span class="hljs-constant"> JNICALL </span>Java_io_github_yanbober_ndkapplication_NdkJniUtils_getCLanguageString
  (JNIEnv *, jobject);


<span class="hljs-preprocessor">#ifdef __cplusplus</span>
}
<span class="hljs-preprocessor">#endif</span>
<span class="hljs-preprocessor">#endif</span></code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><div class="save_code tracking-ad" data-mod="popu_249" data-garbage="true"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul></pre>


<p>在工程的main目录下新建一个名字为jni的目录,然后将刚才的 .h文件剪切过来。在jni目录下新建一个c文件,随意取名,我的叫jnitest.c 。然后编辑代码如下(后面会解释啥意思,这里重在工具使用):</p>






<pre class="prettyprint" name="code"><code class="language-c++ hljs scala has-numbering">#include <span class="hljs-string">"io_github_yanbober_ndkapplication_NdkJniUtils.h"</span>
<span class="hljs-comment" data-garbage="true">/*
 * Class:     io_github_yanbober_ndkapplication_NdkJniUtils
 * Method:    getCLanguageString
 * Signature: ()Ljava/lang/String;
 */</span>
JNIEXPORT jstring JNICALL Java_io_github_yanbober_ndkapplication_NdkJniUtils_getCLanguageString
  (JNIEnv *env, j<span class="hljs-class"><span class="hljs-keyword">object</span> <span class="hljs-title">obj</span>){</span>
     <span class="hljs-keyword">return</span> (*env)-&gt;NewStringUTF(env,<span class="hljs-string">"This just a test for Android Studio NDK JNI developer!"</span>);
  }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul><div class="save_code tracking-ad" data-mod="popu_249" data-garbage="true"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li></ul></pre>


<p>接下来在工程的local.properties文件中添加NDK路径(上面下载好的那个NDK),类似其中的SDK路径一样,我的添加后如下:</p>






<pre class="prettyprint" name="code"><code class="language-java hljs  has-numbering">sdk.dir=D\:\\AndroidStdioSDK\\sdk
#add by 工匠若水
ndk.dir=D\:\\AndroidStdioSDK\\android-ndk-r10d-<span class="hljs-number">64</span>bit</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249" data-garbage="true"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>


<p>接下来在app module目录下的build.gradle中设置库文件名(生成的so文件名)。找到gradle文件的defaultConfig这项,在里面添加如下内容:</p>






<pre class="prettyprint" name="code"><code class="language-groovy hljs lasso has-numbering">defaultConfig {
    <span class="hljs-attribute">...</span><span class="hljs-attribute">...</span>
    ndk{
        moduleName <span class="hljs-string">"YanboberJniLibName"</span>         <span class="hljs-comment" data-garbage="true">//生成的so名字</span>
        abiFilters <span class="hljs-string">"armeabi"</span>, <span class="hljs-string">"armeabi-v7a"</span>, <span class="hljs-string">"x86"</span>  <span class="hljs-comment" data-garbage="true">//输出指定三种abi体系结构下的so库。目前可有可无。</span>
    }
}</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><div class="save_code tracking-ad" data-mod="popu_249" data-garbage="true"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul></pre>


<p>现在生成的so库名字也有了,那就去代码的NdkJniUtils <a href="http://lib.csdn.net/base/javase" class="replace_word" title="Java SE知识库" target="_blank" style="color:#df3434; font-weight:bold;">Java</a>文件添加静态初始化load代码,添加如下:</p>






<pre class="prettyprint" name="code"><code class="language-java hljs  has-numbering"><span class="hljs-keyword">static</span> {
        System.loadLibrary(<span class="hljs-string">"YanboberJniLibName"</span>);   <span class="hljs-comment" data-garbage="true">//defaultConfig.ndk.moduleName</span>
    }</code><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249" data-garbage="true"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>


<p>好了,到此AS下NDK JNI开发的代码编写和设置就OK了,接下来就是编译工程运行就可以了。</p>


<p>但是有些电脑好奇怪此时编译会报错,妹的,没辙,后来网上找到答案说这是NDK在Windows下一个bug,当只编译一个单一文件时出现,解决办法就是再添加一个空的文件就行了,这个网站有介绍:<a href="http://ph0b.com/android-studio-gradle-and-ndk-integration/">NDK在Windows的一个bug</a>。不过你要是刚才能顺利编译就没必要蛋疼这个问题了。</p>


<p>好了,我的编译运行结果如下:</p>


<p><img src="https://img-blog.csdn.net/20150427161306087" alt="这里写图片描述" title=""></p>


<p>到此为止简单的体验AS下NDK开发的过程就结束了。</p>


   
</div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值