android NDK入门篇----混合使用java和c/c++代码

本文介绍了如何在Android应用开发中使用NDK进行Java和C/C++混合编程,包括声明本地方法、实现JNI粘合层、创建Android makefile、编译本地库和加载本地库的步骤。通过示例代码详细阐述了JNI的使用和Android.mk文件的配置,并提供了源码工程下载链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在android应用开发过程中,从Java调用C/C++函数主要经历以下几个步骤:

        1. 必须在java代码中声明本地方法。

        2.需要实现java本地接口(JNI)粘合层。

3.必须创建Android makefile文件。

4.必须用C/C++实现本地方法。

5.必须编译本地库。

6.必须加载本地库。

    

        android-NDK为我们提供了一整套的机制来完成这些步骤。我采用的是NDKr8版本,完全不用Cygwin(貌似从NDKr7开始就可以完全不用Cygwin了)。

        前篇:新建android工程MyJNITest,步骤省略,示例代码如下:

       代码清单1:activity_main.xml

<LinearLayout 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" 
    android:orientation="vertical">

    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
         <EditText 
	        android:layout_width="wrap_content" 
	        android:layout_height="wrap_content"
	        android:text="加法:20+70="/>
        <Button 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/addition"
            android:text="计算"
            android:onClick="calculate"/>
    </LinearLayout>
   
	<EditText 
	    android:id="@+id/addtionResult"
	    android:layout_width="fill_parent"
	    android:layout_height="40dip"
	    android:hint="点击计算按钮,进行加法运算"/>
    
    <LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
     <EditText 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"
     android:text="乘法:20*70="/>
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/multiplication"
        android:text="计算"
        android:onClick="calculate"/>/>
    </LinearLayout>
    
	<EditText 
	    android:id="@+id/multiplicationResult"
	    android:layout_width="fill_parent"
	    android:layout_height="40dip"
	    android:hint="点击计算按钮,进行乘法运算"/>
</LinearLayout>
代码清单2:MainActivity.java

package com.example.myjnitest;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends Activity {

	private EditText additionResult,multiplicationResult;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		additionResult=(EditText)findViewById(R.id.addtionResult);
		multiplicationResult=(EditText)findViewById(R.id.multiplicationResult);
	}
	
	public void calculate(View view)
	{
		int id=view.getId();
		switch (id) {
		case R.id.addition:
			long addResult=addition(20, 70);
			additionResult.setText("20+70="+addResult);
			break;

		case R.id.multiplication:
			long mulResult=multiplication(20, 70);
			multiplicationResult.setText("20*70="+mulResult);
			break;
		}
	}
	
    //本地方法,由java调用
    private native long addition(int i,int j);
    
    public static native long multiplication(int a,int b);

}

1. 声明本地方法:

示例代码2中有两个方法,addition()和multiplication()方法。这就是java中声明的本地方法,只是比普通的方法多了native关键字(native关键字不可省略),这些方法并没有具体的实现。从调用者角度来看,一旦声明了本地方法就可以在java代码中调用,会顺利通过编译。不过,如果应用运行并调用这两个本地方法的话,就会蹦出IllegalStateException异常,这很好理解,因为本地方法还没有具体实现。

        本地方法可以是公共的,也可以是受保护的、私有的或包作用域的,如同任何其他java方法一样。同样,本地方法不一定必须是静态的,也不是必须使用基本类型。

2.实现JNI粘合层:

java通过JNI框架调用库里的C/C++方法。可以利用JDK(java开发工具包)建立JNI粘合层。首先,需要在C/C++头文件中声明要实现的函数。建议使用JDK的javah工具自动生成头文件。

在cmd中,进入MyJNITest工程根目录,例如我的工程根目录为 E:\workSpace\MyJNITest,然后在此目录下使用javah命令:

       将本地方法放在了MainActivity.java类中,使用javah命令:

javah -classpath ./bin/classes -d jni com.example.myjnitest.MainActivity

会蹦出如此错误,找不到android.app.Activity的类文件。跳出该错误,猜想可能得原因是由于没有找到android.jar包,可能得在某个参数中指定下路径,在此不纠结其原因,以后的文章中再详细解释吧。

避免该问题有两种解决办法,仅是避免而已:

                方法一: 在cmd中进入工程的src目录下,执行javah命令:

        javah  -d jni com.example.myjnitest.MainActivity

          

        这样会在src目录下成功生成一个jni文件夹,头文件就在该jni文件夹中。

方法二:不要将本地方法写在MainActivity.java类中,而是单独放在一个普通类中

        代码清单3:NativeMethodsClass.java

package com.example.myjnitest;

public class NativeMethodsClass {

	  //本地方法,由java调用
    private native long addition(int i,int j);
    
    public static native long multiplication(int a,int b);
}
再执行javah命令:

javah -classpath ./bin/classes -d jni com.example.myjnitest.NativeMethodsClass

就会在工程的根目录下生成jni文件夹,该文件夹中包含头文件。


采用方法一,生成头文件,

代码清单4:com_example_myjnitest_MainActivity.h

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值