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

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

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值