要想阅读并调试下文源码,首先要确保你的NDK环境是ok的;
       编译环境:win7+Eclipse+ADT+SDK+NDK;基本用最新的就ok。
       说明下,下文代码就是一个简单的个人jni实现【挺简单的个实现,只是完整实现出来之间经历了好多曲折,记录下呵】;
       不是现成的例子,是自己学习了下jni对Java、c/c++的映射关系之后的一个实现,如有不妥请指正。
       先看一下开始到结束的流程: 【1-10步】
       1.建立普通Android工程:
 
        2.垒一个傻瓜布局,用来显示jni回传信息:

     3.手工创建jni目录-【工程根目录下】

      4.然后在jni目录下建立native实现的源文件(**.c/**.cpp);

      5.进行逻辑实现[见下文];

      6.生成相应的Android.mk文件:

      7.对Android.mk文件属性进行确认:尤其是注意源文件后缀名!!!!

      8.确认无误后通过 debug模式进行动态库(*.so)的编译、生成:此步骤处于Eclipse的C/C++视图下

而后生成相应的*.so动态库,自动嵌入到libs/armeabi目录下;
        其中obj目录下生成的是中间文件*.o;其中控制台输出的日志我还不清楚什么意思,有明白的请明示:


      9.编译无误后,切换到Eclipse的Java视图下,进行普通的Android项目运行操作:

10.正常操作后的效果演示:   
            日志效果:

真机实测效果:
     

好啦, 到现在为止,效果已经看的差不多了,那么接下来就是上代码了··
     1. 傻瓜布局文件:

<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" > <TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下面将显示来自jni端的返回--" /> <TextView
android:id="@+id/show_jni_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView2"
android:layout_below="@+id/textView2"
android:layout_marginTop="77dp"
android:text="此处即将显示来自jni的消息--" /> <Button
android:id="@+id/jni_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/textView2"
android:layout_marginTop="17dp"
android:text="点击此btn调用jni方法" /> </RelativeLayout>

2.activity实现:很简单-点击按钮显示jni回传信息

package com.quanjin.jni;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class QuanjinJniActivity extends Activity implements OnClickListener { private static final String TAG = "MainActivity";
private Button jniButton;
private TextView showJniText; //加载共享库
static {
System.loadLibrary("quanjin_jni");//去掉共享库的前缀lib/后缀so
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quanjin_jni);
Log.d(TAG, show());//log查看返回值。
Log.d("info_out", show()); jniButton = (Button) findViewById(R.id.jni_btn);
showJniText = (TextView) findViewById(R.id.show_jni_text);
jniButton.setOnClickListener(this);
} //声明native方法 在jni中实现。
private native String show();
private void callback() {
Log.d(TAG, " call back from native");
//故意抛出一个异常留给jni处理,如果处理,java层就不会抛;不处理,java层就会抛出异常;
throw new NullPointerException();
} @Override
public void onClick(View v) {
if(v.getId() == R.id.jni_btn) {
//将jni返回值显示在特定控件上。
showJniText.setText(show());
}
} }

3.最重要大部分: native部分的实现-- 看你用什么语言了C/C++都可以;只是C用JNIEve时要先解引用;

#include <string.h>
#include <jni.h> jstring
Java_com_quanjin_jni_QuanjinJniActivity_show( JNIEnv* env, jobject thiz)
{
//通过此方法得到传入对象的类型信息
//此时的对象,就是调用native方法的那个对象
jclass jcls = (*env)->GetObjectClass(env, thiz);
//根据类信息得到callback方法的methodID
jmethodID jmId = (*env)->GetMethodID(env, jcls, "callback", "()V");
//调用callback方法
(*env)->CallVoidMethod(env, thiz, jmId);
//Java层的callback方法中抛出异常, 故此时 jni调用必然出现异常, 必须检查并处理异常;否则异常将会抛给Java层的callback方法;
//而此时的Java层的callback也未捕获异常, 故:此时进程死掉;
if((*env)->ExceptionCheck(env))
{
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);//清除异常;如果注销此句,异常将被抛回至Java层,即Java层中将在log中显示异常情况;
}
//处理异常后响应Java层的调用
return (*env)->NewStringUTF(env, "show message from jni by quanjin!"
"\n ABCDEFGHIGKLMNOPQRSTUVWXYZ \n "
"when you have watch the above messages, congratulations, you got it!");
//中文貌似乱码了-- 大爷的 \\n 中文: 这是来自本人写的jni内容, 当你看到这些话的时候呢, 恭喜你, jni调用成功啦
}

说明下: 如果没接触过的同志们,可能看起来云里雾里的,阅读前先熟悉下jni的函数签名规则比较好【稍后博客继续探讨】;
   详情见代码注释。主要用Java反射,通过获得由jni传进来的对象引用,然后相继获得其他信息;
   至于拓展开来,其他业务逻辑该怎么去展开,之后博客再写一下,今天的内容主要是开个头吧~~~
          嗯 , 基本先说这么多吧; 百闻不如一试试,完整的项目就不贴出来了, 如果有需要进一步研究的请留言附邮箱地址。

建议:
     1. 我之前一直在项目过程中抽空研究C++,其实过程中既增强了自己对面向对象的理解,又可以更深入的研究Android框架源码(Java+C++);
     感觉都是差不多的,了解基础性内容不难,若真想做到融会贯通,短时间内不太容易,慢慢深入慢慢研究吧;
     2. Android源码是个好东西哦~ 无论是哪个版本的,有空的时候阅读一下,感觉真的很爽;就像你在拜读一本武林秘籍一样,你也不知道该怎么读,但是当你开始着迷的时候便一发不可收拾,太棒了!

Android-JNI编程-图文解析的更多相关文章

  1. Android jni 编程4(对基本类型二维整型数组的操作)

    Android jni 编程 对于整型二维数组操作: 类型一:传入二维整型数组,返回一个整型值 类型二:传入二维整型数组,返回一个二维整型数组 声明方法: private native int Sum ...

  2. Android jni 编程(参数的传递,成员,方法的)相互访问

    package com.test.androidjni; import android.app.Activity; import android.os.Bundle; import android.u ...

  3. 【转】Android JNI编程—JNI基础

    原文网址:http://www.jianshu.com/p/aba734d5b5cd 最近看到了很多关于热补的开源项目——Depoxed(阿里).AnFix(阿里).DynamicAPK(携程)等,它 ...

  4. Android jni 编程3(对基本类型一维整型数组的操作)总结版

    主要学习资料:黑马程序员的NDK方法使用(生产类库so)              jni编程指南中文版(已上传至博客园) 博主文章(它使用的是VS和eclipse联合开发):http://www.c ...

  5. Android jni 编程入门

    本文将介绍如何使用eclipse和ndk-build来编写一个基于Android4.4版本的包含有.so动态库的安卓程序. 前提是已经安装和配置好了诸如SDK,NDK等编译环境.下面开始编程! 1 程 ...

  6. 【转】android JNI编程 一些技巧(整理)

    原文网址:http://blog.csdn.net/linweig/article/details/5203716 本篇将介绍在JNI编程中如何传递参数和返回值. 首先要强调的是,native方法不但 ...

  7. Android JNI 之 JNIEnv 解析

    jni.h文件 : 了解 JNI 需要配合 jni.h 文件, jni.h 是 Google NDK 中的一个文件, 位置是 $/android-ndk-r9d/platforms/android-1 ...

  8. 【Android 系统开发】Android JNI 之 JNIEnv 解析

    . jni.h文件 : 了解 JNI 需要配合 jni.h 文件, jni.h 是 Google NDK 中的一个文件, 位置是 $/android-ndk-r9d/platforms/android ...

  9. Android JNI编程(八)——体验AS2.2.2编写Jni程序、Java调C、C调Java函数、将C代码中的Log打印至Logcat

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 不得不说在AS2.2以上的版本进行开发就一个字——爽,在2.0上使用jni出 ...

随机推荐

  1. BNU10791:DOTA选人

    DOTA(Defense of the Ancients)是一款很受欢迎的游戏.DOTA将10个游戏玩家分为两组,分别为天灾和近卫,推倒对方主基地的一方获得胜利.每个玩家可以选择一个英雄作为游戏中的角 ...

  2. DotNet加密方式解析--散列加密

    没时间扯淡类,赶紧上车吧. 在现代社会中,信息安全对于每一个人都是至关重要的,例如我们的银行账户安全.支付宝和微信账户安全.以及邮箱等等,说到信息安全,那就必须得提到加密技术,至于加密的一些相关概念, ...

  3. exec与xargs区别

    区别描述: 两者都是对符合条件的文件执行所给的Linux 命令,而不询问用户是否需要执行该命令. -exec:{}表示命令的参数即为所找到的文件,以:表示comman命令的结束.\是转义符,因为分号在 ...

  4. 获取sqlserver数据库中所有库、表、字段名的方法

    获取sqlserver数据库中所有库.表.字段名的方法 2009年03月12日 星期四 下午 12:51 1.获取所有数据库名: SELECT Name FROM Master..SysDatabas ...

  5. compilation 元素(ASP.NET 设置架构)

    配置 ASP.NET 用于编译应用程序的所有编译设置. <configuration> 元素  system.web 元素(ASP.NET 设置架构)    compilation 元素( ...

  6. NSString字符串类型-学习总结

    1.字符串的创建 (1)创建常量字符串 NSString *str = @"This is a String"; //str是变量名 (2)创建空的字符串,给字符串赋值 NSStr ...

  7. UVa10651(记忆化搜索)

    题意: 给一串-和o组成的字符串,你可以把“-oo"变成”o--",可以把“oo-”变成“--o",问最后最少有多少个o. 状态压缩 ,记忆化搜索 code: #incl ...

  8. mysql索引之普通索引

    1,普通索引的创建 普通索引可以在建表的时候创建 sql : create table temp2(id int(10) not null auto_increment ,title varchar( ...

  9. 【android】android中activity的启动模式

    在AndroidManifest.xml中配置 <activity android:label="第二个应用" android:name=".Demo2Activi ...

  10. 【7】使用css/js/html模板来实现一个注册、登录和管理的功能

    分支:auth static添加文件 css文件夹: app.css    自定义css样式[*] bootstrap.min.cs    bootstrap样式 compomemts文件夹: 插件用 ...