首先整个实现需要有Android源码编译环境。这里我用的是froyo2.2.

1.JNI层--C++代码部分

在目录frameworks/base/core/jni 下创建android_jnidemo_Hello.cpp(文件名称对应后面java实现的包名)代码内容可参考 android_debug_JNITest.cpp。注:如果把函数声明单独放到.h文件中,Hello.h可放到base/include /android_runtime目录或者自己创建的目录base/include/...../   在.cpp文件中引入#include "android_runtime/Hello.h"

#define LOG_TAG "Demo Jni"
#include "jni.h"
#include "nativehelper/JNIHelp.h"
#include "utils/Log.h"
#include "utils/misc.h" namespace android {//android 命名空间 /*
*return string to app
*/
static jstring android_jnidemo_Hello_getString(JNIEnv *env, jclass clazz)
{
   ALOGI("jni return a string!");
return env->NewStringUTF("Hello framework JNI!");//创建返回一个字符串
} /**
*registtration
*/
static JNINativeMethod gMethods[] = {
{"getString", "()Ljava/lang/String;", (void *) android_jnidemo_Hello_geString},
}; int register_android_jnidemo_Hello(JNIEnv* env)
{
return jniRegisterNativeMethods(env, "android/jnidemo/Hello", gMethods, NELEM(gMethods));
}
}

1.1 执行编译处理实现

修改android_jnidemo_Hello.cpp同目录的Android.mk文件。变量LOCAL_SRC_FILES:= \后加入android_jnidemo_Hello \

修改同目录下的AndroidRuntime.cpp 文件在extern int 后面添加
extern int register_android_jnidemo_Hello(JNIEnv* env); 
然后在static const RegJNIRec gRegJNI[] = {

添加
REG_JNI(register_android_jnidemo_Hello),这样整个JNI 部分就完成了。

2.添加Java 代码

frameworks/base/core/java/android/jnidemo 自己创建目录jnidemo,java 类Hello.java

package android.jnidemo;//包名对应.cpp文件

public class Hello {

    public Hello() {}

    //app will call this native method
public static native String getString();
}

这里的java类中并不需要想,app java结合NDK实现JNI使用那样需加入

static {

  System.loadLibrary("xxx");//动态库

}

应该是上面添加到AndroidRuntime 动态库,使虚拟机启动后就载入了。

3.创建一个apk项目Android project Hello

package com.integration.test;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.jnidemo.Hello; //import自己定义的包 public class HelloActivity extends Activity {
/** Called when the activity is first created. */
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.tv);
Hello hello = new Hello(); //创建自己写的framework java 对象 tv.setText(hello.getString());//调用native method
}
}

3.1保留Hello项目下res/   src/  AndroidManifest.xml 文件,并拷贝项目到源码目录package/apps/下,在项目根目录下添加Android.mk文件

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) #HelloJNI project name
LOCAL_PACKAGE_NAME := HelloJNI include $(BUILD_PACKAGE)

4.将Hello项目加入到系统编译中

在build/target/product/generic.mk文件 变量PRODUCT_PACKAGES := \后面加上HelloJNI \(对应Android.mk文件的LOCAL_PACKAGE_NAME

值)

5.编译

5.1切换到源码根目录下执行. build/envsetup.sh 初始化编译环境(若在此之前没执行过编译命令)

在执行lunch 1 选择编译的产品-----这里我的是默认编译generic

5.2编译前面添加的JNI代码,Android 的编译都是以模块位单位的,Android_Runtime是一个独立模块。

执行命令mm Android_Runtime  重新生成libandroid_runtime.so库,看到Install: out/target/product/generic/system/lib/libandroid_runtime.so结果

编译framework java部分,执行 mm framework

重新编译生成 framework.jar

Install: out/target/product/generic/system/framework/framework.jar

5.3编译Hello apk项目

执行命令mmm package/apps/Hello或者mm HelloJNI 生成HelloJNI.apk   out/target/product/generic/system/app目录下

6.重新生成system.img文件

执行命令 make snod    得到新的 out/target/product/generic/system.img

7.启动emulator 打开HelloJNI apk查看结果(不截图了)

执行命令emulator&   (前提在PATH环境变量中加入system.img ..... 镜像路径和emulator可执行文件路径

/usr/froyo/out/host/linux-x86/bin:/usr/froyo/out/target/product/generic)

也可以

 emulator -kernel ./prebuilt/android-arm/kernel/kernel-qemu -sysdir ./out/target/product/generic -system system.img -data userdata.img -ramdisk ramdisk.img

实现apk 调用framework java JNI中方法的更多相关文章

  1. JAVA JNI 中解决在C/C++跨线程FindClass失败

    在JAVA与C/C++交互时使用JNI接口: 先是在JAVA调用的C++方法中直接测试FindClass,使用获取到的jclass操作没有任何问题: 但是在调用的C++方法中起线程后,在线程中Find ...

  2. C#实现调用Java类中方法

    基本思路: 用C#实现调用Java编写的类中的方法:重点是将Java编写的程序打包成Jar,然后使用开源工具IKVM将其转化成DLL控件,在.NET环境下调用. 分为以下步骤: 1.下载JDK6(注: ...

  3. 我的Java开发学习之旅------>Java语言中方法的参数传递机制

    实参:如果声明方法时包含来了形参声明,则调用方法时必须给这些形参指定参数值,调用方法时传给形参的参数值也被称为实参. Java的实参值是如何传入方法?这是由Java方法的参数传递机制来控制的,Java ...

  4. JAVA 类中方法参数与返回值

    无参无返回值的方法,用public void 方法名,来声明: 有参无返回值的方法,用public void 方法名,来声明: 有参有返回值的方法,用public int 方法名(int i,int ...

  5. java Date中方法toLocaleString过时的替代方案

    DateFormat ddf = DateFormat.getDateInstance(); DateFormat dtf = DateFormat.getTimeInstance(); DateFo ...

  6. Android JNI中C和JAVA代码之间的互相调用

    关于Android studio中使用NDK/JNI环境和入门:http://blog.csdn.net/quan648997767/article/details/64923143 1. C代码回调 ...

  7. Java Native Interface 二 JNI中对Java基本类型和引用类型的处理

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 Java编程里会使用到两种类型:基本类型(如 ...

  8. 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码

    详解C#泛型(二)   一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...

  9. Java应用中使用ShutdownHook友好地清理现场、退出JVM的2种方法

    Runtime.getRuntime().addShutdownHook(shutdownHook);    这个方法的含义说明:        这个方法的意思就是在jvm中增加一个关闭的钩子,当jv ...

随机推荐

  1. Scala分号推断

    看这样段代码,Scala会把它当作两个语句,x 和 +y,如果想把它作为一个语句,可以把它们放在括号里(x+y) x +y 或者也可以把 + 放在行末,也正因为此,串接类似于 + 这样的中缀操作符的时 ...

  2. IIS7添加mp4 MINE类型报错:无法写入配置文件

    解决方法: 方法一: 可能是由于文件为只读属性,所以修改网站文件访问权限,把此文件夹或者文件的写入权限给了这个用户. 方法二: 可能由于网站目录所在的分区是fat32格式,所以要把网站目录放在NTFS ...

  3. logger日志工具类

    日志工厂类 package cn.itcast.utils; import java.util.logging.FileHandler; import java.util.logging.Handle ...

  4. Python笔记5(字符串)-20160921

    一.字符串常用方法 1.title():返回字符串的标题版本,即单词首字母大写其余字母小写 2.upper():返回字符串全部大写版本,lower()则返回字符串全部小写版本 >>> ...

  5. C#中string.Substring 的用法

    String.SubString(int  startIndex,int length)     startIndex:截取字符串开始的位置       length:截取字符串的长度 例子:用户 输 ...

  6. 简单的java程序通过对话框输出 计算加减乘除运算(运算方法可选择)

    import javax.swing.JOptionPane; // import class JOptionPane public class Addition { public static vo ...

  7. sublime text 安装 SFTP

    1  先安装Package Control import urllib.request,os,hashlib; h = 'df21e130d211cfc94d9b0905775a7c0f' + '1e ...

  8. Windows下Discuz搭建论坛过程

    搭建环境:Win7 + XAMPP5.5 + Discuz3.2 GBK 官方论坛下载安装包,解压,把upload文件夹拷贝到网站文档根目录(例如我的为:D:\IT\XAMPP5.5\htdocs\) ...

  9. SVD分解技术数学解释

    SVD分解 SVD分解是LSA的数学基础,本文是我的LSA学习笔记的一部分,之所以单独拿出来,是因为SVD可以说是LSA的基础,要理解LSA必须了解SVD,因此将LSA笔记的SVD一节单独作为一篇文章 ...

  10. 每天200亿次查询 – MongoDB在奇虎360【转】

    100多个应用,1,500多个实例,每天200亿次查询 奇虎是中国最大的安卓移动发布平台.奇虎也是中国最顶尖的病毒软件防护公司,同时为网络以及移动平台提供产品.自从2011年成为MongoDB的用户之 ...