如何在Android下使用JNI

\u5982\u4f55\u5728Android\u4e0b\u4f7f\u7528JNI

\u3000\u3000\u6211\u4eec\u77e5\u9053\uff0cAndroid\u7cfb\u7edf\u7684\u5e95\u5c42\u5e93\u7531c/c++\u7f16\u5199\uff0c\u4e0a\u5c42Android\u5e94\u7528\u7a0b\u5e8f\u901a\u8fc7Java\u865a\u62df\u673a\u8c03\u7528\u5e95\u5c42\u63a5\u53e3\uff0c\u8854\u63a5\u5e95\u5c42c/c++\u5e93\u4e0eJava\u5e94\u7528\u7a0b\u5e8f\u95f4\u7684\u63a5\u53e3\u6b63\u662fJNI\uff08JavaNative Interface)\u3002\u672c\u6587\u63cf\u8ff0\u4e86\u5982\u4f55\u5728ubuntu\u4e0b\u914d\u7f6eAndroidJNI\u7684\u5f00\u53d1\u73af\u5883\uff0c\u4ee5\u53ca\u5982\u4f55\u7f16\u5199\u4e00\u4e2a\u7b80\u5355\u7684c\u51fd\u6570\u5e93\u548cJNI\u63a5\u53e3\uff0c\u5e76\u901a\u8fc7\u7f16\u5199Java\u7a0b\u5e8f\u8c03\u7528\u8fd9\u4e9b\u63a5\u53e3\uff0c\u6700\u7ec8\u8fd0\u884c\u5728\u6a21\u62df\u5668\u4e0a\u7684\u8fc7\u7a0b\u3002

\u3000\u30002.\u73af\u5883\u914d\u7f6e

\u3000\u30002.1.\u5b89\u88c5jdk1.6
\u3000\u3000\uff081\uff09\u4ecejdk\u5b98\u65b9\u7f51\u7ad9\u4e0b\u8f7djdk-6u29-linux-i586.bin\u6587\u4ef6\u3002
\u3000\u3000\uff082\uff09\u6267\u884cjdk\u5b89\u88c5\u6587\u4ef6
\u3000\u3000[html] view plaincopyprint?
\u3000\u300001.$chmod a+x jdk-6u29-linux-i586.bin
\u3000\u300002.$jdk-6u29-linux-i586.bin
\u3000\u3000$chmod a+x jdk-6u29-linux-i586.bin
\u3000\u3000$jdk-6u29-linux-i586.bin
\u3000\u3000(3)\u914d\u7f6ejdk\u73af\u5883\u53d8\u91cf

\u3000\u3000[html] view plaincopyprint?
\u3000\u300001.$sudo vim /etc/profile
\u3000\u300002.#JAVAEVIRENMENT
\u3000\u300003.exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
\u3000\u300004.exportJRE_HOME=$JAVA_HOME/jre
\u3000\u300005.exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
\u3000\u300006.exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
\u3000\u3000$sudo vim /etc/profile
\u3000\u3000#JAVAEVIRENMENT
\u3000\u3000exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
\u3000\u3000exportJRE_HOME=$JAVA_HOME/jre
\u3000\u3000exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
\u3000\u3000exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
\u3000\u3000\u4fdd\u5b58\u540e\u9000\u51fa\u7f16\u8f91\uff0c\u5e76\u91cd\u542f\u7cfb\u7edf\u3002

\u3000\u3000\uff084\uff09\u9a8c\u8bc1\u5b89\u88c5

\u3000\u3000[html] view plaincopyprint?
\u3000\u300001.$java -version
\u3000\u300002.javaversion "1.6.0_29"
\u3000\u300003.Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
\u3000\u300004.JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
\u3000\u300005.$javah
\u3000\u300006.\u7528\u6cd5\uff1ajavah[\u9009\u9879]
\u3000\u300007.\u5176\u4e2d[\u9009\u9879]\u5305\u62ec\uff1a
\u3000\u300008.-help\u8f93\u51fa\u6b64\u5e2e\u52a9\u6d88\u606f\u5e76\u9000\u51fa
\u3000\u300009.-classpath\u7528\u4e8e\u88c5\u5165\u7c7b\u7684\u8def\u5f84
\u3000\u300010.-bootclasspath\u7528\u4e8e\u88c5\u5165\u5f15\u5bfc\u7c7b\u7684\u8def\u5f84
\u3000\u300011.-d\u8f93\u51fa\u76ee\u5f55
\u3000\u300012.-o\u8f93\u51fa\u6587\u4ef6\uff08\u53ea\u80fd\u4f7f\u7528-d\u6216-o\u4e2d\u7684\u4e00\u4e2a\uff09
\u3000\u300013.-jni\u751f\u6210JNI\u6837\u5f0f\u7684\u5934\u6587\u4ef6\uff08\u9ed8\u8ba4\uff09
\u3000\u300014.-version\u8f93\u51fa\u7248\u672c\u4fe1\u606f
\u3000\u300015.-verbose\u542f\u7528\u8be6\u7ec6\u8f93\u51fa
\u3000\u300016.-force\u59cb\u7ec8\u5199\u5165\u8f93\u51fa\u6587\u4ef6
\u3000\u300017.\u4f7f\u7528\u5168\u9650\u5b9a\u540d\u79f0\u6307\u5b9a\uff08\u4f8b
\u3000\u300018.\u5982\uff0cjava.lang.Object\uff09\u3002
\u3000\u3000$java -version
\u3000\u3000javaversion "1.6.0_29"
\u3000\u3000Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
\u3000\u3000JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
\u3000\u3000$javah
\u3000\u3000\u7528\u6cd5\uff1ajavah[\u9009\u9879]
\u3000\u3000\u5176\u4e2d[\u9009\u9879]\u5305\u62ec\uff1a
\u3000\u3000-help\u8f93\u51fa\u6b64\u5e2e\u52a9\u6d88\u606f\u5e76\u9000\u51fa
\u3000\u3000-classpath\u7528\u4e8e\u88c5\u5165\u7c7b\u7684\u8def\u5f84
\u3000\u3000-bootclasspath\u7528\u4e8e\u88c5\u5165\u5f15\u5bfc\u7c7b\u7684\u8def\u5f84
\u3000\u3000-d\u8f93\u51fa\u76ee\u5f55
\u3000\u3000-o\u8f93\u51fa\u6587\u4ef6\uff08\u53ea\u80fd\u4f7f\u7528-d\u6216-o\u4e2d\u7684\u4e00\u4e2a\uff09
\u3000\u3000-jni\u751f\u6210JNI\u6837\u5f0f\u7684\u5934\u6587\u4ef6\uff08\u9ed8\u8ba4\uff09
\u3000\u3000-version\u8f93\u51fa\u7248\u672c\u4fe1\u606f
\u3000\u3000-verbose\u542f\u7528\u8be6\u7ec6\u8f93\u51fa
\u3000\u3000-force\u59cb\u7ec8\u5199\u5165\u8f93\u51fa\u6587\u4ef6
\u3000\u3000\u4f7f\u7528\u5168\u9650\u5b9a\u540d\u79f0\u6307\u5b9a\uff08\u4f8b
\u3000\u3000\u5982\uff0cjava.lang.Object\uff09\u30022.2.\u5b89\u88c5android\u5e94\u7528\u7a0b\u5e8f\u5f00\u53d1\u73af\u5883
\u3000\u3000ubuntu\u4e0b\u5b89\u88c5android\u5e94\u7528\u7a0b\u5e8f\u5f00\u53d1\u73af\u5883\u4e0ewindows\u7c7b\u4f3c\uff0c\u4f9d\u6b21\u5b89\u88c5\u597d\u4ee5\u4e0b\u8f6f\u4ef6\u5373\u53ef\uff1a
\u3000\u3000\uff081\uff09Eclipse
\u3000\u3000\uff082\uff09ADT
\u3000\u3000\uff083\uff09AndroidSDK
\u3000\u3000\u4e0ewindows\u4e0b\u5b89\u88c5\u552f\u4e00\u4e0d\u540c\u7684\u4e00\u70b9\u662f\uff0c\u4e0b\u8f7d\u8fd9\u4e9b\u8f6f\u4ef6\u7684\u65f6\u5019\u8981\u4e0b\u8f7dLinux\u7248\u672c\u7684\u5b89\u88c5\u5305\u3002
\u3000\u3000\u5b89\u88c5\u597d\u4ee5\u4e0aandroid\u5e94\u7528\u7a0b\u5e8f\u7684\u5f00\u53d1\u73af\u5883\u540e\uff0c\u8fd8\u53ef\u4ee5\u9009\u62e9\u662f\u5426\u9700\u8981\u914d\u7f6eemulator\u548cadb\u5de5\u5177\u7684\u73af\u5883\u53d8\u91cf\uff0c\u4ee5\u65b9\u4fbf\u5728\u8fdb\u884cJNI\u5f00\u53d1\u7684\u65f6\u5019\u4f7f\u7528\u3002\u914d\u7f6e\u6b65\u9aa4\u5982\u4e0b\uff1a
\u3000\u3000\u628aemulator\u6240\u5728\u76ee\u5f55android-sdk-linux/tools\u4ee5\u53caadb\u6240\u5728\u76ee\u5f55android-sdk-linux/platform-tools\u6dfb\u52a0\u5230\u73af\u5883\u53d8\u91cf\u4e2d\uff0candroid-sdk-linux\u6307androidsdk\u5b89\u88c5\u5305android-sdk_rxx-linux\u7684\u89e3\u538b\u76ee\u5f55\u3002
\u3000\u3000[plain] view plaincopyprint?
\u3000\u300001.$sudo vim /etc/profile
\u3000\u300002.exportPATH=~/software/android/android-sdk-linux/tools:$PATH
\u3000\u300003. exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
\u3000\u3000$sudo vim /etc/profile
\u3000\u3000exportPATH=~/software/android/android-sdk-linux/tools:$PATH
\u3000\u3000exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
\u3000\u3000\u7f16\u8f91\u5b8c\u6bd5\u540e\u9000\u51fa\uff0c\u5e76\u91cd\u542f\u751f\u6548\u3002

\u3000\u30002.3.\u5b89\u88c5NDK
\u3000\u3000NDK\u662f\u7531android\u63d0\u4f9b\u7684\u7f16\u8bd1android\u672c\u5730\u4ee3\u7801\u7684\u4e00\u4e2a\u5de5\u5177\u3002
\u3000\u3000\uff081\uff09\u4eceandroidndk\u5b98\u7f51\u4e0b\u8f7dndk\uff0c\u76ee\u524d\u6700\u65b0\u7248\u672c\u4e3aandroid-ndk-r6b-linux-x86.tar.bz2.
\u3000\u3000\uff082\uff09\u89e3\u538bndk\u5230\u5de5\u4f5c\u76ee\u5f55\uff1a
\u3000\u3000[plain] view plaincopyprint?
\u3000\u300001.$tar -xvf android-ndk-r6b-linux-x86.tar.bz2
\u3000\u300002.$sudo mv android-ndk-r6b /usr/local/ndk
\u3000\u3000$tar -xvf android-ndk-r6b-linux-x86.tar.bz2
\u3000\u3000$sudo mv android-ndk-r6b /usr/local/ndk
\u3000\u3000\uff083\uff09\u8bbe\u7f6endk\u73af\u5883\u53d8\u91cf

\u3000\u3000[plain] view plaincopyprint?
\u3000\u300001.$sudo vim /etc/profile
\u3000\u300002.exportPATH=/usr/local/ndk:$PATH
\u3000\u3000$sudo vim /etc/profile
\u3000\u3000exportPATH=/usr/local/ndk:$PATH

\u3000\u3000\u7f16\u8f91\u5b8c\u6bd5\u540e\u4fdd\u5b58\u9000\u51fa\uff0c\u5e76\u91cd\u542f\u751f\u6548

\u3000\u3000\uff084\uff09\u9a8c\u8bc1\u5b89\u88c5

\u3000\u3000[plain] view plaincopyprint?
\u3000\u300001.$ cd/usr/local/ndk/samples/hello-jni/
\u3000\u300002.$ ndk-build
\u3000\u300003.Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
\u3000\u300004.Gdbsetup : libs/armeabi/gdb.setup
\u3000\u300005.Install : libhello-jni.so => libs/armeabi/libhello-jni.so
\u3000\u3000$ cd/usr/local/ndk/samples/hello-jni/
\u3000\u3000$ ndk-build
\u3000\u3000Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
\u3000\u3000Gdbsetup : libs/armeabi/gdb.setup
\u3000\u3000Install : libhello-jni.so => libs/armeabi/libhello-jni.so

\u3000\u30003.JNI\u5b9e\u73b0
\u3000\u3000\u6211\u4eec\u9700\u8981\u5b9a\u4e49\u4e00\u4e2a\u7b26\u5408JNI\u63a5\u53e3\u89c4\u8303\u7684c/c++\u63a5\u53e3\uff0c\u8fd9\u4e2a\u63a5\u53e3\u4e0d\u7528\u592a\u590d\u6742\uff0c\u4f8b\u5982\u8f93\u51fa\u4e00\u4e2a\u5b57\u7b26\u4e32\u3002\u63a5\u4e0b\u6765\uff0c\u5219\u9700\u8981\u628ac/c++\u63a5\u53e3\u7684\u4ee3\u7801\u6587\u4ef6\u7f16\u8bd1\u6210\u5171\u4eab\u5e93\uff08\u52a8\u6001\u5e93\uff09.so\u6587\u4ef6\uff0c\u5e76\u653e\u5230\u6a21\u62df\u5668\u7684\u76f8\u5173\u76ee\u5f55\u4e0b\u3002\u6700\u540e\uff0c\u542f\u52a8Java\u5e94\u7528\u7a0b\u5e8f\uff0c\u5c31\u53ef\u4ee5\u770b\u5230\u6700\u7ec8\u6548\u679c\u4e86\u3002

\u3000\u30003.1.\u7f16\u5199Java\u5e94\u7528\u7a0b\u5e8f\u4ee3\u7801
\u3000\u3000\uff081\uff09\u542f\u52a8Eclipse\uff0c\u65b0\u5efaandroid\u5de5\u7a0b

\u3000\u3000Project\uff1aJNITest

\u3000\u3000Package\uff1aorg.tonny.jni

\u3000\u3000Activity\uff1aJNITest

\u3000\u3000\uff082\uff09\u7f16\u8f91\u8d44\u6e90\u6587\u4ef6

\u3000\u3000\u7f16\u8f91res/values/strings.xml\u6587\u4ef6\u5982\u4e0b\uff1a

\u3000\u3000[html] view plaincopyprint?
\u3000\u300001.
\u3000\u300002.
\u3000\u300003.HelloWorld, JNITestActivity!
\u3000\u300004.JNITest
\u3000\u300005.Show
\u3000\u300006.
\u3000\u3000
\u3000\u3000
\u3000\u3000HelloWorld, JNITestActivity!
\u3000\u3000JNITest
\u3000\u3000Show
\u3000\u3000

\u3000\u3000\u7f16\u8f91res/layout/main.xml\u6587\u4ef6\u5982\u4e0b\uff1a

\u3000\u3000[html] view plaincopyprint?
\u3000\u300001.
\u3000\u300002.<LinearLayoutxmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
\u3000\u300003.android:layout_width="fill_parent"
\u3000\u300004.android:layout_height="fill_parent"
\u3000\u300005.android:orientation="vertical">
\u3000\u300006.<TextView
\u3000\u300007.android:layout_width="fill_parent"
\u3000\u300008.android:layout_height="wrap_content"
\u3000\u300009.android:text="@string/hello"/>
\u3000\u300010.<EditText
\u3000\u300011.android:id="@+id/ed_name"
\u3000\u300012.android:layout_width="match_parent"
\u3000\u300013.android:layout_height="wrap_content"
\u3000\u300014.android:layout_gravity="center_horizontal"
\u3000\u300015.android:layout_marginLeft="5dp"
\u3000\u300016.android:layout_marginRight="5dp"/>
\u3000\u300017.<Button
\u3000\u300018.android:id="@+id/btn_show"
\u3000\u300019.android:layout_width="109dp"
\u3000\u300020.android:layout_height="wrap_content"
\u3000\u300021.android:layout_gravity="center_horizontal"
\u3000\u300022.android:text="@string/btn_show"/>
\u3000\u300023.
\u3000\u3000
\u3000\u3000<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
\u3000\u3000android:layout_width="fill_parent"
\u3000\u3000android:layout_height="fill_parent"
\u3000\u3000android:orientation="vertical">
\u3000\u3000<TextView
\u3000\u3000android:layout_width="fill_parent"
\u3000\u3000android:layout_height="wrap_content"
\u3000\u3000android:text="@string/hello"/>
\u3000\u3000<EditText
\u3000\u3000android:id="@+id/ed_name"
\u3000\u3000android:layout_width="match_parent"
\u3000\u3000android:layout_height="wrap_content"
\u3000\u3000android:layout_gravity="center_horizontal"
\u3000\u3000android:layout_marginLeft="5dp"
\u3000\u3000android:layout_marginRight="5dp"/>
\u3000\u3000<Button
\u3000\u3000android:id="@+id/btn_show"
\u3000\u3000android:layout_width="109dp"
\u3000\u3000android:layout_height="wrap_content"
\u3000\u3000android:layout_gravity="center_horizontal"
\u3000\u3000android:text="@string/btn_show"/>
\u3000\u3000

\u3000\u3000\u6211\u4eec\u5728\u4e3b\u754c\u9762\u4e0a\u6dfb\u52a0\u4e86\u4e00\u4e2aEditText\u63a7\u4ef6\u548c\u4e00\u4e2aButton\u63a7\u4ef6\u3002

\u3000\u3000\uff083\uff09\u7f16\u8f91JNITest.java\u6587\u4ef6

\u3000\u3000[java] view plaincopyprint?
\u3000\u300001.packageorg.tonny.jni;
\u3000\u300002.
\u3000\u300003.importandroid.app.Activity;
\u3000\u300004.importandroid.os.Bundle;
\u3000\u300005.importandroid.view.View;
\u3000\u300006.importandroid.widget.EditText;
\u3000\u300007.importandroid.widget.Button;
\u3000\u300008.
\u3000\u300009.
\u3000\u300010.publicclassJNITestextendsActivity {
\u3000\u300011.static{
\u3000\u300012.System.loadLibrary("JNITest");
\u3000\u300013.}
\u3000\u300014.privatenativeString GetReply();
\u3000\u300015.privateEditTextedtName;
\u3000\u300016.privateButtonbtnShow;
\u3000\u300017.Stringreply;
\u3000\u300018./**Called when the activity is first created. */
\u3000\u300019.@Override
\u3000\u300020.publicvoidonCreate(Bundle savedInstanceState) {
\u3000\u300021.super.onCreate(savedInstanceState);
\u3000\u300022.setContentView(R.layout.main);
\u3000\u300023.reply= GetReply();
\u3000\u300024.edtName= (EditText)this.findViewById(R.id.ed_name);
\u3000\u300025.btnShow= (Button)this.findViewById(R.id.btn_show);
\u3000\u300026.btnShow.setOnClickListener(newButton.OnClickListener() {
\u3000\u300027.publicvoidonClick(View arg0) {
\u3000\u300028.edtName.setText(reply);
\u3000\u300029.}
\u3000\u300030.});
\u3000\u300031.}
\u3000\u300032.}
\u3000\u3000packageorg.tonny.jni;

\u3000\u3000importandroid.app.Activity;
\u3000\u3000importandroid.os.Bundle;
\u3000\u3000importandroid.view.View;
\u3000\u3000importandroid.widget.EditText;
\u3000\u3000importandroid.widget.Button;

\u3000\u3000publicclassJNITestextendsActivity {
\u3000\u3000static{
\u3000\u3000System.loadLibrary("JNITest");
\u3000\u3000}
\u3000\u3000privatenativeString GetReply();
\u3000\u3000privateEditTextedtName;
\u3000\u3000privateButtonbtnShow;
\u3000\u3000Stringreply;
\u3000\u3000/**Called when the activity is first created. */
\u3000\u3000@Override
\u3000\u3000publicvoidonCreate(Bundle savedInstanceState) {
\u3000\u3000super.onCreate(savedInstanceState);
\u3000\u3000setContentView(R.layout.main);
\u3000\u3000reply= GetReply();
\u3000\u3000edtName= (EditText)this.findViewById(R.id.ed_name);
\u3000\u3000btnShow= (Button)this.findViewById(R.id.btn_show);
\u3000\u3000btnShow.setOnClickListener(newButton.OnClickListener() {
\u3000\u3000publicvoidonClick(View arg0) {
\u3000\u3000edtName.setText(reply);
\u3000\u3000}
\u3000\u3000});
\u3000\u3000}
\u3000\u3000}

\u3000\u3000\u6211\u4eec\u770b\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff1a

\u3000\u3000[java] view plaincopyprint?
\u3000\u300001.static{
\u3000\u300002.System.loadLibrary("JNITest");
\u3000\u300003.}
\u3000\u3000static{
\u3000\u3000System.loadLibrary("JNITest");
\u3000\u3000}

\u3000\u3000static\u8868\u793a\u5728\u7cfb\u7edf\u7b2c\u4e00\u6b21\u52a0\u8f7d\u7c7b\u7684\u65f6\u5019\uff0c\u5148\u6267\u884c\u8fd9\u4e00\u6bb5\u4ee3\u7801\uff0c\u5728\u8fd9\u91cc\u8868\u793a\u52a0\u8f7d\u52a8\u6001\u5e93libJNITest.so\u6587\u4ef6\u3002

\u3000\u3000\u518d\u770b\u8fd9\u4e00\u6bb5\uff1a

\u3000\u3000[java] view plaincopyprint?
\u3000\u300001.privatenativeString GetReply();
\u3000\u3000privatenativeString GetReply();
\u3000\u3000native\u8868\u793a\u8fd9\u4e2a\u65b9\u6cd5\u7531\u672c\u5730\u4ee3\u7801\u5b9a\u4e49\uff0c\u9700\u8981\u901a\u8fc7jni\u63a5\u53e3\u8c03\u7528\u672c\u5730c/c++\u4ee3\u7801\u3002

\u3000\u3000[java] view plaincopyprint?
\u3000\u300001.publicvoidonClick(View arg0) {
\u3000\u300002.edtName.setText(reply);
\u3000\u300003.}
\u3000\u3000publicvoidonClick(View arg0) {
\u3000\u3000edtName.setText(reply);
\u3000\u3000}

\u3000\u3000\u8fd9\u6bb5\u4ee3\u7801\u8868\u793a\u70b9\u51fb\u6309\u94ae\u540e\uff0c\u628anative\u65b9\u6cd5\u7684\u8fd4\u56de\u7684\u5b57\u7b26\u4e32\u663e\u793a\u5230EditText\u63a7\u4ef6\u3002

\u3000\u3000\uff084\uff09\u7f16\u8bd1\u5de5\u7a0b\uff0c\u751f\u6210.class\u6587\u4ef6\u3002

\u7b2c\u4e00\u6b65\uff1a

\u3000\u3000\u4f7f\u7528Java\u7f16\u5199HelloWorld \u7684Android\u5e94\u7528\u7a0b\u5e8f\uff1a

\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000package com.lucyfyr;
\u3000\u3000import android.app.Activity;
\u3000\u3000import android.os.Bundle;
\u3000\u3000import android.util.Log;

\u3000\u3000public class HelloWorld extends Activity {
\u3000\u3000/** Called when the activity is first created. */
\u3000\u3000@Override
\u3000\u3000public void onCreate(Bundle savedInstanceState) {
\u3000\u3000super.onCreate(savedInstanceState);
\u3000\u3000setContentView(R.layout.main);
\u3000\u3000Log.v("dufresne", printJNI("I am HelloWorld Activity"));
\u3000\u3000}
\u3000\u3000static
\u3000\u3000{
\u3000\u3000//\u52a0\u8f7d\u5e93\u6587\u4ef6
\u3000\u3000System.loadLibrary("HelloWorldJni");
\u3000\u3000}
\u3000\u3000//\u58f0\u660e\u539f\u751f\u51fd\u6570 \u53c2\u6570\u4e3aString\u7c7b\u578b \u8fd4\u56de\u7c7b\u578b\u4e3aString
\u3000\u3000private native String printJNI(String inputStr);
\u3000\u3000}
\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000

\u3000\u3000\u8fd9\u4e00\u6b65\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528eclipse\u6765\u751f\u6210\u4e00\u4e2aApp\uff1b

\u3000\u3000\u56e0\u4e3aeclipse\u4f1a\u81ea\u52a8\u4e3a\u6211\u4eec\u7f16\u8bd1\u6b64Java\u6587\u4ef6\uff0c\u540e\u9762\u8981\u662f\u7528\u5230\u3002

\u3000\u3000\u7b2c\u4e8c\u6b65\uff1a

\u3000\u3000\u751f\u6210\u5171\u4eab\u5e93\u7684\u5934\u6587\u4ef6\uff1a

\u3000\u3000\u8fdb\u5165\u5230eclipse\u751f\u6210\u7684Android Project\u4e2d \uff1a/HelloWorld/bin/classes/com/lucyfyr/ \u4e0b\uff1a

\u3000\u3000\u53ef\u4ee5\u770b\u5230\u91cc\u9762\u540e\u5f88\u591a\u540e\u7f00\u4e3a.class\u7684\u6587\u4ef6\uff0c\u5c31\u662feclipse\u4e3a\u6211\u4eec\u81ea\u52a8\u7f16\u8bd1\u597d\u4e86\u7684java\u6587\u4ef6\uff0c\u5176\u4e2d\u5c31\u6709\uff1a

\u3000\u3000HelloWorld.class\u6587\u4ef6\u3002

\u3000\u3000\u9000\u56de\u5230classes\u4e00\u7ea7\u76ee\u5f55\uff1a/HelloWorld/bin/classes/

\u3000\u3000\u6267\u884c\u5982\u4e0b\u547d\u4ee4\uff1a

\u3000\u3000javah com.lucyfyr.HelloWorld

\u3000\u3000\u751f\u6210\u6587\u4ef6:com_lucyfyr_HelloWorld.h

\u3000\u3000

\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000/* DO NOT EDIT THIS FILE - it is machine generated */
\u3000\u3000#include
\u3000\u3000/* Header for class com_lucyfyr_HelloWorld */
\u3000\u3000#ifndef _Included_com_lucyfyr_HelloWorld
\u3000\u3000#define _Included_com_lucyfyr_HelloWorld
\u3000\u3000#ifdef __cplusplus
\u3000\u3000extern "C" {
\u3000\u3000#endif
\u3000\u3000/*
\u3000\u3000* Class: com_lucyfyr_HelloWorld
\u3000\u3000* Method: printJNI
\u3000\u3000* Signature: (Ljava/lang/String;)Ljava/lang/String;
\u3000\u3000*/
\u3000\u3000JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI
\u3000\u3000(JNIEnv *, jobject, jstring);
\u3000\u3000#ifdef __cplusplus
\u3000\u3000}
\u3000\u3000#endif
\u3000\u3000#endif
\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000

\u3000\u3000\u53ef\u4ee5\u770b\u5230\u81ea\u52a8\u751f\u6210\u5bf9\u5e94\u7684\u51fd\u6570\uff1aJava_com_lucyfyr_HelloWorld_printJNI

\u3000\u3000Java_ + \u5305\u540d\uff08com.lucyfyr\uff09 + \u7c7b\u540d(HelloWorld) + \u63a5\u53e3\u540d(printJNI)\uff1a\u5fc5\u987b\u8981\u6309\u6b64JNI\u89c4\u8303\u6765\u64cd\u4f5c\uff1b

\u3000\u3000java\u865a\u62df\u673a\u5c31\u53ef\u4ee5\u5728com.simon.HelloWorld\u7c7b\u8c03\u7528printJNI\u63a5\u53e3\u7684\u65f6\u5019\u81ea\u52a8\u627e\u5230\u8fd9\u4e2aC\u5b9e\u73b0\u7684Native\u51fd\u6570\u8c03\u7528\u3002

\u3000\u3000\u5f53\u7136\u51fd\u6570\u540d\u592a\u957f\uff0c\u53ef\u4ee5\u5728.c\u6587\u4ef6\u4e2d\u901a\u8fc7\u51fd\u6570\u540d\u6620\u5c04\u8868\u6765\u5b9e\u73b0\u7b80\u5316\u3002

\u3000\u3000\u7b2c\u4e09\u6b65\uff1a

\u3000\u3000\u5b9e\u73b0JNI\u539f\u751f\u51fd\u6570\u6e90\u6587\u4ef6\uff1a

\u3000\u3000\u65b0\u5efacom_lucyfyr_HelloWorld.c\u6587\u4ef6\uff1a

\u3000\u3000

\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000#include
\u3000\u3000#define LOG_TAG "HelloWorld"
\u3000\u3000#include
\u3000\u3000/* Native interface, it will be call in java code */
\u3000\u3000JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr)
\u3000\u3000{
\u3000\u3000LOGI("dufresne Hello World From libhelloworld.so!");
\u3000\u3000// \u4ece instring \u5b57\u7b26\u4e32\u53d6\u5f97\u6307\u5411\u5b57\u7b26\u4e32 UTF \u7f16\u7801\u7684\u6307\u9488
\u3000\u3000const char *str =
\u3000\u3000(const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE );
\u3000\u3000LOGI("dufresne--->%s",(const char *)str);
\u3000\u3000// \u901a\u77e5\u865a\u62df\u673a\u672c\u5730\u4ee3\u7801\u4e0d\u518d\u9700\u8981\u901a\u8fc7 str \u8bbf\u95ee Java \u5b57\u7b26\u4e32\u3002
\u3000\u3000(*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str );
\u3000\u3000return (*env)->NewStringUTF(env, "Hello World! I am Native interface");
\u3000\u3000}

\u3000\u3000/* This function will be call when the library first be load.
\u3000\u3000* You can do some init in the libray. return which version jni it support.
\u3000\u3000*/
\u3000\u3000jint JNI_OnLoad(JavaVM* vm, void* reserved)
\u3000\u3000{
\u3000\u3000void *venv;
\u3000\u3000LOGI("dufresne----->JNI_OnLoad!");
\u3000\u3000if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {
\u3000\u3000LOGE("dufresne--->ERROR: GetEnv failed");
\u3000\u3000return -1;
\u3000\u3000}
\u3000\u3000return JNI_VERSION_1_4;
\u3000\u3000}
\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000

\u3000\u3000OnLoadJava_com_lucyfyr_HelloWorld_printJNI

\u3000\u3000\u51fd\u6570\u91cc\u9762\u505a\u4e00\u4e9blog\u8f93\u51fa \u6ce8\u610fJNI\u4e2d\u7684log\u8f93\u51fa\u7684\u4e0d\u540c\u3002

\u3000\u3000JNI_OnLoad\u51fd\u6570JNI\u89c4\u8303\u5b9a\u4e49\u7684\uff0c\u5f53\u5171\u4eab\u5e93\u7b2c\u4e00\u6b21\u88ab\u52a0\u8f7d\u7684\u65f6\u5019\u4f1a\u88ab\u56de\u8c03\uff0c

\u3000\u3000\u8fd9\u4e2a\u51fd\u6570\u91cc\u9762\u53ef\u4ee5\u8fdb\u884c\u4e00\u4e9b\u521d\u59cb\u5316\u5de5\u4f5c\uff0c\u6bd4\u5982\u6ce8\u518c\u51fd\u6570\u6620\u5c04\u8868\uff0c\u7f13\u5b58\u4e00\u4e9b\u53d8\u91cf\u7b49\uff0c

\u3000\u3000\u6700\u540e\u8fd4\u56de\u5f53\u524d\u73af\u5883\u6240\u652f\u6301\u7684JNI\u73af\u5883\u3002\u672c\u4f8b\u53ea\u662f\u7b80\u5355\u7684\u8fd4\u56de\u5f53\u524dJNI\u73af\u5883\u3002

\u3000\u3000

\u3000\u3000\u7b2c\u56db\u6b65\uff1a

\u3000\u3000\u7f16\u8bd1\u751f\u6210so\u5e93

\u3000\u3000\u7f16\u8bd1com_lucyfyr_HelloWorld.c\u6210so\u5e93\u53ef\u4ee5\u548capp\u4e00\u8d77\u7f16\u8bd1\uff0c\u4e5f\u53ef\u4ee5\u90fd\u5355\u72ec\u7f16\u8bd1\u3002

\u3000\u3000\u5728\u5f53\u524d\u76ee\u5f55\u4e0b\u5efa\u7acbjni\u6587\u4ef6\u5939\uff1aHelloWorld/jni/

\u3000\u3000\u4e0b\u5efa\u7acbAndroid.mk \uff0c\u5e76\u5c06com_lucyfyr_HelloWorld.c\u548c com_lucyfyr_HelloWorld.h \u62f7\u8d1d\u5230\u8fdb\u53bb

\u3000\u3000\u7f16\u5199\u7f16\u8bd1\u751f\u6210so\u5e93\u7684Android.mk\u6587\u4ef6\uff1a

\u3000\u3000

\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000LOCAL_PATH:= $(call my-dir)
\u3000\u3000# \u4e00\u4e2a\u5b8c\u6574\u6a21\u5757\u7f16\u8bd1
\u3000\u3000include $(CLEAR_VARS)
\u3000\u3000LOCAL_SRC_FILES:=com_lucyfyr_HelloWorld.c
\u3000\u3000LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
\u3000\u3000LOCAL_MODULE := libHelloWorldJni
\u3000\u3000LOCAL_SHARED_LIBRARIES := libutils
\u3000\u3000LOCAL_PRELINK_MODULE := false
\u3000\u3000LOCAL_MODULE_TAGS :=optional
\u3000\u3000include $(BUILD_SHARED_LIBRARY)
\u3000\u3000\u590d\u5236\u4ee3\u7801
\u3000\u3000

\u3000\u3000\u7cfb\u7edf\u53d8\u91cf\u89e3\u6790\uff1a

\u3000\u3000LOCAL_PATH - \u7f16\u8bd1\u65f6\u7684\u76ee\u5f55
\u3000\u3000$(call \u76ee\u5f55\uff0c\u76ee\u5f55\u2026.) \u76ee\u5f55\u5f15\u5165\u64cd\u4f5c\u7b26
\u3000\u3000\u5982\u8be5\u76ee\u5f55\u4e0b\u6709\u4e2a\u6587\u4ef6\u5939\u540d\u79f0 src\uff0c\u5219\u53ef\u4ee5\u8fd9\u6837\u5199 $(call src)\uff0c\u90a3\u4e48\u5c31\u4f1a\u5f97\u5230 src \u76ee\u5f55\u7684\u5b8c\u6574\u8def\u5f84

\u3000\u3000include $(CLEAR_VARS) -\u6e05\u9664\u4e4b\u524d\u7684\u4e00\u4e9b\u7cfb\u7edf\u53d8\u91cf
\u3000\u3000LOCAL_MODULE \uff0d \u7f16\u8bd1\u751f\u6210\u7684\u76ee\u6807\u5bf9\u8c61
\u3000\u3000LOCAL_SRC_FILES \uff0d \u7f16\u8bd1\u7684\u6e90\u6587\u4ef6
\u3000\u3000LOCAL_C_INCLUDES \uff0d \u9700\u8981\u5305\u542b\u7684\u5934\u6587\u4ef6\u76ee\u5f55
\u3000\u3000LOCAL_SHARED_LIBRARIES \uff0d \u94fe\u63a5\u65f6\u9700\u8981\u7684\u5916\u90e8\u5e93
\u3000\u3000LOCAL_PRELINK_MODULE \uff0d \u662f\u5426\u9700\u8981prelink\u5904\u7406
\u3000\u3000include$\uff08BUILD_SHARED_LIBRARY\uff09 \uff0d \u6307\u660e\u8981\u7f16\u8bd1\u6210\u52a8\u6001\u5e93

  1.引言
  我们知道,Android系统的底层库由c/c++编写,上层Android应用程序通过Java虚拟机调用底层接口,衔接底层c/c++库与Java应用程序间的接口正是JNI(JavaNative Interface)。本文描述了如何在ubuntu下配置AndroidJNI的开发环境,以及如何编写一个简单的c函数库和JNI接口,并通过编写Java程序调用这些接口,最终运行在模拟器上的过程。

  2.环境配置

  2.1.安装jdk1.6
  (1)从jdk官方网站下载jdk-6u29-linux-i586.bin文件。
  (2)执行jdk安装文件
  [html] view plaincopyprint?
  01.$chmod a+x jdk-6u29-linux-i586.bin
  02.$jdk-6u29-linux-i586.bin
  $chmod a+x jdk-6u29-linux-i586.bin
  $jdk-6u29-linux-i586.bin
  (3)配置jdk环境变量

  [html] view plaincopyprint?
  01.$sudo vim /etc/profile
  02.#JAVAEVIRENMENT
  03.exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
  04.exportJRE_HOME=$JAVA_HOME/jre
  05.exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
  06.exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
  $sudo vim /etc/profile
  #JAVAEVIRENMENT
  exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
  exportJRE_HOME=$JAVA_HOME/jre
  exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
  exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
  保存后退出编辑,并重启系统。

  (4)验证安装

  [html] view plaincopyprint?
  01.$java -version
  02.javaversion "1.6.0_29"
  03.Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
  04.JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
  05.$javah
  06.用法:javah[选项]<类>
  07.其中[选项]包括:
  08.-help输出此帮助消息并退出
  09.-classpath<路径>用于装入类的路径
  10.-bootclasspath<路径>用于装入引导类的路径
  11.-d<目录>输出目录
  12.-o<文件>输出文件(只能使用-d或-o中的一个)
  13.-jni生成JNI样式的头文件(默认)
  14.-version输出版本信息
  15.-verbose启用详细输出
  16.-force始终写入输出文件
  17.使用全限定名称指定<类>(例
  18.如,java.lang.Object)。
  $java -version
  javaversion "1.6.0_29"
  Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
  JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
  $javah
  用法:javah[选项]<类>
  其中[选项]包括:
  -help输出此帮助消息并退出
  -classpath<路径>用于装入类的路径
  -bootclasspath<路径>用于装入引导类的路径
  -d<目录>输出目录
  -o<文件>输出文件(只能使用-d或-o中的一个)
  -jni生成JNI样式的头文件(默认)
  -version输出版本信息
  -verbose启用详细输出
  -force始终写入输出文件
  使用全限定名称指定<类>(例
  如,java.lang.Object)。2.2.安装android应用程序开发环境
  ubuntu下安装android应用程序开发环境与windows类似,依次安装好以下软件即可:
  (1)Eclipse
  (2)ADT
  (3)AndroidSDK
  与windows下安装唯一不同的一点是,下载这些软件的时候要下载Linux版本的安装包。
  安装好以上android应用程序的开发环境后,还可以选择是否需要配置emulator和adb工具的环境变量,以方便在进行JNI开发的时候使用。配置步骤如下:
  把emulator所在目录android-sdk-linux/tools以及adb所在目录android-sdk-linux/platform-tools添加到环境变量中,android-sdk-linux指androidsdk安装包android-sdk_rxx-linux的解压目录。
  [plain] view plaincopyprint?
  01.$sudo vim /etc/profile
  02.exportPATH=~/software/android/android-sdk-linux/tools:$PATH
  03. exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
  $sudo vim /etc/profile
  exportPATH=~/software/android/android-sdk-linux/tools:$PATH
  exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
  编辑完毕后退出,并重启生效。

  2.3.安装NDK
  NDK是由android提供的编译android本地代码的一个工具。
  (1)从androidndk官网http://developer.android.com/sdk/ndk/index.html下载ndk,目前最新版本为android-ndk-r6b-linux-x86.tar.bz2.
  (2)解压ndk到工作目录:
  [plain] view plaincopyprint?
  01.$tar -xvf android-ndk-r6b-linux-x86.tar.bz2
  02.$sudo mv android-ndk-r6b /usr/local/ndk
  $tar -xvf android-ndk-r6b-linux-x86.tar.bz2
  $sudo mv android-ndk-r6b /usr/local/ndk
  (3)设置ndk环境变量

  [plain] view plaincopyprint?
  01.$sudo vim /etc/profile
  02.exportPATH=/usr/local/ndk:$PATH
  $sudo vim /etc/profile
  exportPATH=/usr/local/ndk:$PATH

  编辑完毕后保存退出,并重启生效

  (4)验证安装

  [plain] view plaincopyprint?
  01.$ cd/usr/local/ndk/samples/hello-jni/
  02.$ ndk-build
  03.Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
  04.Gdbsetup : libs/armeabi/gdb.setup
  05.Install : libhello-jni.so => libs/armeabi/libhello-jni.so
  $ cd/usr/local/ndk/samples/hello-jni/
  $ ndk-build
  Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
  Gdbsetup : libs/armeabi/gdb.setup
  Install : libhello-jni.so => libs/armeabi/libhello-jni.so

  3.JNI实现
  我们需要定义一个符合JNI接口规范的c/c++接口,这个接口不用太复杂,例如输出一个字符串。接下来,则需要把c/c++接口的代码文件编译成共享库(动态库).so文件,并放到模拟器的相关目录下。最后,启动Java应用程序,就可以看到最终效果了。

  3.1.编写Java应用程序代码
  (1)启动Eclipse,新建android工程

  Project:JNITest

  Package:org.tonny.jni

  Activity:JNITest

  (2)编辑资源文件

  编辑res/values/strings.xml文件如下:

  

  编辑res/layout/main.xml文件
  我们在主界面上添加了一个EditText控件和一个Button控件。

  (3)编辑JNITest.java文件

 
  static表示在系统第一次加载类的时候,先执行这一段代码,在这里表示加载动态库libJNITest.so文件。

  再看这一段:

  [java] view plaincopyprint?
  01.privatenativeString GetReply();
  privatenativeString GetReply();
  native表示这个方法由本地代码定义,需要通过jni接口调用本地c/c++代码。

  [java] view plaincopyprint?
  01.publicvoidonClick(View arg0) {
  02.edtName.setText(reply);
  03.}
  publicvoidonClick(View arg0) {
  edtName.setText(reply);
  }

  这段代码表示点击按钮后,把native方法的返回的字符串显示到EditText控件。

  (4)编译工程,生成.class文件。

  3.2.用javah工具生成符合JNI规范的c语言头文件

  在终端中,进入android工程所在的bin目录

  [plain] view plaincopyprint?
  01.$cd ~/project/Android/JNITest/bin
  $cd ~/project/Android/JNITest/bin
  我们用ls命令查看,可以看到bin目录下有个classes目录,其目录结构为classes/org/tonny/jni,即classes的子目录结构是android工程的包名org.tonny.jni。请注意,下面我们准备执行javah命令的时候,必须进入到org/tonny/jni的上级目录,即classes目录,否则javah会提示找不到相关的java类。

  下面继续:

  [plain] view plaincopyprint?
  01.$cd classes
  02.$javah org.tonny.jni.JNITest
  03.$ls
  04.org org_tonny_jni_JNITest.h
  $cd classes
  $javah org.tonny.jni.JNITest
  $ls
  org org_tonny_jni_JNITest.h

  执行javahorg.tonny.jni.JNITest命令,在classes目录下会生成org_tonny_jni_JNITest.h头文件。如果不进入到classes目录下的话,也可以这样:

  [plain] view plaincopyprint?
  01.$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest
  $javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest
  -classpath 参数表示装载类的目录。

  3.3.编写c/c++代码
  生成org_tonny_jni_JNITest.h头文件后,我们就可以编写相应的函数代码了。下面在android工程目录下新建jni目录,即~/project/Android/JNITest/jni,把org_tonny_jni_JNITest.h头文件拷贝到jni目录下,并在jni目录下新建org_tonny_jni_JNITest.c文件,编辑代码如下:

  [cpp] view plaincopyprint?
  01.#include<jni.h>
  02.#include<string.h>
  03.#include"org_tonny_jni_JNITest.h"
  04.
  05.
  06.JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply
  07.(JNIEnv *env, jobject obj){
  08.return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");
  09.}
  #include<jni.h>
  #include<string.h>
  #include"org_tonny_jni_JNITest.h"

  JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply
  (JNIEnv *env, jobject obj){
  return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");
  }

  我们可以看到,该函数的实现相当简单,返回一个字符串为:"Hello,JNITest"

  3.4.编写Android.mk文件
  在~/project/Android/JNITest/jni目录下新建Android.mk文件,android可以根据这个文件的编译参数编译模块。编辑Android.mk文件如下:

  [plain] view plaincopyprint?
  01.LOCAL_PATH:= $(call my-dir)
  02.include$(CLEAR_VARS)
  03.LOCAL_MODULE := libJNITest
  04.LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c
  05.include$(BUILD_SHARED_LIBRARY)
  LOCAL_PATH:= $(call my-dir)
  include$(CLEAR_VARS)
  LOCAL_MODULE := libJNITest
  LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c
  include$(BUILD_SHARED_LIBRARY)

  LOCAL_MODULE表示编译的动态库名称

  LOCAL_SRC_FILES 表示源代码文件

  3.5.用ndk工具编译并生成.so文件
  进入到JNITest的工程目录,执行ndk-build命令即可生成libJNITest.so文件。

  [plain] view plaincopyprint?
  01.$cd ~/project/Android/JNITest/
  02.$ndk-build
  03.Invalidattribute name:
  04.package
  05.Install : libJNITest.so => libs/armeabi/libJNITest.so
  $cd ~/project/Android/JNITest/
  $ndk-build
  Invalidattribute name:
  package
  Install : libJNITest.so => libs/armeabi/libJNITest.so
  可以看到,在工程目录的libs/armeabi目录下生成了libJNITest.so文件。

  3.6.在模拟器上运行
  (1)首先,我们把android模拟器启动起来。进入到emulator所在目录,执行emulator命令:

  [plain] view plaincopyprint?
  01.$cd ~/software/android/android-sdk-linux/tools
  02.$./emulator @AVD-2.3.3-V10 -partition-size 512
  $cd ~/software/android/android-sdk-linux/tools
  $./emulator @AVD-2.3.3-V10 -partition-size 512
  AVD-2.3.3-V10表示你的模拟器名称,与在Eclipse->AVDManager下的AVDName对应,-partition-size表示模拟器的存储设备容量。

  (2)接下来,我们需要把libJNITest.so文件拷贝到模拟器的/system/lib目录下,执行以下命令:

  [plain] view plaincopyprint?
  01.$cd ~/project/Android/JNITest/libs/armeabi/
  02.$adb remount
  03.$adb push libJNITest.so /system/lib
  04.80 KB/s (10084 bytes in 0.121s)
  $cd ~/project/Android/JNITest/libs/armeabi/
  $adb remount
  $adb push libJNITest.so /system/lib
  80 KB/s (10084 bytes in 0.121s)

  当在终端上看到有80 KB/s (10084 bytes in 0.121s)传输速度等信息的时候,说明拷贝成功。

  (3)在终端上执行JNITest程序,这个我们可以在Eclipse下,右键点击JNITest工程,RunAs->Android Application,即可在模拟器上启动程序

  • 鍍忕礌濂界殑鎵嬫満鎺ㄨ崘?
    绛旓細瀹夊厰鍏旇窇鍒嗘柟闈,澶╃帒1200鑳借窇鍒72涓,鑰屽ぉ鐜1100澶х害鍦67涓,鏃ュ父浣跨敤涔熸槸澶熺殑銆 鎷嶇収鏂归潰: S12Pro鍜孲12鐨勫悗缃暅澶存ā缁勪竴妯′竴鏍,閮芥槸涓浜垮儚绱+800涓囧箍瑙+200涓囧井璺,瀹為檯鐨勬媿鐓ц〃鐜颁笉閿欍傚墠缃柟闈,S12Pro鏈変竴瀹氫紭鍔,涓绘憚鏄5000涓囧儚绱犵殑涓夋槦JNV,寮轰簬S12 4400涓囧儚绱犵殑涓夋槦GH1,涓昏寮哄湪ISOCELL 3.0鐨勬劅鍏夊崌绾с備袱鑰呴兘...
  • 鍓槧鎬庝箞鍓緫
    绛旓細銆婂壀鏄 v2.1.0瑙嗛鍓緫杞欢銆嬬櫨搴︾綉鐩樿祫婧愬厤璐逛笅杞:閾炬帴: https://pan.baidu.com/s/1AMehG-1JNqDTs_5Amro6PQ ?pwd=m44a 鎻愬彇鐮: m44a 鍓槧v2.1.0鏈鏂扮増鏄竴娆鹃潪甯稿疄鐢ㄧ殑瑙嗛鍒朵綔杞欢锛屾彁渚涗簡鍒囧壊銆佸彉閫熴佸掓斁銆佺敾甯冦佽浆鍦虹瓑瑙嗛澶勭悊鍔熻兘锛屽彲浠ュ揩閫熻嚜鐢卞垎鍓茶棰戯紝涓閿壀鍒囪棰戯紱鐝嶈棌澶ч噺瀹炵敤鐨...
  • 鍍忕礌濂芥т环姣旈珮鐨勬墜鏈
    绛旓細S12Pro鍜孲12鐨勫悗缃暅澶存ā缁勫畬鍏ㄤ竴鏍凤紝1浜垮儚绱+800涓囧箍瑙+200涓囧井璺濄傚疄闄呯浉鏈鸿〃鐜颁笉閿欍傛闈㈡潵鐪嬶紝S12Pro鏈変竴瀹氫紭鍔裤備富鎽勫儚澶存槸5000涓囧儚绱犵殑涓夋槦JNV锛屽己浜嶴12鐨4400涓囧儚绱犵殑涓夋槦GH1锛屼富瑕佸己浜嶪SOCELL 3.0鐨勬劅鍏夊崌绾т袱鑰呴兘鏈夊弻鑹叉俯鍜屽洓涓煍鍏夌伅锛屽湪鏆楀厜鎴栭粦鏆楃幆澧冧笅閮芥湁涓嶉敊鐨勮〃鐜般備粠缁煎悎鏁版嵁鏉ョ湅锛...
  • vivox90鍜宱ppofindx6鍝釜濂界敤?
    绛旓細vivox90鍜宱ppofindx6浠庢ц兘閰嶇疆銆佸睆骞曘佹憚褰便佺画鑸佸叾浠栧姛鑳界瓑鏂归潰姣旇緝鏉ョ湅浜掓湁浼樺娍锛岄兘鏄尯濂界殑鏈哄瀷銆1銆佹ц兘閰嶇疆 浠栦滑閮浣跨敤浜嗗ぉ鐜9200澶勭悊鍣ㄥ拰LPDDR5+ufs4.0鐨勭粍鍚堛2銆佸睆骞 vivox90鐨6.78鑻卞灞忓箷鏇村ぇ锛屾嫢鏈夋洿楂樼殑1300nit宄板间寒搴︼紝灞忓箷绱犺川鏇磋儨涓绛广3銆佹憚褰 oppofindx6鐨勭储灏糏MX989浼犳劅鍣ㄨ姣...
  • 棰勭畻2000宸﹀彸,鏄拱vivoT1杩樻槸灏忕背Civi姣旇緝濂?
    绛旓細鎷嶇収杩欐柟闈㈠氨瑙佷粊瑙佹櫤浜嗐備笉杩嘥1涔熸湁6400涓囧儚绱犱笁鎽勯厤缃紝鏃ュ父浣跨敤涔熺畻鍙互鐨勩傝嚜鎷嶆柟闈㈡槸鍗曟憚鐨1600涓囧儚绱狅紝鍜屽皬绫矯ivi閰嶇疆鏄樊涓嶅鐨勩傛兂瑕佽嚜鎷嶆洿濂界殑鎴戝缓璁彲浠ョ湅涓涓媣ivoS12锛屾垨鑰呯幇鍦ㄤ环鏍煎弸濂界殑vivoS12Pro銆傚墠缃槸鍙屾憚閰嶇疆锛孲12Pro鏇存槸閲囩敤5000涓囧儚绱JN1涓绘憚锛岄厤800涓囧儚绱犺秴骞胯闀滃ご銆傚苟涓旇繕鏈夊弻...
  • 浜笢鐨勫皬绫宠嚜钀ュ簵鎬庝箞涓嶅崠榛戦波娓告垙鎵嬫満鍛
    绛旓細榛戦波鎵嬫満鍙槸鎺ュ彈浜嗗皬绫崇殑璧勯噾鎶曡祫鑰屽凡锛屼絾鏄粬鐨勯攢鍞笭閬擄紝鍝佺墝杩愯惀锛岀敓浜х鐞嗭紝閲囪喘绠$悊绛夌瓑閮借繕鏄敱鑷鍐冲畾銆傝鐨勭畝鍗曠偣锛屽氨鏄皬绫冲彧鏄潗绛夊勾搴曢粦椴ㄦ墜鏈哄垎绾㈣屽凡锛屼絾鏄棤娉曞榛戦波鎵嬫満杩涜鍐崇瓥銆傛墍浠ヤ笉璁烘槸鍦ㄤ含涓滐紝澶╃尗杩樻槸鑻忓畞鏄撹喘绛夌瓑鍚勭鐢靛晢鐨勫皬绫宠嚜钀ュ簵鍐呴兘鏄拱涓嶅埌榛戦波鎵嬫満鐨勶紝鐢氳嚦鍦ㄥ皬绫崇嚎涓嬭嚜钀ョ殑灏忕背...
  • 扩展阅读:android系统下载安装 ... 平板android系统下载 ... 苹果android怎么设置 ... 直接下载app安装 ... android安卓版下载 ... android下载安装app1.37 ... android苹果下载安装 ... android在哪里打开 ... 苹果android在哪里找 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网