您的位置:首页 > 移动开发 > Android开发

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

2015-10-26 09:40 447 查看
第一步:

在工程目录下创建一个文件夹,名为 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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: