zoukankan      html  css  js  c++  java
  • JNI之HelloWorld

    什么是JNI?

    JNI java本地开发接口
    JNI 是一个协议
    这个协议用来沟通java代码和外部的本地代码(c/c++).
    通过这个协议,java代码就可以调用外部的c/c++代码
    外部的c/c++代码也可以调用java代码

    环境搭建完毕......开始第一个JNI程序咯..╮(╯_╰)╭必写的HelloWorld.
    第一步:
    首先创建一个普通的android工程:























    第二步:

    我们声明2个方法,一个名称是不带下划线的,一个名称带下划线的
    //native方法就是告诉虚拟机,这个方法由本地的代码实现。现在在windows下实现,就是dll了。
    public native String getHelloString(); //声明
    public native String get_Hello_String();//声明

    第三步:

    在项目根目录下创建一个jni目录:

    在jni目录下创建两个文件:Android.mk和Hello.c.

    Android.mk编译文件是用来向Android NDK描述你的C,C++源代码文件的;

      Hello.c c的源文件.我们主要在这个文件里做实现;)

    Android.mk里面该怎么写呢?我们去看下NDK文档(我的路径F: dkandroid-ndk-r7bdocsANDROID-MK.html):


    把下面的代码复制到我们的Android.mk里面:

    LOCAL_PATH := $(call my-dir)

       include $(CLEAR_VARS)

       LOCAL_MODULE    := hello-jni
       LOCAL_SRC_FILES := hello-jni.c


      include $(BUILD_SHARED_LIBRARY)



    然后把hello-jni改成Hello   和hello-jni.c改成Hello.c


    说明(具体请百度Android.mk语法):

    LOCAL_PATH := $(call my-dir)它用来在你的工程树形目录下定位你的资源文件的位置。那个编译系统提供的“my-dir”宏函数用来返回当前目录的路径(Android.mk文件所在的目录)

     LOCAL_MODULE 是定义模块的名字

    注意,编译系统会给相应的生成文件自动地添加适当的前缀和后缀。换句话说,一个命名为“Hello”的共享库module将生成名为“libHello.so”的文件。

    如果你的模块命名为“libHello”,编译系统不会为你添加另外一个“lib”前缀,还是会生成一个“libHello.so”的文件而已。

    LOCAL_SRC_FILES变量必须包含一个将要被编译和汇编进module的一个C/C++资源文件列表

    include $(BUILD_SHARED_LIBRARY)编译出的是动态库

    Hello.c代码如下:

    #include <stdio.h>
    #include <jni.h>
    
    jstring Java_com_pl_demo1_MainActivity_getHelloString(JNIEnv* env,jobject obj){
    
    
    return (*(*env)).NewStringUTF(env,"1.hello world!");
    }
    
    
    jstring Java_com_pl_demo1_MainActivity_get_1Hello_1String(JNIEnv* env,jobject obj){
    return (*env)->NewStringUTF(env,"2.__hello___!");
    }
    

    jni.h头文件可以具体去看看内容.

    (严格区分大小写)

    返回值 Java_包名_类名_方法名(JNIEnv* env,jobject obj)

    两个参数先用吧 暂时不说明用途

    带下划线的方法名和普通的区别是 在下划线后面添加一个1

    第四步:打开Cygwin进入到项目根目录执行ndk-build:


    cygdirve是计算机的根目录

    f是我的盘符

    我的项目是在F:summerVacation dkhelloworld

    像上图情况表示已经搞定了。下面我们去项目中看看 (刷新一下项目):


    第五步:

    在MainActivity.java里实现静态代码块里加载动态链接库(去掉libHello.so前缀和后缀):

    static{
    		System.loadLibrary("Hello");//加载动态链接库(把二进制库文件加载到java虚拟机里)
    	}


    第六步:

    在layout布局里面定义个Button并激活点击事件:

    main.xml

    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        xmlns:android="http://schemas.android.com/apk/res/android">
     <Button 
         android:id="@+id/bt_c_hello"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="连接底层c动态链接库"
         />
    </LinearLayout>

    MainActivity.java

    package com.pl.demo1;
    
    import com.example.ndkhelloworld.R;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class MainActivity extends Activity implements OnClickListener {
    	private Button bt_c_hello;
    	static{
    		System.loadLibrary("Hello");//加载动态链接库(把二进制库文件加载到java虚拟机里)
    	}
    	//ative方法就是告诉虚拟机,这个方法由本地的代码实现。现在在windows下实现,就是dll了。
    	public native String getHelloString(); //声明
    	public native String get_Hello_String();//声明
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		 bt_c_hello = (Button) findViewById(R.id.bt_c_hello);
    		 bt_c_hello.setOnClickListener(this);
    	}
    	@Override
    	public void onClick(View v) {
    		// TODO Auto-generated method stub
    		Toast.makeText(getApplicationContext(),"普通的方法名:"+getHelloString(),Toast.LENGTH_SHORT).show();
    		Toast.makeText(getApplicationContext(),"第二个方法名带_:"+get_Hello_String(),Toast.LENGTH_SHORT).show();
    	}
    }
    


    好了 点击界面的按钮调用native声明的方法就会调用c的Hello.c的函数

    源码下载地址:http://download.csdn.net/detail/pl83447876/6572641

    手写Hello.c函数容易出错,所以我们用: Javah生成JNI头文件 

  • 相关阅读:
    对100以内的两位数,请使用一个两重循环打印出所有十位数数字比个位数数字小的数,
    给定两个不同的变量,不使用中间变量的情况下互换两个变量的值,使用函数直接生成
    将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
    POJ 2138 最长路
    POJ 2133 暴搜
    POJ 1988 带偏移量的并查集
    POJ 1989 贪心
    POJ 1991 DP
    POJ 3175 枚举
    POJ 3168 排序+扫描
  • 原文地址:https://www.cnblogs.com/riasky/p/3430884.html
Copyright © 2011-2022 走看看