TODO…
升级包 OTA 包 增量包 编译制作过程
to do
pm命令实的实现方式在Pm.java,最后大多数都是调用PackageManagerService相应的方法来完成的。disbale之后,在桌面和应用程序列表里边都看到不该app。
pm
命令 功能 实现方法
list packages 列举app包信息 PMS.getInstalledPackages
install [options]
uninstall [options]
enable <包名或组件名> enable PMS.setEnabledSetting
disable <包名或组件名> disable PMS.setEnabledSetting
hide
unhide
get-install-location 获取安装位置 PMS.getInstallLocation
set-install-location 设置安装位置 PMS.setInstallLocation
path
clear
get-max-users 最大用户数 UserManager.getMaxSupportedUsers
force-dex-opt
dump
trim-caches <目标size> 紧缩cache目标大小 PMS.freeStorageAndNotify
查看所有的package
list packages [options]
其中[options]参数:
-f: 显示包名所关联的文件;
-d: 只显示disabled包名;
-e: 只显示enabled包名;
-s: 只显示系统包名;
-3: 只显示第3方应用的包名;
-i: 包名所相应的installer;
-u: 包含uninstalled包名.
规律: disabled + enabled = 总应用个数; 系统 + 第三方 = 总应用个数。
比如:查看第3方应用:
pm list packages -3
又比如,查看已经被禁用的包名。(国内的厂商一般把google的服务禁用了)
pm list packages -d
当FILTER为不为空时,则只会输出包名带有FILTER字段的应用;当FILTER为空时,则默认显示所有满足条件的应用。
比如,查看包名带google字段的包名
pm list packages google
pm install [options]
其中[options]参数:
-r: 覆盖安装已存在Apk,并保持原有数据;
-d: 运行安装低版本Apk;
-t: 运行安装测试Apk
-i : 指定Apk的安装器;
-s: 安装apk到共享快存储,比如sdcard;
-f: 安装apk到内部系统内存;
-l: 安装过程,持有转发锁
-g: 准许Apk manifest中的所有权限;
该参数是必须的,是指需要安装的apk所在的路径。
pm list users //查看当前手机用户
pm list libraries //查看当前设备所支持的库
pm list features //查看系统所有的features
pm list instrumentation //所有测试包的信息
pm list permission-groups //查看所有的权限组
pm list permissions [options]
-g: 以组形式组织;
-f: 打印所有信息;
-s: 简要信息;
-d: 只列举危险权限;
-u: 只列举用户可见的权限。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags); //打开一个现有的文件
int open(const char *pathname, int flags, mode_t mode); //打开文件不存在,则先创建
【flags】:----------
O_RDONLY, O_WRONLY, or O_RDWR. 这三个之一必备
O_APPEND: The file is opened in append mode.
O_ASYNC: This feature is available only for terminals, pseudoterminals, sockets, pipes and FIFOs
O_CLOEXEC: Enable the close-on-exec flag for the new file descriptor.
了解这个选项需要明白fork后跟随exec和fork后不跟随exec的区别
fork之后若跟随执行exec后,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以先后的进程ID并未改变。exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈段。
也就是说之前的打开的文件描述符fd会被清理掉,导致打开的文件句柄无法释放,所以有了这个选项,在当前进程执行exec族函数时,会先做一个清理工作,close掉当前进程的文件描述符,再载入要执行的程序到当前进程环境。
O_CREAT:-
【mode】: (如果是新建文件,就设置初始访问权限)
S_IRWXU 00700 user (file owner) has read, write and execute permission
S_IRUSR 00400 user has read permission
S_IWUSR 00200 user has write permission
S_IXUSR 00100 user has execute permission
S_IRWXG 00070 group has read, write and execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 others have read, write and execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
多个模式可位或 bitwise-or
O_DIRECT: Try to minimize cache effects of the I/O to and from this file.
O_DIRECTORY: If pathname is not a directory, cause the open to fail.
O_EXCL: 如果同时指定了O_CREAT,而文件已经存在,则导致调用出错
O_LARGEFILE:
O_NOATIME:
O_NOCTTY: 如果pathname指的是终端设备(tty),则不将此设备分配作为此进程的控制终端
O_NOFOLLOW
O_NONBLOCK : When possible, the file is opened in nonblocking mode.
O_PATH:
O_SYNC: The file is opened for synchronous I/O. Any write(2)s on the resulting file descriptor will block
the calling process until the data has been physically written to the underlying hardware.
只在数据被写入外存或者其他设备之后操作才返回
O_TRUNC: If the file already exists and is a regular file and the open mode allows writing
(i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0.
如果文件存在,而且为读写或只写方式打开,则将其长度截断为0
ls -l
drwxr-xr-x. 2 anxier anxier 4096 1月 15 00:29 desktop
第一栏的信息包含10字符。第1个字符,表示文件的类型;第2~4位,代表文件所有者(User)的权限,分别为读、写、执行;第5~7位,代表文件所有者的同组用户(Group)的权限,分别是读、写、执行;第8~10位,代表其他用户(Other)的权限,分别为读、写、执行。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|
-/l/c/s/d/b/p | r/- | w/- | x/- | r/- | w/- | x/- | r/- | w/- | x/- |
- 普通文件
d 目录文件 文本文件和二进制文件。
l 链接文件
b 块设备文件
c 字符设备文件
p 管道文件 用于在进程间传递数据
s 套接口文件
#include <sys/ioctl.h>
int ioctl(int d, int request, ...);
request: ----
TIOCSETD int *ldisc change the line discipline:
TTYDISC termios interactive line discipline
TABLDISC tablet line discipline
SLIPDISC serial IP line discipline
PPPDISC PPP line discipline
TIOCGETD int *ldisc return the current line discipline
TIOCSBRK set the terminal into BREAK condition
TIOCCBRK clear the terminal BREAK condition
TIOCSDTR assert data terminal ready
TIOCCDTR clear data terminal ready
TIOCGPGRP int *tpgrp return the terminal's process group
TIOCSPGRP int *tpgrp associate the terminal's process group
TIOCGETA struct termios *term get the terminal's termios attributes
TIOCSETA struct termios *term set the terminal's termios attributes
TIOCSETAW struct termios *term set the termios attrs after any output completes
TIOCSETAF struct termios *term after any output completes, clear input and set termios attrs
TIOCOUTQ int *num current number of characters in the output queue
TIOCSTI char *cp manually send a character to the terminal
TIOCSTOP stop output (like typing ^S)
TIOCSTART start output (like typing ^Q)
TIOCSCTTY make this the controlling terminal for the process
TIOCDRAIN wait until all output is drained
TIOCEXCL set exclusive use on the terminal
TIOCNXCL clear exclusive use of the terminal
TIOCFLUSH int *what clear input/output if `what' has FREAD/FWRITE set
TIOCGWINSZ struct winsize *ws get the winsize information
TIOCSWINSZ struct winsize *ws set the winsize information
TIOCCONS int *on redirect kernel console messages
TIOCMSET int *state set the modem state bit flags according to the following:
TIOCM_LE Line Enable
TIOCM_DTR Data Terminal Ready
TIOCM_RTS Request To Send
TIOCM_ST Secondary Transmit
TIOCM_SR Secondary Receive
TIOCM_CTS Clear To Send
TIOCM_CAR Carrier Detect
TIOCM_CD Carrier Detect (synonym)
TIOCM_RNG Ring Indication
TIOCM_RI Ring Indication (synonym)
TIOCM_DSR Data Set Ready
TIOCMGET int *state get the modem state bit flags
TIOCMBIS int *state add modem state bit flags, OR-ing in the new states
TIOCMBIC int *state clear modem state bit flags
am命令实的实现方式在Am.java,最终几乎都是调用ActivityManagerService相应的方法来完成的,am monitor除外。比如前面概述中介绍的命令am start -a android.intent.action.VIEW -d http://gityuan.com, 启动Acitivty最终调用的是ActivityManagerService类的startActivityAsUser()方法来完成的。再比如am kill-all命令,最终的实现工作是由ActivityManagerService的killBackgroundProcesses()方法完成的。
am [subcommand] [options]
命令 | 功能 | 实现方法 |
---|---|---|
am start [options] |
启动Activity | startActivityAsUser |
am startservice |
启动Service | startService |
am stopservice |
停止Service | stopService |
am broadcast |
发送广播 | broadcastIntent |
am kill |
杀指定后台进程 | killBackgroundProcesses |
am kill-all | 杀所有后台进程 | killAllBackgroundProcesses |
am force-stop |
强杀进程 | forceStopPackage |
am hang | 系统卡住 | hang |
am restart | 重启 | restart |
am bug-report | 创建bugreport | requestBugReport |
am dumpheap |
进程pid的堆信息输出到file | dumpheap |
am send-trim-memory |
收紧进程的内存 | setProcessMemoryTrimLevel |
am monitor | 监控 | MyActivityController.run |
am start [options]
[options]参数:
am send-trim-memory
用例:
向pid=12345的进程,发出level=RUNNING_LOW的收紧内存命令
am send-trim-memory 12345 RUNNING_LOW
level取值范围为: HIDDEN、RUNNING_MODERATE、BACKGROUND、RUNNING_LOW、MODERATE、RUNNING_CRITICAL、COMPLETE
am的子命令,startservice, stopservice, broadcast, kill, profile start, profile stop, dumpheap的可选参数都允许设置–user <USER_ID>。目前市面上的绝大多数手机还是单用户模式,故可以忽略该参数,默认为当前用户。
例如:启动id=10010的用户的指定service。
am startservice –user 10010
Intent的参数和flags较多,本文为方便起见,分为3种类型参数,常用参数,Extra参数,Flags参数。
am start -a android.intent.action.VIEW
am start -n com.yuanhh.app/.MainActivity
am start -d content://contacts/people/1
am start -t image/png
am start -c android.intent.category.APP_CONTACTS
基本类型
参数 | -e/-es | -esn | -ez | -ei | -el | -ef | -eu | -ecn |
---|---|---|---|---|---|---|---|---|
类型 | String | (String)null | boolean | int | long | float | uri | component |
比如参数es是Extra String首字母简称,实例:
am start -n com.yuanhh.app/.MainActivity -es website gityuan.com
此处-es website gityuan.com,等价于Intent.putExtra(“website”, “gityuan.com”);
数组类型
参数 -esa -eia -ela -efa
数组类型 String[] int[] long[] float[]
比如参数eia,是Extra int array首字母简称,多个value值之间以逗号隔开,实例:
am start -n com.yuanhh.app/.MainActivity -ela weekday 1,2,3,4,5
此处-ela weekday 1,2,3,4,5,等价于Intent.putExtra(“weekday”, new int[]{1,2,3,4,5});
ArrayList类型
参数 -esal -eial -elal -efal
List类型 String int long float
比如参数efal,是Extra float Array List首字母简称,多个value值之间以逗号隔开,实例:
am start -n com.yuanhh.app/.MainActivity -efal nums 1.2,2.2
此处-efal nums 1.2,2.2,等价于先构造ArrayList变量,再通过putExtra放入第二个参数。
在参数类型1中,提到有-f
[–grant-read-uri-permission] [–grant-write-uri-permission]
[–grant-persistable-uri-permission] [–grant-prefix-uri-permission]
[–debug-log-resolution]
[–exclude-stopped-packages] [–include-stopped-packages]
[–activity-brought-to-front] [–activity-clear-top]
[–activity-clear-when-task-reset] [–activity-exclude-from-recents]
[–activity-launched-from-history] [–activity-multiple-task]
[–activity-no-animation] [–activity-no-history]
[–activity-no-user-action] [–activity-previous-is-top]
[–activity-reorder-to-front] [–activity-reset-task-if-needed]
[–activity-single-top] [–activity-clear-task]
[–activity-task-on-home]
[–receiver-registered-only] [–receiver-replace-pending]
例如,发送action=”broadcast.demo”的广播,并且对于forceStopPackage()的应用不允许接收该广播,命令如下:
am broadcast -a broadcast.demo –exclude-stopped-packages
用例:
am start -n com.android.dialer/com.android.dialer.DialtactsActivity
Android 源码目录繁多,本文旨在更详尽做出说明。
.
├── abi
├── art
├── bionic
├── bootable
├── build
├── cts
├── dalvik
├── developers
├── development
├── device
├── docs
├── external
├── frameworks
├── hardware
├── libcore
├── libnativehelper
├── ndk
├── packages
├── pdk
├── prebuilts
├── sdk
├── system
└── tools
待续。。。