在底層代碼中看到這樣一條語句:
system("/system/bin/sh -c \"am broadcast -a android.intent.action.AT_AIRPLANE_MODE --ez state true\"");
system 這是幹什麼的啊??
經google原來system是系統調用,執行一個系統命令。
這裏system加上其參數的意思:
調用system,通過shell,執行可執行程序或者腳本am,
發送broadcast Action爲:android.intent.action.AT_AIRPLANE_MODE 廣播參數--ez 鍵值對 state true……
這樣也可以啊,我原來以爲android底層要主動和上層進行交互,就得通過socket等,原來這樣也可以的,真是學習了。
1 system命令
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed.
During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.
system()函數調用/bin/sh來執行參數指定的命令,/bin/sh 一般是一個軟連接,指向某個具體的shell,比如bash,-c選項是告訴shell從字符串command中讀取命令;
在該command執行期間,SIGCHLD是被阻塞的,好比在說:hi,內核,這會不要給我送SIGCHLD信號,等我忙完再說;
在該command執行期間,SIGINT和SIGQUIT是被忽略的,意思是進程收到這兩個信號後沒有任何動作。
爲了更好的理解system()函數返回值,需要了解其執行過程,實際上system()函數執行了三步操作:
a.fork一個子進程;
b.在子進程中調用exec函數去執行command;
c.在父進程中調用wait去等待子進程結束。
對於fork失敗,system()函數返回-1。
如果exec執行成功,也即command順利執行完畢,則返回command通過exit或return返回的值。
注意,command順利執行不代表執行成功,比如command:"rm debuglog.txt",不管文件存不存在該command都順利執行了
如果exec執行失敗,也即command沒有順利執行,比如被信號中斷,或者command命令根本不存在,system()函數返回127.
如果command爲NULL,則system()函數返回非0值,一般爲1.
具體可參考這篇文章:
http://my.oschina.net/renhc/blog/53580
2 AM
am的代碼實現在\frameworks\base\cmds\am\目錄下:
\frameworks\base\cmds\am\am 這個就是放在system/bin/am:
base=/system
export CLASSPATH=$base/framework/am.jar
exec app_process $base/bin com.android.commands.am.Am "$@"
通過app_process創建執行com.android.commands.am.Am這樣進程 $@傳遞所有參數給Am
\frameworks\base\cmds\am\src
\frameworks\base\cmds\am\Android.mk
將編譯java層Am爲一個am.jar包,下面看一下Am的支持的功能。
public static void main(String[] args) {
try {
(new Am()).run(args);
} catch (IllegalArgumentException e) {
showUsage();
}
}
private void run(String[] args) throws Exception {
……
//獲取ActivityManagerService實例
mAm = ActivityManagerNative.getDefault();
mArgs = args;
String op = args[0];
mNextArg = 1;
//Am所支持的命令
if (op.equals("start")) {
runStart();
} else if (op.equals("startservice")) {
runStartService();
} else if (op.equals("force-stop")) {
runForceStop();
} else if (op.equals("kill")) {
runKill();
} else if (op.equals("kill-all")) {
runKillAll();
} else if (op.equals("instrument")) {
runInstrument();
} else if (op.equals("broadcast")) {
sendBroadcast();
}
…… //很多命令
}
看一下發送廣播的命令:
private void sendBroadcast() throws Exception {
//解析發送廣播的參數
Intent intent = makeIntent(UserHandle.USER_ALL);
IntentReceiver receiver = new IntentReceiver();
//通過AMS發送廣播
mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, true, false,
mUserId);
receiver.waitForFinish();
}
所以Android 還有這樣一個工具am,通過看showUsage,可以幹很多事情的;