Android系统prop属性的研究与分析(二)

Android是如何使用selinux来保护系统属性的 Android是如何使用selinux来保护系统属性的尝试获取Android设备的序列号SerialNo1 Build.SERIAL新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 尝试获取Android设备的序列号Seri 阅读详情

Android System Property

一 System Property

  代码中大量存在:SystemProperties.set()/SystemProperties.get();通过这两个接口可以对系统的属性进行读取/设置,

顾名思义系统属性,肯定对整个系统全局共享。通常程序的执行以进程为单位各自相互独立,如何实现全局共享呢?

System Properties是怎么一回事,又是如何实现的呢?

       属性系统是android的一个重要特性。它作为一个服务运行,管理系统配置和状态。所有这些配置和状态都是属性。

每个属性是一个键值对(key/value pair),其类型都是字符串。

这些属性可能是有些资源的使用状态,进程的执行状态,系统的特有属性……

       可以通过命令adb shell :

    getprop查看手机上所有属性状态值。

       或者 getprop init.svc.bootanim制定查看某个属性状态

       使用setprop init.svc.bootanim start 设置某个属性的状态

特别属性 :

  如果属性名称以“ro.”开头,那么这个属性被视为只读属性。一旦设置,属性值不能改变。

  如果属性名称以“persist.”开头,当设置这个属性时,其值也将写入/data/property。

  如果属性名称以“net.”开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名。

    (这是很巧妙的。 netresolve模块的使用这个属性来追踪在net.*属性上的任何变化。)

  属性“ ctrl.start ”和“ ctrl.stop ”是用来启动和停止服务。每一项服务必须在/init.rc中定义.系统启动时,与init守护

    进程将解析init.rc和启动属性服务。一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务

    名找到该服务,启动该服务。这项服务的启动结果将会放入“ init.svc.<服务名>“属性中。客户端应用程序可以轮询那个属性值,以确定结果。

二 framework访问系统服务流程

  framework通过SystemProperties接口操作系统属性,SystemProperties通过JNI调用访问系统属性。

  \frameworks\base\core\java\android\os\ SystemProperties.java:

public class SystemProperties
{
    //JNI
    private static native String native_get(String key, String def);
    private static native void native_set(String key, String def);

    public static String get(String key, String def) {
        return native_get(key, def);
    }

    public static void set(String key, String val) {
        native_set(key, val);
    }
}

Jni代码位置:

\frameworks\base\core\jni\android_os_SystemProperties.cpp

获取系统属性 阻塞方式:

static jstring SystemProperties_getSS()
{
        len = property_get(key, buf, "");
} 

操作在\bionic\libc\bionic\system_properties.c中:

int __system_property_get(const char *name, char *value)
{
    //数据已经存储在内存中__system_property_area__ 等待读取完返回
    const prop_info *pi = __system_property_find(name);
    return __system_property_read(pi, 0, value);
} 

       进程启动后数据已经将系统属性数据读取到相应的共享内存中,保存在全局变量__system_property_area__;

进程之间都是独立的,系统属性数据是如何读取到当前进程空间中的呢?后续介绍。

设置属性异步socket通信:

int __system_property_set(const char *key, const char *value)
{
      msg.cmd = PROP_MSG_SETPROP;
    strlcpy(msg.name, key, sizeof msg.name);
    strlcpy(msg.value, value, sizeof msg.value);
    err = send_prop_msg(&msg);
}

static int send_prop_msg(prop_msg *msg)
{
    //sokcet 通信 /dev/socket/property_service 
    s = socket(AF_LOCAL, SOCK_STREAM, 0);
    connect(s, (struct sockaddr *) &addr, alen)
    send(s, msg, sizeof(prop_msg), 0)
    close(s);
}

  通过socket向property_service发送消息,property_service运行在哪里呢?

三 Property Service创建服务端socket

init进程启动监听过程中:\system\core\init\Init.c

int main(int argc, char **argv)
{    
    //加入到action queue队列
    queue_builtin_action(property_service_init_action, "property_service_init");
    for(;;)
        //执行action queue队列
        //接收通过socket向property service 发送的数据;
        nr = poll(ufds, fd_count, timeout);
        ……
        handle_property_set_fd();
}

static int property_service_init_action(int nargs, char **args)
{
    start_property_service();

}

\system\core\init\property_service.c:
void start_property_service(void)
{
    //加载属性配置文件
    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
    load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);
    load_persistent_properties();
    
    //创建socket资源 并绑定
    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);
    //监听
    listen(fd, 8);
}

  Property Service 是运行在init守护进程中。

  接收到消息之后干什么,还是要先弄清楚整个Property Service是如何实现的呢,后续介绍。

先看看Property Service接收到消息后的处理。

 

四 Property Service 监听socket处理

Property Service监听socket消息的处理过程:

void handle_property_set_fd()
{
    //等待建立通信
    s = accept(property_set_fd, (struct sockaddr *) &addr, &addr_size)

    //获取套接字相关信息 uid gid
    getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size);
    //接收属性设置请求消息
    recv(s, &msg, sizeof(msg), 0);
    //处理消息    
    switch(msg.cmd) {
    case PROP_MSG_SETPROP:
        //通过设置系统属性  处理ctl.开头消息
        if(memcmp(msg.name,"ctl.",4) == 0) 
        {
            //权限检测
            if (check_control_perms(msg.value, cr.uid, cr.gid)) 
            {
                handle_control_message((char*) msg.name + 4, (char*) msg.value);
            }
        } else 
        {
            //更改系统属性值
            if (check_perms(msg.name, cr.uid, cr.gid)) 
            {
                property_set((char*) msg.name, (char*) msg.value);
            }
        }
    break;
    }
    close(s);
}

通过设置系统属性启动/关闭Service:

权限判断:

static int check_control_perms(const char *name, unsigned int uid, unsigned int gid) 
{
    // system /root用户直接有权限
    if (uid == AID_SYSTEM || uid == AID_ROOT)
        return 1;
    
    //查询用户名单,判断是否存在表中并具有对应权限
    for (i = 0; control_perms[i].service; i++) {
        if (strcmp(control_perms[i].service, name) == 0) {
            if ((uid && control_perms[i].uid == uid) ||
                (gid && control_perms[i].gid == gid)) {
                return 1;
            }
        }
    }
    return 0;
}

 

 所以如果想要应用有权限启动/关闭某Native Service:

  需要具有system/root权限

  找到对应应用uid gid,将应用名称加入到control_perms列表中

 

处理消息 可以通过设置系统属性 改变服务的执行状态 start/stop:

void handle_control_message(const char *msg, const char *arg)
{
    if (!strcmp(msg,"start")) {
        msg_start(arg);
    } else if (!strcmp(msg,"stop")) {
        msg_stop(arg);
    } else if (!strcmp(msg,"restart")) {
        msg_stop(arg);
        msg_start(arg);
    } 
}

static void msg_start(const char *name)
{
    service_start(svc, args);
}
void service_start(struct service *svc, const char *dynamic_args){
    //创建进程启动服务
    pid = fork();
    execve(svc->args[0], (char**) svc->args, (char**) ENV);
    
    //修改服务的系统属性 执行状态
    notify_service_state(svc->name, "running");
}

连着前面就是ctr.start和ctr.stop系统属性:用来启动和停止服务的。

例如:

    // start boot animation

    property_set("ctl.start", "bootanim");

在init.rc中表明服务是否在开机时启动:

service adbd /sbin/adbd
    class core
    disabled //不自动启动

 

启动服务的时候会判断:

static void service_start_if_not_disabled(struct service *svc)
{
        //判断是否启动
        if (!(svc->flags & SVC_DISABLED)) {
            service_start(svc, NULL);
        }
}

修改系统属性值:

static int check_perms(const char *name, unsigned int uid, unsigned int gid)
{
    //进行权限检测
    for (i = 0; property_perms[i].prefix; i++) {
        int tmp;
        if (strncmp(property_perms[i].prefix, name,
                    strlen(property_perms[i].prefix)) == 0) {
            if ((uid && property_perms[i].uid == uid) ||
                (gid && property_perms[i].gid == gid)) {
                return 1;
            }
        }
    }

    return 0;
}

 

看这个修改系统属性权限表:

property_perms[] = {
    { "net.dns",          AID_RADIO,    0 },
    { "net.",             AID_SYSTEM,   0 },
    { "dev.",             AID_SYSTEM,   0 },
    { "runtime.",         AID_SYSTEM,   0 },
    { "sys.",             AID_SYSTEM,   0 },
    { "service.",         AID_SYSTEM,   0 },
    { "persist.sys.",     AID_SYSTEM,   0 },
    { "persist.service.", AID_SYSTEM,   0 },
    ……
     { NULL, 0, 0 }
};

 

  指定了特定的用户有用修改 带有某些前缀的系统属性值。

  到这里基本就是Property对外的基本工作流程,Property Service内部具体如何实现,操作运行,

  跨进程空想内存等问题仍未清楚是如何处理的。

五 属性系统设计

         属性系统的上层架构如下图所示:

     

  Property Service运行在init进程中,开机从属性文件中加载到共享内存中;设置系统属性通过socket与Property Service通信。

  Property Consumer进程将存储系统属性值的共享内存,加载到当前进程虚拟空间中,实现对系统属性值的读取。

  Property Setter进程修改系统属性,通过socket向Property Service发送消息,更改系统属性值。

六 属性系统实现

       属性系统设计的关键就是:跨进程共享内存的实现。

下面将看看属性系统实现具体过程:

Init进程执行:

int main(int argc, char **argv){
    //将属性系统初始化函数加入action queue
  queue_builtin_action(property_init_action, "property_init");
  for(;;)
}

static int property_init_action(int nargs, char **args)
{
    property_init(load_defaults);
}

初始化Property Service:

       \system\core\init\property_service.c

void property_init(bool load_defaults)
{
    //初始化共享内存空间
    init_property_area();
    //加载属性文件
  load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT);
}

初始化共享内存空间:

static int init_property_area(void)
{    
    //创建匿名内存空间PA_SIZE = 32768
    init_workspace(&pa_workspace, PA_SIZE)
    //将内存区域分成两部分:属性系统基本信息和属性键值对
    pa_info_array = (void*) (((char*) pa_workspace.data) + PA_INFO_START);
    
    //初始化属性系统信息
    pa = pa_workspace.data;
    memset(pa, 0, PA_SIZE);
    pa->magic = PROP_AREA_MAGIC;
    pa->version = PROP_AREA_VERSION;

    /* plug into the lib property services */
    __system_property_area__ = pa;
}

__system_property_area__:

  每个进程都会使用此变量,指向系统属性共享内存区域,访问系统属性,很重要。

位于:\bionic\libc\bionic\system_properties.c中,属于bionic库。后面将介绍各进程如何加载共享内存。

将文件作为共享内存映射到进程空间内存使用:

static int init_workspace(workspace *w, size_t size)
{
    //dev is a tmpfs是一种虚拟内存文件系统
    int fd = open("/dev/__properties__", O_RDWR | O_CREAT, 0600);
    //将文件映射为共享进程空间内存 使其可以与操作内存方式一致
    void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, 
      MAP_SHARED, fd, 0);
    close(fd);
    
    //删除文件
    fd = open("/dev/__properties__", O_RDONLY);
    unlink("/dev/__properties__");
    //保存fd size 将作为环境变量传递给每个进程
     w->data = data; w->size = size; w->fd = fd;
}

加载系统属性默认数据文件:

#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
static void load_properties_from_file(const char *fn)
{
    //读取系统属性键值对数据写入到共享内存中
    data = read_file(fn, &sz);
    load_properties(data);
} 

  加上上面所述:Property Service Socket资源的创建,来监听socket通信连接设置系统属性,

  在Init进程中Property Service完成了初始化。

将得到该内存区域数据结构:

     

七 进程共享系统属性内存空间实现

  Property Service运行于init进程中,将文件映射为创建一块共享内存空间,但在整个系统中,

其他进程也能够读取这块内存映射到当前进程空间中,是如何实现的呢?

Service进程启动:将共享内存空间fd size作为环境变量传递给新创建进程

void service_start(struct service *svc, const char *dynamic_args)
{
    //创建进程
    pid = fork();

    if (pid == 0) {
        if (properties_inited()) {
            //获取系统属性空间文件描述
            get_property_workspace(&fd, &sz);
            //dup最小的可用文件描述符
            sprintf(tmp, "%d,%d", dup(fd), sz);
            //加入ANDROID_PROPERTY_WORKSPACE环境变量到ENV 
        //包含共享内存fd
            add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);
        }
        //执行程序 传递环境变量ENV
        execve(svc->args[0], (char**) svc->args, (char**) ENV)
        //设置Service系统属性
        notify_service_state(svc->name, "running");
    }
}

void get_property_workspace(int *fd, int *sz)
{
   *fd = pa_workspace.fd;
   *sz = pa_workspace.size;
}

共享内存空间fd size作为环境变量传递给新创建进程后,将在何处使用呢?

将系统属性内存空间映射到当前进程虚拟空间:

进程在启动时,会加载动态库bionic libc库:

  \bionic\libc\bionic\libc_init_dynamic.c中:

  void __attribute__((constructor)) __libc_preinit(void);          

根据GCC的constructor/destructor属性:

    给一个函数赋予constructor或destructor,其中constructor在main开始运行之前被调用,

  destructor在main函数结束后被调用。如果有多个constructor或destructor,可以给每个constructor

  或destructor赋予优先级,对于constructor,优先级数值越小,运行越早。destructor则相反。

多个constructor需要加优先级:

__attribute__((constructor(1))) void func1()  
{  
    printf("in constructor of foo\n");  
}  
__attribute__((constructor(2))) void func2()  
{  
    printf("in constructor of foo1\n");  
} 
__attribute__((destructor)) void bar()  
{  
    printf("in constructor of bar\n");  
}

 

__libc_preinit在bionic libc库加载的时候会被调用:

void __libc_preinit(void)
{   
    __libc_init_common(elfdata);
}

void __libc_init_common(uintptr_t *elfdata)
{
    __system_properties_init();
}

int __system_properties_init(void)
{
    prop_area *pa;    int s, fd;        unsigned sz;        char *env;
    //获取环境变量ANDROID_PROPERTY_WORKSPACE 
  //与上面init进程中设置对应
    env = getenv("ANDROID_PROPERTY_WORKSPACE");
    //共享内存文件描述符 内存大小
    fd = atoi(env);
    sz = atoi(env + 1);
    //将文件描述符映射到当前进程虚拟空间内存,实现共享内存
    pa = mmap(0, sz, PROT_READ, MAP_SHARED, fd, 0);
    //全局变量指向共享系统属性内存首地址
    __system_property_area__ = pa;
}

  这就是整个System Property的访问交互和实现过程,具体请参考源码。

参考文档:

  http://blog.chinaunix.net/uid-20459533-id-3168973.html

  http://www.cnblogs.com/simonshi/archive/2010/04/08/1707516.html

  http://blog.youkuaiyun.com/zhangchiytu/article/details/7539101

 

 

Android属性之build.prop生成过程:

  http://www.cnblogs.com/bastard/archive/2013/02/28/2937014.html


转自:http://www.cnblogs.com/bastard/archive/2012/10/11/2720314.html


安卓逆向调试:基于Magisk修改ro.debuggable属性的两种实战方法 在安卓系统开发与安全研究中,系统属性是控制设备行为的关键配置项。其中,ro.debuggable属性作为系统调试模式的总开关,其原理在于控制底层内核与运行时环境对调试接口的暴露程度。开启此属性具有重要的技术价值,它允许安全研究人员和开发者进行进程注入、动态分析和内存取证等高级操作,是应用行为分析、漏洞挖掘和系统机制研究的基石。在实际应用场景中,这常见于移动应用安全评估、恶意软件分析和系统级功能开发。本文聚焦于在已获取root权限的设备上,通过Magisk框架实现属性修改,具体介绍了利用resetprop命令 阅读详情

相关推荐

安卓模拟器检测原理与伪装实战:从Build属性到API Hook

在安卓应用开发、自动化测试与兼容性调试中,识别和规避模拟器检测是常遇到的工程问题。应用通常通过系统属性如Build类、CPU指令集、OpenGL渲染器、传感器列表等静态特征,以及TelephonyManager、SensorManager等动态API调用来判断运行环境。理解这些检测逻辑的底层原理,有助于开发者针对性地调整模拟器配置与系统行为。硬件层面可修改build.prop中的机型、硬件平台、ABI等字段,并对传感器、电量、渲染器等特征进行对齐;动态检测则需借助Xposed或Frida等Hook框架,在A

weixin_33965305的博客 408

Android 系统属性SystemProperty分析

Android System Property 一 System Property   代码中大量存在:SystemProperties.set()/SystemProperties.get();通过这两个接口可以对系统的属性进行读取/设置, 顾名思义系统属性,肯定对整个系统全局共享。通常程序的执行以进程为单位各自相互独立,如何实现全局共享呢? System Properties是怎么一回...

weixin_33845881的博客 971

安卓逆向与固件分析实战:从黑盒到白盒的系统化指南

在嵌入式系统与移动安全领域,固件分析是理解设备底层工作原理的核心技术。其基本原理是通过提取、解析和修改设备固件,将厂商封装的“黑盒”系统转化为可被深入分析的“白盒”。这项技术的核心价值在于,它不仅是安全研究员进行漏洞挖掘和渗透测试的必备技能,也是嵌入式开发者进行定制开发、功能扩展和性能优化的基础。在实际应用场景中,固件分析广泛应用于智能设备安全评估、物联网设备研究、安卓系统定制以及硬件功能逆向等方向。本文聚焦于使用Kalitools工具集进行安卓逆向与固件分析,详细介绍了从固件提取、镜像解包到二进制逆向的完

weixin_33672400的博客 373

Android系统下使用c语言获取相关系统信息

首先教你如何在pc机上使用命令形式查看Android系统设备的相关信息 1.使用数据线连接Android系统设备 2.开始调试模式 3.打开pc机的命令行工具,例如windows的cmd 4.找到你Android SDK所在的目录下的adb工具,一般存放在SDK根目录的platform-tools文件夹下 5.我们使用Android sdk中的adb.exe查看相关Andro...

sailleed的知识存储库 2724

Android系统中prop详解

Android 中很多时候会用到prop的操作,这样的话在系统操作的时候可能会更方便一点。这篇文章就是关于prop的详细使用,以后一定会慢慢补充。 主要分两部分: 1. SystemProperties 类 2. 终端prop命令   首先来看一下SystemProperties类的source code。   package android.os; import java.u

私房菜 1万+

Android 10.0 动态修改ro开头系统属性的值

在10.0 定制化产品开发时,在10.0的产品中为了产品的安全性,ro开头属性值是不能修改的,由于项目需要变成可以修改它的值, 所以这就要从System的开机init.rc中来分析来实现这个功能 android10.0它是在开机的时候从build.prop中读取的属性值 由property_service.cpp来负责系统属性的修改,下面从property_service.cpp来分析相关代码 来看如何实现功能 3.2 动态修改ro开头系统属性的值的功能实现......

安卓兼职framework和app工程师的博客 1993

Android系统注册表(prop属性)的研究与分析

在程序开发的时候,往往会共享一些数据信息,有一个环境变量或者属性下面几种情况:         1.该变量在多处需要使用,并且是跨进程或者跨线程的。          2.该环境变量一般只需读取一次,不需要频繁保存。          3.同时这个变量信息在关机重启后任然可以保存。 对于这些需求,通常的做法是将这些信息保存到一个文件中,通过对该文件的读写来提取和保存信息,这些信息的数据量都

taoxugang2012的专栏 5374

异步复位同步释放:如何确保复位信号的可靠性与时序安全

本文深入探讨了异步复位同步释放技术在数字电路设计中的关键作用,详细分析了复位信号的可靠性与时序安全问题。通过对比异步复位与同步复位的本质区别,揭示异步复位的优势与潜在风险,并提供了标准的Verilog实现方案。文章还涵盖了多时钟域下的复位同步策略、复位网络时序约束方法以及实际工程中的经验教训,为数字系统设计者提供了全面的复位信号处理指南。

weixin_29213655的博客 400

Android系统prop属性的研究与分析(一)

在程序开发的时候,往往会共享一些数据信息,有一个环境变量或者属性下面几种情况: 1.该变量在多处需要使用,并且是跨进程或者跨线程的。 2.该环境变量一般只需读取一次,不需要频繁保存。 3.同时这个变量信息在关机重启后任然可以保存。 对于这些需求,通常的做法是将这些信息保存到一个文件中,通过对该文件的读写来提取和保存信息,这些信息的数据量都比较小。这种方法是可以的,但是不是很系统完善,而且当

编程菜鸟进阶之路 4843

Linux下基于AHCI controller模块实现SATA Platform驱动附代码详细流程

本文主要是针对ARM A55集成了AHSATA controller模块开发sata驱动,通过Platform的形式在linux识别到SSD,本文详细讲述整个开发过程,同时对SATA Platform驱动进行讲解。1、配置SATA Phy的初始化;2、打开SATA Platform相关编译开关;3、配置设备树;4、linux启动识盘。

Luckiers的博客 2497

STM32 移植FreeModbus详细过程

modbus是一个非常好的串口协议(当然也能用在网口上),它简洁、规范、强大。可以满足大部分的工业、嵌入式需求。 这里详细说下如何将freemodbus移植到stm32平台。我之前下载的版本是1.6,我会在我的下载链接里面加上1.6的freemodbus压缩包以及我已经移植好的stm32 for freemodbus版本。我上传的移植好的绝对没问题,经过多个板子测试。这里编译器使用的是keil5.28,单片机用的是STM32F103RCT6。 移植到VET6以及ZET6的话只需要改一下选择的芯片就好,改法:

qq_40305944的博客 8万+

Android 蓝牙默认名称设置分析总结

Android蓝牙默认名称设置分析总结 本文分析了Android系统中蓝牙默认名称的设置方法,基于Android 13源码。研究发现蓝牙名称与ro.product.model属性相关,而非常见的def_bluetooth_name或Settings属性。文章提供了四种设置方法: 修改ro.product.model属性值(需在build.prop或.mk文件中配置) 使用Settings.Secure.bluetooth_name记录蓝牙名称(仅用于查询) 应用层通过BluetoothAdapter.set

wenzhi的博客 2487

安装破解IAR EWARM 8.2,提供注册机

IAR Embedded Workbench for ARM(IAR for ARM)是一款微处理器的集成开发环境软件,该集成开发环境中包含了IAR的C/C++编译器、 汇编工具、链接器、库管理器、文本编辑器、工程管理器和C-SPY调试器,支持ARM,AVR,MSP430等芯片。   一、安装 双击运行安装程序,点击Install IAR Embedded Workbench for ARM...

睿思派克 4万+

Android系统属性SystemProperties分析

Android SystemProperties简介 Systemproperties类在android.os下,但这个类是隐藏的,上层程序开发无法直接使用。其实用java的反射机制是可以使用这个类。何谓java反射机制,请自行研究学习,在此不做介绍,放到后续文章中。用JNI 的方式,可以绕过Systemproperties这个类,直接本地调用来实现创建、获取及修改系统属

JESSE_ZHAO_503的专栏 2420

5分钟搞定Google Custom Search API申请:从注册到获取CX Key全流程

本文详细介绍了如何快速申请和配置Google Custom Search API,从Google Cloud项目创建、启用计费、获取API Key,到在Programmable Search Engine控制台创建自定义搜索引擎并获取关键的CX Key,提供了全流程实战指南。文章还包含安全配置建议、API调用测试方法及前端与后端的集成代码示例,帮助开发者高效实现网站或应用的智能搜索功能。

weixin_29227585的博客 1673

工程师必收藏,Juniper(Junos)网络设备命令大全

不要直接删除配置 → 使用deactivate配置前先修改大配置用出现风险命令一律用写自动化时一律用格式真正会用 Juniper 的工程师,不是命令多,而是命令用得精。

网络技术联盟站 404

Android SystemProperties设置/取得系统属性的用法总结

1.Android SystemProperties简介 介绍了设置属性需要的权限,已经设置权限的方法。 Systemproperties类在android.os下,但这个类是隐藏的,上层程序开发无法直接使用。其实用Java的反射机制是可以使用这个类。何谓java反射机制,请自行研究学习,在此不做介绍,放到后续文章中。用JNI的方式,可以绕过Systemproperties这个类,直接

u014386544的博客 3037

华为OD机试 - 物流仓储多维度成本利润综合查询系统 - 二维数组(Python/JS/C/C++ 新系统 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。某物流企业在全国多个仓库开展仓储业务,需要对不同仓库、不同时段的入库成本、出库收入和库存损耗进行综合统计分析,用于生成 日报、周报和月报。字段说明及取值范围如下:warehouses: int[] 扁平化数组 [w0d0in, w0d0out,

学Java,找哪吒 309

[转载]Android SystemProperties设置/取得系统属性的用法总结

https://www.cnblogs.com/senior-engineer/p/4972848.html 通过调查得知,Android系统中取得/设置系统属性的用法参考以下3篇文章就足够了。   1.Android SystemProperties简介 介绍了设置属性需要的权限,已经设置权限的方法。   Systemproperties类在android.os...

刚刚好的博客 935

手把手教你学Simulink——基于Simulink的PR(比例谐振)控制器在单相整流中的应用

本文详细介绍了基于Simulink的PR(比例谐振)控制器在单相整流系统中的应用。通过与传统PI控制器的对比,阐述了PR控制器在交流信号跟踪中的优势:可实现50Hz正弦电流的无静差跟踪,THD低于2%,功率因数接近1。文章从PR控制器原理出发,提供了Simulink建模的具体步骤,包括主电路搭建、电压外环设计、PR控制器实现方法(推荐MATLAB Function方式)以及SPWM调制。通过仿真验证了PR控制在稳态和负载突变情况下的优越性能,并探讨了工程实践中的电网频率自适应、多谐振PR等关键技术。该教程为

MHD0815的博客 123

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

无法调用android.os.SystemProperties.set方法设置系统属性的问题研究

com.test.testservice 无法调用android.os.SystemProperties.set方法的问题研究 error log: E AndroidRuntime: java.lang.RuntimeException: Unable to create service com.test.testservice.testService: java.lang.RuntimeEx...

sinat_37343534的博客 4780

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

default.prop、build.prop、local.prop哪个优先级高?

在android系统中会有各种prop,那么他们初始化顺序优先级如何呢?

键盘的起始页 1318

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

android Android SystemProperties设置/取得系统属性的用法总结

android  Android SystemProperties设置/取得系统属性的用法总结   通过调查得知,Android系统中取得/设置系统属性的用法参考以下3篇文章就足够了。 1.Android SystemProperties简介 介绍了设置属性需要的权限,已经设置权限的方法。   Systemproperties类在an

IT杂谈 2322
上一篇: Android系统prop属性的研究与分析(一)
下一篇: SELinux策略语言--类型强制(编写TE规则)
沉默的过客
博客等级 码龄13年 60粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值