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>
- Android_10_Java调用C代码(纯手工制作)
- Android_10_java调用C(借助NDK工具自动生成.so)
- 手工编译java,手工打包, 纯手工制作
- div+css3纯手工制作登录页
- 纯天然手工制作RS232/TTL转换模块
- 辣出翔,纯手工制作,辣椒酱中的极品辣出翔辣椒酱
- 纯手工制作—Android原生手势锁
- 利用POI实现复杂表头制作(纯手工)
- 手工编写测试代码(C#)
- 纯手工代码使用COM/ActiveX控件(如何不通过注册表)
- 纯手工gcc 编译android native Cpp代码
- VC 纯资源DLL制作及调用
- VC 纯资源DLL制作及调用
- VC 纯资源DLL制作及调用
- VC 纯资源DLL制作及调用
- C#_delegate - 有返回值手工调用
- 使用纯swift代码文件制作framework
- 堆排序 纯C代码
- android android.view.InflateException: Binary XML file line #14: Error inflating class<unknown>
- Android创建项目时候为什么是RelativeLayout
- Android工程导入时常见的错误解决方法
- android在Service,BroadCast onReceiver()中弹出Dialog对话框
- DocumentEditor: Markdown
- Android_10_Java调用C代码(纯手工制作)
- Storm——基本概念
- Truncate Table 用法
- 以空间换时间计算Fibonacci数列
- AxWindowsMediaPlayer的详细用法
- RSA加解密签名验证的简要介绍
- 寻找旋转排序数组中的最小值
- 图像滤镜艺术---Photoshop实现Instagram之Mayfair滤镜效果
- IOS-UIImageView