解析android framework下利用app_process来调用java写的命令及示例

简介: 解析android framework下利用app_process来调用java写的命令及示例          在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是build出一个bin文件...

解析android framework下利用app_process来调用java写的命令及示例

 

       在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是build出一个bin文件,再存放到/system/bin目录下,对于C/CPP写的命令,我们还是比较好理解的,都有一个main函数作为入口,但是在cmds目录下还有一些原生代码是java的,比如input、settings,那么这种类型的命令是怎么实现的呢?

      笔者研习了原生的命令实现,写了一个demo,抛砖引玉吧!暂时叫strong吧!我们都知道java写的文件最后都是编译成了class文件,java类里面也有很多接口,在android平台上cmds目录下的各模块的java文件都实现了一个共同的方法,还是叫main(),真是情有独钟啊!当然从技术角度看叫其他名字也是可以的。那我们就简单实现以下这个class吧!如下:

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.commands.strong;

import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.IActivityManager.ContentProviderHolder;
import android.content.IContentProvider;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;

public final class strongcmd {
    static final String TAG = "strong";

    static String[] mArgs;
    int mNextArg;
    static int value = 0;

    public static void main(String[] args) {
    int c;
    
    printUsage();
    System.err.println("Wellcom strong test function!!");               

        try {
           new strongcmd().run();
        } catch (Exception e) {
            System.err.println("Unable to run settings command");
        }
    }

    public void run() {

        try {
           System.err.println("Now strong run() again");
        } catch (Exception e) {
           System.err.println("Now strong run() Exception");        	
        }

    }

    private String nextArg() {
        if (mNextArg >= mArgs.length) {
            return null;
        }
        String arg = mArgs[mNextArg];
        mNextArg++;
        return arg;
    }
    
    private static void printUsage() {
        System.err.println("usage:  strong -a -b -h");
        System.err.println("'a' is for add");
        System.err.println("-h for help");
    }
}

/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/edsam49原创,转载请注明出处,谢谢!
/*****************************************************************************************************/

  写好Android.mk,编译好这个文件,会生成strong.jar包,包含这个class。那么,又怎么跟命令挂钩呢?先看看Android.mk,如下:

# Copyright 2011 The Android Open Source Project
#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := strong
LOCAL_MODULE_TAGS := optional
include $(BUILD_JAVA_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := strong
LOCAL_SRC_FILES := pre_strong
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)

  上一部分是BUILD_JAVA_LIBRARY,关键在下面,利用的是BUILD_PREBUILT,添加一个预编译好的应用程序,我们叫pre_strong,它有可执行的权限,看看它的具体实现吧!

# Script to start "strong" on the device
#
base=/system
export CLASSPATH=$base/framework/strong.jar
exec app_process $base/bin com.android.commands.strong.strongcmd "$@"

   首先还是设置好这个java lib的路径,如何再调用app_process来执行,主要是把这个类名要给对,app_process其实也是个命令。在app_process里面,还是一样利用JNI技术,在java ENV里面查找传给app_process的class,找到这个class后再去找main函数接口的field,然后再call这个main接口,这样就call到java里面去了。

     下面简要看看app_process的关键代码吧!

    virtual void onVmCreated(JNIEnv* env)
    {
        if (mClassName == NULL) {
            return; // Zygote. Nothing to do here.
        }

        /*
         * This is a little awkward because the JNI FindClass call uses the
         * class loader associated with the native method we're executing in.
         * If called in onStarted (from RuntimeInit.finishInit because we're
         * launching "am", for example), FindClass would see that we're calling
         * from a boot class' native method, and so wouldn't look for the class
         * we're trying to look up in CLASSPATH. Unfortunately it needs to,
         * because the "am" classes are not boot classes.
         *
         * The easiest fix is to call FindClass here, early on before we start
         * executing boot class Java code and thereby deny ourselves access to
         * non-boot classes.
         */
        char* slashClassName = toSlashClassName(mClassName);
        mClass = env->FindClass(slashClassName);
        if (mClass == NULL) {
            ALOGE("ERROR: could not find class '%s'\n", mClassName);
        }
        free(slashClassName);

        mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
    }

    virtual void onStarted()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();

        AndroidRuntime* ar = AndroidRuntime::getRuntime();
        ar->callMain(mClassName, mClass, mArgC, mArgV);

        IPCThreadState::self()->stopProcess();
    }

if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    }

     Android平台提供的app_process,还是相当不错的,比较实用,利用好app_process还是可以写成很多供我们自己开发、测试、定制一些特殊的程序,给开发带来了很大的便利。

 

目录
相关文章
|
9天前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
87 2
|
12天前
|
Java
怎么用Java 代码示例来展示继承的实现
本文通过Java代码示例展示继承机制:Animal为父类,Cat和Dog继承其属性与方法,并实现构造函数调用、方法重写与特有功能扩展,体现代码复用与多态特性。
51 4
|
13天前
|
Java
java入门代码示例
本文介绍Java入门基础,包含Hello World、变量类型、条件判断、循环及方法定义等核心语法示例,帮助初学者快速掌握Java编程基本结构与逻辑。
190 0
Java API 开发者
43 0
|
2月前
|
存储 Java PHP
轻量化短视频电商直播带货APP源码全解析:核心功能与设计流程​
在电商直播热潮下,开发专属直播带货APP成为抢占市场关键。本文详解原生开发轻量化APP的核心功能与全流程设计,涵盖用户登录、商品浏览、直播互动、购物车、订单及售后功能,并介绍安卓端Java、苹果端Object-C、后台PHP的技术实现,助力打造高效优质的直播电商平台。
|
3月前
|
安全 Java 网络安全
Java 实现 SMTP 协议调用的详细示例及实战指南 SMTP Java 调用示例
本文介绍了如何使用Java调用SMTP协议发送邮件,涵盖SMTP基本概念、JavaMail API配置、代码实现及注意事项,适合Java开发者快速掌握邮件发送功能集成。
245 0
|
3月前
|
算法 搜索推荐 Java
Java中的Collections.shuffle()方法及示例
`Collections.shuffle()` 是 Java 中用于随机打乱列表顺序的方法,基于 Fisher-Yates 算法实现,支持原地修改。可选传入自定义 `Random` 对象以实现结果可重复,适用于抽奖、游戏、随机抽样等场景。
128 0
|
3月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
202 4
|
7月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
191 4
|
7月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章

推荐镜像

更多