Android_10_Java调用C代码(纯手工制作)
2015-10-26 09:40
447 查看
第一步:
在工程目录下创建一个文件夹,名为 jni ,然后在jni目录下创建一个c文件,例如我的c文件名为:Hello.c
第二步:
在Java程序中定义一个本地方法,这个方法是要我们用c来实现的,如:
注:public native String helloFromC()就是我们要用c去实现的方法了,
而关于这个c方法的调用就是:Toast.makeText(this, helloFromC(), 0).show();
第三步:
在hello.c中编写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 { }里边存放了好多的指针,其中有一个指针是:
而我们传进来的参数env其类型是JNIEnv*
所以我们要访问NewStringUTF就需要写成:
(*env)->NewStringUTF(JNIEnv*, const char*)
第四步:
编译c代码,其操作步骤如下:
1>
将NDK目录下的ndk-build.cmd命令的路径写到Windows的Path环境变量中去
2>
在jni文件夹下添加Android.mk文件,其内容如下:
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文件中换成如下内容:
当执行完ndk-builld.cmd命令后,就会多生成如下库文件:
这样我们编写的C代码就可以支持多个平台了
4>
加载生成的库,其操作如下:
在Java代码中添加如下内容:
第五步:
运行Java代码,即可看到其效果如下:
注:整个代码的结构及其源码如下:
1>代码结构
2>源码
MainActivity.java
jni / Hello.c
jni / Android.mk
布局文件如下:
清单文件如下:
在工程目录下创建一个文件夹,名为 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>
相关文章推荐
- Android创建项目时候为什么是RelativeLayout
- Android studio 中的Theme Editor神器
- Android 4.0新组件:GridLayout详细说明
- Android版本和API Level对应关系
- Android的Socket通信编程实例
- Android Studio 引入第三方库
- Android修改TitleBar标题栏详解
- Android基础控件之Button的基本使用
- Android逆向之旅---Android应用的汉化功能(修改SO中的字符串内容)
- 倍数提高工作效率的 Android Studio 奇技
- Android USB Host 通信程序
- FFmpeg的Android平台移植—编译篇
- android图片预览
- Android Api Demos登顶之路(110)View-->Lists-->Transcript
- Android中历史浏览功能的实现
- Android中对Activity的一些封装
- Android Studio,TextView运行时显示中文乱码
- android:windowSoftInputMode
- [转]android手机连接mac调试
- android studio 快捷键