zoukankan      html  css  js  c++  java
  • 实现apk 调用framework java JNI中方法

    首先整个实现需要有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

  • 相关阅读:
    (转)灵活运用 SQL SERVER FOR XML PATH
    Docker
    Springboot
    Redis
    Centos7.6在线安装mysql8.0.16
    Centos7.6安装jdk1.8
    Dubbo
    相关性检验
    逻辑回归和决策树上的一些区别
    postgresql 学习手册(客户端)
  • 原文地址:https://www.cnblogs.com/hei-da-mi/p/5025929.html
Copyright © 2011-2022 走看看