Android JNI例程

本文通过一个具体实例,介绍了如何在Android应用中使用JNI技术调用C/C++代码,包括环境搭建、按钮点击事件处理、字符串及整数传递等关键步骤。

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

操作环境:32bit Ubuntu12.04+Android编译环境

配置Android编译环境和NDK的过程不再叙述,下面记录一个完整的例子。例子功能是:按下button1,从jni中取出一个字符串到textview;按下button2,把两个editview的int值传递到jni进行加法运算然后返回结果到textview显示。顺便实现了最简单的jni的参数传递。

eclipse可以按照下面的步骤逐步建立,也可以下载整个工程文件,下载链接:http://download.youkuaiyun.com/detail/cleanness/6281613

1、打开eclipse,创建工程“MyJniTest”

XML如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="85dp"
        android:text="Button" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="39dp"
        android:text="Button" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignRight="@+id/button1"
        android:layout_marginTop="35dp"
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/button2"
        android:layout_marginTop="42dp"
        android:layout_toLeftOf="@+id/button2"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <EditText
        android:id="@+id/editText2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/editText1"
        android:layout_alignBottom="@+id/editText1"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@+id/button2"
        android:ems="10" />

</RelativeLayout>

MyJniTestActivity 如下:

package com.example.myjnitest;

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

public class MyJniTestActivity extends Activity implements OnClickListener{

	public native int addint(int a,int b);
	public native String StringFromJni();
	
	private Button btn1;
	private Button btn2;
	private TextView text1;
	private EditText edit1;
	private EditText edit2;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.myjnitestxml);
        
        btn1 = (Button)findViewById(R.id.button1);
        btn2 = (Button)findViewById(R.id.button2);
        text1 = (TextView)findViewById(R.id.textView1);
        edit1 = (EditText)findViewById(R.id.editText1);
        edit2 = (EditText)findViewById(R.id.editText2);
        
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        
    }

    public void onClick(View v)
    {
    	switch(v.getId())
    	{
    	case R.id.button1:
    	{
    		int a1 = Integer.parseInt(edit1.getText().toString());
    		int a2 = Integer.parseInt(edit2.getText().toString());
    		int a = addint(a1,a2);
    		String aa = String.valueOf(a);
    		
    		text1.setText(aa);
    		
    	}
    	break;
    	case R.id.button2:
    	{
    		text1.setText(StringFromJni());
    		
    	}
    	break;
    	default:break;
    	}
    	
    	
    }
    
    static{
    	System.loadLibrary("MyJniTest");
    	
    	
    }
    
}



2、用eclipse编译该工程,生成相应的.class文件,这步必须在下一步之前完成,因为生成.h文件需要用到相应的.class文件。

编译生成的class文件在你的bin目录先,比如我的是在/home/kang/workspace/MyJniTest/bin/classes/com/example/myjnitest/中有一个MyJniTestActivity.class既是生成的class文件。


3、生成",h"头文件

       1)进入工程目录,方法:在终端执行  cd /home/kang/workspace/MyJniTest/ 

  2)在工程目录下建立jni文件夹,方法:在终端执行  mkdir jni

3)   使用工具javah生成.h文件,方法:在终端执行  javah -classpath  /home/kang/workspace/MyJniTest/bin/classes/  -d   /home/kang/workspace/MyJniTest  com.example.myjnitest.MyJniTestActivity

              这条命令的意思是利用MyJniTestActivity.class在路径/home/kang/workspace/MyJniTest/jni生成.h文件

      如果出现如下错误:

Error: cannot access android.app.Activity
class file for android.app.Activity not found

       附上android.jar的地址即可,方法:在终端执行   javah -classpath /home/ kang/android/env/adt-bundle-linux-x86-20130717/sdk/platforms/android-17/android.jar:/home/ kang/workspace/MyJniTest/bin/classes/  -d   /home/ kang/workspace/MyJniTest/jni  com.example.myjnitest.MyJniTestActivity

               这一步出现的问题大部分都是路径错误,仔细检查路径即可解决。


4、编写c/c++文件

       在Eclipse里面New->File->MyJniTest(选择项目)->jni(选择新建文件存放路径),填写File Name: MyJniTest.c(可任意命名)

#include<string.h>
#include<jni.h>

JNIEXPORT jint JNICALL Java_com_example_myjnitest_MyJniTestActivity_addint(JNIEnv * env,jobject thiz,jint a,jint b)
{
	int c = a+b;
	return c;

	//return (*env)->NewStringUTF(env,"this is 1");
}

JNIEXPORT jstring JNICALL Java_com_example_myjnitest_MyJniTestActivity_StringFromJni(JNIEnv * env,jobject thiz,jint a,jint b)
{
	return (*env)->NewStringUTF(env,"haha from .c");
}


5、编写Android.mk文件
      在Eclipse里面New->File->MyJniTest(选择项目)->jni(选择新建文件存放路径),填写File Name: Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE :=MyJniTest
LOCAL_SRC_FILES :=MyJniTest.c

include $(BUILD_SHARED_LIBRARY)

6、生成.so动态链接库

1)进入jni目录,方法:终端执行  cd /home/kang/workspace/MyJniTest/jni

2)用NDK工具生成动态链接库,方法:终端执行  ndk-build

        成功后你会看到多了一个.so。

7、在eclipse中reflash工程,编译运行。

可能还会遇到其他的问题,大部分都是编译环境没有配置好,编译过程中路径没有取对的问题,仔细检查即可修复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值