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
    ...省略
    ],
    }

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

相关推荐
tangweiguo030519871 小时前
Android Kotlin ViewModel 错误处理:最佳 Toast 提示方案详解
android·kotlin
火柴就是我2 小时前
android 基于 PhotoEditor 这个库 开发类似于dlabel的功能_2
android
每次的天空3 小时前
Android学习总结之Java篇(一)
android·java·学习
8931519604 小时前
Android开发Glide做毛玻璃效果
android·glide·android开发·android教程·glide做毛玻璃效果
whysqwhw4 小时前
DRouter代码走读
android
人生游戏牛马NPC1号5 小时前
学习Android(五)玩安卓项目实战
android·kotlin
前行的小黑炭6 小时前
Android Lifecycle代码分析:为什么使用;注解的方式为什么过期?源码分析;状态与事件
android
和煦的春风6 小时前
案例分析 | SurfaceFlinger 大片Runnable引起的卡顿
android·linux
浩宇软件开发7 小时前
Android开发,实现一个简约又好看的登录页
android·java·android studio·android开发
未扬帆的小船8 小时前
在gpt的帮助下安装chales的证书,用于https在root情况下抓包
android·charles