模仿android_debug_JNITest实现apk 调用framework java JNI中方法

来源:互联网 发布:笔记本共享网络给手机 编辑:程序博客网 时间:2024/05/17 22:10

首先整个实现需要有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 := optionalLOCAL_SRC_FILES := $(call all-subdir-java-files)#HelloJNI project nameLOCAL_PACKAGE_NAME := HelloJNIinclude $(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


原创粉丝点击