Android系统定制开发

作者: 小村医 | 来源:发表于2019-07-02 10:59 被阅读10次

一、系统APP开发

在这里以系统计算器为例,通过修改计算器代码并运行。
在主界面Calculator中添加一行Log输出

public class Calculator extends Activity
        implements OnTextSizeChangeListener, OnLongClickListener,
        AlertDialogFragment.OnClickListener, Evaluator.EvaluationListener /* for main result */,
        DragLayout.CloseCallback, DragLayout.DragCallback {
  ......
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("huang", "11");
        ......
  }
}

应用开发中可以使用ide直接运行安装到手机上,在系统开发中需要使用mm命令来构建系统级APP,在Calculator项目的根目录下运行mm:

[ 75% 3/4] glob vendor/google_data/pgo-profiles/art/dex2oat_x86_x86_64.profdata
[ 22% 2/9] Target Java: out/target/common/obj/APPS/ExactCalculator_intermediates/classes-full-debug.jar
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
[ 55% 5/9] Proguard: out/target/common/obj/APPS/ExactCalculator_intermediates/classes-proguard.jar
ProGuard, version 5.1
Reading input...
Reading system jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/JAVA_LIBRARIES/core-oj_intermediates/classes-header.jar]
Reading system jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes-header.jar]
Reading system jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes-header.jar]
Reading system jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes-header.jar]
Reading system jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/JAVA_LIBRARIES/okhttp_intermediates/classes-header.jar]
Reading system jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes-header.jar]
Reading system jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/JAVA_LIBRARIES/core-lambda-stubs_intermediates/classes-header.jar]
Reading program jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/APPS/ExactCalculator_intermediates/classes.jar]
Initializing...
Ignoring unused library classes...
  Original number of library classes: 15678
  Final number of library classes:    15678
Shrinking...
Removing unused program classes and class elements...
  Original number of program classes: 2066
  Final number of program classes:    633
Writing output...
Preparing output jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/APPS/ExactCalculator_intermediates/classes-proguard.jar]
  Copying resources from program jar [/Volumes/M1/aosp/android9.0/out/target/common/obj/APPS/ExactCalculator_intermediates/classes.jar]
[100% 9/9] Install: out/target/product/generic_x86_64/system/app/ExactCalculator/ExactCalculator.apk
#### build completed successfully (17 seconds) ####

执行成功后可以从log中看到,Install后面就是apk的路径,然后就可以使用adb进行安装了

二、Framework定制

Framework层的定制一般是为了APP层或整个系统的某一种需求。
如:修改Activity.java,在Activity onCreate中打印一行日志,模拟对系统的修改

@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
    Log.d("huang","activity onCreate");
}

如果不知道Activity.java所对应的Android.mk是哪一个,可以之间在Activity.java所在的目录中执行mm,mm会自动向上去查找修改文件所属的module进行编译

[ 80% 4/5] glob frameworks/base/core/java/**/*.java
[ 25% 2/8] //frameworks/base:framework javac0 [common]
注: 某些输入文件使用或覆盖了已过时的 API。
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
注: 某些输入文件使用了未经检查或不安全的操作。
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
[100% 8/8] Install: out/target/product/generic_x86_64/system/framework/framework.jar

#### build completed successfully (47 seconds) ####

编译成功后会输出编译完成的文件路径,下面需要做的就是把ramework.jar push到模拟器的/system/framework目录下:

adb push out/target/product/generic_x86_64/system/framework/framework.jar /system/framewerror

直接push会报下面的错误

adb: error: failed to copy 'out/target/product/generic_x86_64/system/framework/framework.jar' to '/system/framework/framework.jar': remote couldn't create file: Read-only file system
out/target/product/generic_x86_64/system/framework/framework.jar: 0 files pushed. 260.3 MB/s (1376088 bytes in 0.005s)

这是因为system文件是只读文件,需要设置成可写文件:

  1. 模拟器启动时添加-writable-system
emulator -writable-system
  1. 重新挂载系统分区
adb remount

再次调用adb push就可以把新编译生成的framework.jar push到系统的system/framework/目录下,最后使用adb reboot重启一下模拟器就可以了

三、JNI层修改与运行

在这修改一下Log输出,如果TAG等于“huang”,修改输出内容,看一下Log的源码,最终输出会调用public static native int println_native(int bufID, int priority, String tag, String msg);函数。
看一下修改后的jni方法:

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

    if (msgObj == NULL) {
        jniThrowNullPointerException(env, "println needs a message");
        return -1;
    }

    if (bufID < 0 || bufID >= LOG_ID_MAX) {
        jniThrowNullPointerException(env, "bad bufID");
        return -1;
    }

    if (tagObj != NULL)
        tag = env->GetStringUTFChars(tagObj, NULL);
    msg = env->GetStringUTFChars(msgObj, NULL);

    if(strcmp(tag,"huang")==0){
        msg="Finally wait for you.";
    }

    int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);

    if (tag != NULL)
        env->ReleaseStringUTFChars(tagObj, tag);
    env->ReleaseStringUTFChars(msgObj, msg);

    return res;
}

在修改的文件目录下执行mm进行编译

[ 80% 4/5] glob .
[100% 18/18] build out/target/product/generic_x86_64/obj_x86/SHARED_LIBRARIES/libandroid_runtime_intermediates/libandroid_runtime.so

编译完成后会返回so的数据路径

adb push out/target/product/generic_x86_64/obj_x86/SHARED_LIBRARIES/libandroid_runtime_intermediates/libandroid_runtime.so /system/lib/libandroid_runtime.so
adb reboot

把so文件push到 /system/lib/目录下冲洗模拟器,修改生效。

相关文章

网友评论

    本文标题:Android系统定制开发

    本文链接:https://www.haomeiwen.com/subject/eynpcctx.html