Framework定制-在JAVA核心库中移植Android Log

在java核心库中,由于无法导入android的包,要想使用Log,最粗暴的方式就是用反射调用,还有一种方式就是移植Android的Log到java核心库中。

具体实现如下:

创建JLog.java

复制代码
aosp/libcore/ojluni/src/main/java/java/lang

package java.lang;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONObject;
 
public class JLog {
    public static final String mTag = "Yooha-log";
    public static final int INFO = 4;
    public static final int ERROR = 6;
 
    public static native int println_native(int bufID, int priority, String tag, String msg);
    public static native int getpid();

 
    public static void print_info(String tag, String info) {
        try{
            JSONObject jsinfo = new JSONObject();
            jsinfo.put("Type", tag);
            jsinfo.put("PID", getProcessID());
            jsinfo.put("Info", info);
            i(mTag, jsinfo.toString());
        } catch (Exception e){
            showException(e);
        }
    }
 
    public static void print_stack(String type, String clz, String method, String ret, String...param) {
        try{
            JSONObject jsinfo = new JSONObject();
            jsinfo.put("Type", type);
            jsinfo.put("PID", getProcessID());
            jsinfo.put("Class", clz);
            jsinfo.put("Method", method);
             
            if (param != null){
                jsinfo.put("Param", param.toString());
            }else{
                jsinfo.put("Param", "NULL");
            }
 
            if (ret == null){
                jsinfo.put("Return", "NULL");
            }else{
                jsinfo.put("Return", ret);
            }
            jsinfo.put("stackTrace", getStackTrace());
            i(mTag, jsinfo.toString());
        } catch (Exception e){
            showException(e);
        }
    }
 
    public static String getStackTrace() {
        StringBuffer sb = new StringBuffer();
        try{
            Throwable ex = new Throwable();
            StackTraceElement[] stackElements = ex.getStackTrace();
            for (int i = 0; i < stackElements.length; i++) {
                StackTraceElement element = stackElements[i];
                sb.append("at " +
                        element.getClassName() +
                        "." +
                        element.getMethodName() +
                        "(" +
                        element.getFileName() +
                        ":" +
                        element.getLineNumber() +
                        ")\n");
            }
        } catch(Exception e){
 
        }
        return sb.toString();
    }
 
    public static void showException(Exception e){
        e(mTag, "Type:Exception, ExceptionLine:" + getExceptionLine() + ", Exception:" + e.toString());
    }
 
    public static String getExceptionLine(){
        StackTraceElement element = new Throwable().getStackTrace()[1];
        return element.getFileName() + "-->" + element.getLineNumber() + " : " + element.getClassName();
    }
 
    public static int getProcessID(){
        try{
            return getpid();
        } catch (Exception e){
        }
        return -1;
    }
 
    public static int i(String tag, String msg){
        return println_native(0, INFO, tag, msg);
    }
    public static int e(String tag, String msg){
        return println_native(0, ERROR, tag, msg);
    }
}
  • 将JLog.java文件添加到编译文件链

    • 路径:/home/yooha/aosp/libcore/penjdk_java_files.bp

    filegroup {
    name: "openjdk_javadoc_files",
    srcs: [
    ...省略
    "ojluni/src/main/java/java/lang/System.java",
    ///ADD START
    "ojluni/src/main/java/java/lang/JLog.java",
    ///ADD END
    "ojluni/src/main/java/java/lang/ThreadDeath.java",
    ...省略

    复制代码
      ],

    }

  • 在libcore native层添加JLog.c

    /aosp/libcore/ojluni/src/main/native

    #include <log/log.h>
    #include <utils/Log.h>
    #include <jni.h>
    #include <nativehelper/JNIHelp.h>
    //#include <process.h>
    #include <unistd.h>

    static jint java_lang_JLog_println_native(JNIEnv* env, jclass clazz,
    jint bufID, jint priority, jstring tagObj, jstring msgObj)
    {
    const char* tag = NULL;
    const char* msg = NULL;

    复制代码
      if (msgObj == NULL) {
          //JNU_ThrowNullPointerException(env, "println needs a message");
          return -1;
      }
    
      if (bufID < 0 || bufID >= LOG_ID_MAX) {
          //JNU_ThrowNullPointerException(env, "bad bufID");
          return -1;
      }
    
      if (tagObj != NULL)
          tag = (*env)->GetStringUTFChars(env,tagObj, NULL);
      msg = (*env)->GetStringUTFChars(env,msgObj, NULL);
    
      int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
    
      if (tag != NULL)
          (*env)->ReleaseStringUTFChars(env,tagObj, tag);
      (*env)->ReleaseStringUTFChars(env,msgObj, msg);
    
      return res;

    }

    static jint java_lang_JLog_getpid(JNIEnv* env, jclass clazz){
    return getpid();
    }

    static const JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr /
    { "println_native", "(IILjava/lang/String;Ljava/lang/String;)I", (void
    ) java_lang_JLog_println_native },
    { "getpid", "()I", (void*) java_lang_JLog_getpid }
    };

    void register_java_lang_JLog(JNIEnv* env) {
    jniRegisterNativeMethods(env, "java/lang/JLog", gMethods, NELEM(gMethods));
    }

  • OnLoad.cpp中声明和调用 register_java_lang_JLog

    • 路径:libcore/ojluni/src/main/native/OnLoad.cpp

    ...省略
    ///ADD START
    extern "C" void register_java_lang_JLog(JNIEnv* env);
    ///ADD END
    ...省略
    extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
    ...省略
    ///ADD START
    register_java_lang_JLog(env);
    ///ADD END
    ...省略
    }
    ...省略

  • Android.bp中添加XLog.c文件到编译文件中

    • 路径:/home/yooha/aosp/libcore/ojluni/src/main/native/Android.bp

    filegroup {
    name: "libopenjdk_native_srcs",
    srcs: [
    ...省略
    ///ADD START
    "JLog.c",
    ///ADD END
    ...省略
    ],
    }

最后编译刷机,就可以正常使用了

相关推荐
雨白4 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹6 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空8 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭8 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日9 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安9 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑9 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟13 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡15 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0015 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体