How to: 在Android系统中添加JAVA API


本文的主要目的是:为native代码添加相应的java api代码添加相应的java api
第一步:编写Java API类,请注意使用<>括起的注释内容
<添加文件头信息:>
/***************************************************************************************************
 *  FileName    : NativeVideoConfig.java
 *  Copyright   : Beijing Cycle Century Digital Technology Co.Ltd. 2003 (c)
 *  Description : dd native api for video config
 *--------------------------------------------------------------------------------------------------
 *  History     :
 *  <time>        <version >   <author>   <desc>
 *  2012-8-23     V1.0.0       zhaoyh      first release.
 ***************************************************************************************************
 */
package android.ccdt.dd;//<命名规则:android.ccdt为统一包开头,随后为所封装的模块名
public class NativeVideoConfig {
  
  //<编写native方法封装>
  // ------------------------- for native code --------------------------
  static {
    System.loadLibrary("dd_jni"); //<加载libdd_jni.so,命名规则为:调用的底层库,加后缀_jni为jni封装库的名字>
  }     
  private static native int set_video_format(int videoformat); //<native方法均为private,禁止java层直接访问,方便今后的代码修改维护>
  private static native int get_video_format();
  private static native int adjust_video_offset(int xoff, int yoff, int width, int height);
  private static native int set_display_brightness(int brightness);
  private static native int set_display_proportion(int proportion);
  //----------------------------------------------------------------------
  //<编写该类的公有接口封装>
  public static enum Proportion{ //<int 类型的数据,都应该用枚举进行一次封装,方便接口的使用,以及代码可读性>
    PROPORTION_E4X3(0),
    PROPORTION_E16X9(1);
        
    private final int value;
    private Proportion(int val) {
      value = val;
    }
    public int getValue() {
      return value;
    }
    public static Proportion getEnum(int val) {
      for (Proportion e : Proportion.values()) {
        if (e.getValue() == val) {
           return e;
        }
      }
      return null;
    }
  }
  public static VideoFormat getVideoFormat(){//<公有接口封装>
     return VideoFormat.getEnum(get_video_format());//<int类型装枚举类型>
  }
  public static int setVideoProportion(Proportion proportion){ //<公有接口封装>
    return set_video_proportion(proportion.getValue());//<枚举类型转int>
  }
}
第二步:编写Android.mk,编译并生成jar包
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
           $(call all-subdir-java-files) \
LOCAL_MODULE:= android.ccdt.dd
LOCAL_MODULE_TAGS := eng
include $(BUILD_JAVA_LIBRARY)
第三步:使用javah生成java文件对应的C++的.h头文件
由于javah只能对.class文件进行进行处理,而编译出来的文件被打成了jar包,因此,首先需要进行解包。对于LOCAL_MODULE:= ccdt_dd的文件,编译生成的jar包位置为:
$(AndroidRoot)/out/target/common/obj/JAVA_LIBRARIES/android.ccdt.dd_intermediates/classes.jar
对jar包解压的命令为:
cd $(AndroidRoot)/out/target/common/obj/JAVA_LIBRARIES/android.ccdt.dd_intermediates/
jar xvf classes.jar
使用javah生成头文件
javah -classpath $(AndroidRoot)/out/target/common/obj/JAVA_LIBRARIES/android.ccdt.dd_intermediates/ -jni android.ccdt.dd.NativeDisplayConfig
第四步:编写api的native实现,编写方法请参照JNI相关规范编写,这里主要描述如何利用现有代码框架,减少编写工作量
在头文件中添加注册函数
int register_android_ccdt_dd_NativeDisplayConfig(JNIEnv *env);
根据头文件中的注释说明,在cpp文件中实现该注册函数
/*
 * Class:     android_ccdt_dd_NativeDisplayConfig
 * Method:    set_video_proportion
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_android_ccdt_dd_NativeDisplayConfig_set_1video_1proportion
 (JNIEnv *, jclass, jint);
static const char* const kClassPathName = "android/ccdt/dd/NativeDisplayConfig";//<java类的包名/类名>
static JNINativeMethod gMethods[] = {
   { "set_video_format", "(I)I", (void*) Java_android_ccdt_dd_NativeDisplayConfig_set_1video_1format },//<拷贝自头文件的说明>
   { "get_video_format", "(I)I", (void*) Java_android_ccdt_dd_NativeDisplayConfig_get_1video_1format },
   { "adjust_video_offset", "(IIII)I", (void*) Java_android_ccdt_dd_NativeDisplayConfig_adjust_1video_1offset },
   { "set_display_brightness", "(I)I", (void*) Java_android_ccdt_dd_NativeDisplayConfig_set_1display_1brightness },
   { "set_video_proportion", "(I)I", (void*) Java_android_ccdt_dd_NativeDisplayConfig_set_1video_1proportion },
};
int register_android_ccdt_dd_NativeDisplayConfig(JNIEnv *env) {
   return AndroidRuntime::registerNativeMethods(env, kClassPathName,
           gMethods, NELEM(gMethods));
}
在JNILoader.cpp中调用注册方法
#include "android_ccdt_dd_NativeDisplayConfig.h"
static int registerNatives(JNIEnv* env) {
   if (register_android_ccdt_dd_NativeDisplayConfig(env) < 0) {
       LOGE("ERROR: NativeDisplayConfig native registration failed\n");
       return JNI_FALSE;
   }
   return JNI_TRUE;
}
第五步:编写Android.mk文件
include $(CLEAR_VARS)
LOCAL_MODULE:= libdd_jni
LOCAL_MODULE_TAGS := eng
LOCAL_PRELINK_MODULE := false
LOCAL_SRC_FILES:= \
   JniLoader.cpp \
   android_ccdt_dd_NativeDisplayConfig.cpp \ #<添加需要编译的模块>
LOCAL_SHARED_LIBRARIES := \ #<链接所需的动态库>
   libandroid_runtime \
   libnativehelper \
   libutils \
   libbinder \
LOCAL_C_INCLUDES += \ #<包含所需的头文件>
   $(TOP)/frameworks/base/core/jni \
   $(TOP)/frameworks/base/include/binder \
include $(BUILD_SHARED_LIBRARY)
第六步:添加权限控制xml
文件名称:android.ccdt.dd.xml 内容:
<?xml version="1.0" encoding="utf-8"?>
<permissions>
   <library name="android.ccdt.dd"
           file="/system/framework/android.ccdt.dd.jar"/>
</permissions>
在产品的makefile中添加对该文件的拷贝:
PRODUCT_COPY_FILES += \
   vendor/broadcom/bcm${BCHP_CHIP}/framework/java/android.ccdt.dd.xml:system/etc/permissions/android.ccdt.dd.xml
第七步:应用程序使用该库
在应用程序的AndroidManifest.xml中进行定义:
<application>
  <uses-library android:name="android.ccdt.dd" />
  ...
  <activity />
</application>

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐