Android_10_Java调用C代码(纯手工制作)

来源:互联网 发布:select ajax json 联动 编辑:程序博客网 时间:2024/04/20 10:49

第一步:

在工程目录下创建一个文件夹,名为 jni ,然后在jni目录下创建一个c文件,例如我的c文件名为:Hello.c


第二步:

在Java程序中定义一个本地方法,这个方法是要我们用c来实现的,如:

package com.itheima.helloworld1;import android.os.Bundle;import android.app.Activity;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);            }    public void click(View v){    Toast.makeText(this, helloFromC(), 0).show();    }        //定义一个本地方法,方法体由c语言实现    public native String helloFromC();    }

注:public native String helloFromC()就是我们要用c去实现的方法了,

而关于这个c方法的调用就是:Toast.makeText(this, helloFromC(), 0).show();


第三步:

在hello.c中编写c文件,如:

#include <stdio.h>#include <stdlib.h>#include <jni.h>jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj){//c语言的字符串char* cstr = "hello from c";//把C语言的字符串转换成java的字符串// jstring     (*NewStringUTF)(JNIEnv*, const char*);jstring jstr = (*env)->NewStringUTF(env, cstr);return jstr;}
注:关于c代码的编写

1>

方法名必须是Java_包名_类名_方法名

2>

在方法的形参列表中,JNIEnv* env, jobject obj这两个参数是必须写的

对于无参方法,只需写JNIEnv* env, jobject obj这两个

对于有参方法,则只需在这两个JNIEnv* env, jobject obj参数后边依次添加即可

3>
在Java代码中,public native String helloFromC()方法其返回值是String

所以在C代码中,需要写成jstring

4>

在jni.h头文件中,我们可以看到:


继续查找下去,我们可以看到:

在struct JNINativeInterface { }里边存放了好多的指针,其中有一个指针是:

 jstring     (*NewStringUTF)(JNIEnv*, const char*);
这个函数指针的作用就是将一个字符指针转化成一个jstring

而我们传进来的参数env其类型是JNIEnv*

所以我们要访问NewStringUTF就需要写成:

(*env)->NewStringUTF(JNIEnv*, const char*)


第四步:

编译c代码,其操作步骤如下:

1>

将NDK目录下的ndk-build.cmd命令的路径写到Windows的Path环境变量中去

2>

在jni文件夹下添加Android.mk文件,其内容如下:

 LOCAL_PATH := $(call my-dir)    include $(CLEAR_VARS)<span style="white-space:pre"></span>#编译生成的文件的类库叫什么名字    LOCAL_MODULE    := hello    #要编译的c文件    LOCAL_SRC_FILES := Hello.c    include $(BUILD_SHARED_LIBRARY)

3>

切换到Hello.c文件的目录下,然后用shift + 右键,点击在此处打开命令行窗口,

接着在命令行窗口中使用命令:ndk-build.mk

然后我们就可以看到在libs目录下看到:


注:默认情况下,它只会生成支持ARM架构的CPU,若想要支持我们Intel架构的CPU的手机,

则需要在jni目录下,再新建一个Application.mk文件,在该文件中添加如下内容:

APP_ABI := armeabi armeabi-v7a x86

添加了上述一行代码之后,再在命令行执行ndk-build.cmd文件,就会多生成如下库:


若我们还想要其支持所有平台的CPU,可以在Application.mk文件中换成如下内容:

APP_ABI := all
当执行完ndk-builld.cmd命令后,就会多生成如下库文件:


这样我们编写的C代码就可以支持多个平台了

4>

加载生成的库,其操作如下:

在Java代码中添加如下内容:

static{//加载打包完毕的so类库System.loadLibrary("hello");}

第五步:

运行Java代码,即可看到其效果如下:





注:整个代码的结构及其源码如下:

1>代码结构


2>源码

MainActivity.java

package com.itheima.helloworld1;import android.os.Bundle;import android.app.Activity;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity {static{//加载打包完毕的so类库System.loadLibrary("hello");}    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);            }    public void click(View v){    Toast.makeText(this, helloFromC(), 0).show();    }        //定义一个本地方法,方法体由c语言实现    public native String helloFromC();    }

jni / Hello.c

#include <stdio.h>#include <stdlib.h>#include <jni.h>jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj){//c语言的字符串char* cstr = "hello from c";//把C语言的字符串转换成java的字符串// jstring     (*NewStringUTF)(JNIEnv*, const char*);jstring jstr = (*env)->NewStringUTF(env, cstr);return jstr;}

jni / Android.mk

 LOCAL_PATH := $(call my-dir)    include $(CLEAR_VARS)#编译生成的文件的类库叫什么名字    LOCAL_MODULE    := hello    #要编译的c文件    LOCAL_SRC_FILES := Hello.c    include $(BUILD_SHARED_LIBRARY)

布局文件如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="调用c代码"         android:onClick="click"        /></RelativeLayout>


清单文件如下:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.itheima.helloworld1"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="17" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.itheima.helloworld1.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>



0 0
原创粉丝点击