編輯:關於Android編程
如借用其它人員研究的wifi層次,對比android 下載後的源碼。可看到android一層一層的架構層次是怎麼樣的。
並了解一個android系統是怎麼跑起來的。
所以平時我的的android開發大部分是在java應用層,一些深層次點的就是ndk編碼,會通過進行ndk編碼。如proxydroid.
他的代理功能其實就是用到了ndk,通過jndi接口,調用到一個c++層,然後c++層次可以用到一些c++的類庫,會fork一個後台進程
去進行iptable的代理。
如執行下述命令
iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:8123
會用過jndi調用 c++的
android_os_Exec_createSubProcess方法
最後調用 create_subprocess方法
static int create_subprocess(const int rdt, const char *cmd, char *const argv[],
char *const envp[], const char* scripts, int* pProcessId)
{
pid_t pid;
int pfds[2];
int pfds2[2];
pipe(pfds);
if (rdt) {
pipe(pfds2);
}
pid = fork();
if(pid < 0) {
LOGE("- fork failed: %s -\n", strerror(errno));
return -1;
}
if(pid == 0){
signal(SIGPIPE, SIG_IGN);
if (envp) {
for (; *envp; ++envp) {
putenv(*envp);
}
}
dup2(pfds[0], 0);
close(pfds[1]);
if (rdt) {
close(1);
close(2);
dup2(pfds2[1], 1);
dup2(pfds2[1], 2);
close(pfds2[0]);
}
execv(cmd, argv);
fflush(NULL);
exit(0);
} else {
signal(SIGPIPE, SIG_IGN);
*pProcessId = (int) pid;
dup2(pfds[1], 1);
close(pfds[0]);
write(pfds[1], scripts, strlen(scripts)+1);
if (rdt) {
close(pfds2[1]);
return pfds2[0];
} else {
return -1;
}
}
}
Wifi System:
Java應用層
Java Framework層
JNI層
適配器層
wpa_supplicant程序
Kernel層
Java應用層
-- Settings, WifiSwitcher等應用
--> /system/app
Java Framework層
-- frameworks/base/wifi/java/android/net/wifi/* (android.net.wifi)
-- frameworks/base/services/java/com/android/server/WifiService.java
frameworks/base/services/java/com/android/server/WifiWatchdogService.java
--> /system/framework/framework.jar
/system/framework/services.jar
JNI層
-- frameworks/base/core/jni/android_net_wifi_Wifi.cpp
--> /system/lib/libandroid_runtime.so
適配器層
-- hardware/libhardware_legacy/wifi/wifi.c
--> /system/lib/libhardware_legacy.so
wpa_supplicant程序
-- external/wpa_supplicant
-- external/wpa_supplicant_6
--> /system/bin/wpa_supplicant
/system/lib/libwpa_client.so
Kernel層
-- kernel wifi driver
Enable Wifi 的過程:
Settings/WifiEnabler.java
mWifiManager.setWifiEnabled(enable);
-->
frameworks/base/wifi/java/android/net/wifi/WifiManager.java
public boolean setWifiEnabled(boolean enabled) {
mService.setWifiEnabled(enabled);
}
-->
frameworks/base/services/java/com/android/server/WifiService.java
public boolean setWifiEnabled(boolean enable) {
sendEnableMessage(enable, true, Binder.getCallingUid());
}
->
setWifiEnabledBlocking() {
if (enable) {
mWifiStateTracker.loadDriver();
mWifiStateTracker.startSupplicant();
} else {
mWifiStateTracker.stopSupplicant();
mWifiStateTracker.unloadDriver();
}
}
-->
frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
public synchronized boolean loadDriver() {
return WifiNative.loadDriver();
}
public synchronized boolean startSupplicant() {
return WifiNative.startSupplicant();
}
-->
frameworks/base/wifi/java/android/net/wifi/WifiNative.java
public native static boolean loadDriver();
public native static boolean startSupplicant();
-->
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz)
{
return (jboolean)(::wifi_load_driver() == 0);
}
static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
{
return (jboolean)(::wifi_start_supplicant() == 0);
}
-->
hardware/libhardware_legacy/wifi/wifi.c
int wifi_load_driver(){
//for build in driver, do nothing
//for .ko driver, insmod/load firmware...
}
int wifi_start_supplicant(){
property_set("ctl.start", "wpa_supplicant");
}
-->
/init.rc
service wpa_supplicant /system/bin/wpa_supplicant ...
UITextView與UITextField功能類似,也是字符輸入的視圖控件。區別在於:1、UITextView是多行字符輸入,可通過回車鍵進行換行輸入2、也可以設置固定
集合類洩漏集合類如果僅僅有添加元素的方法,而沒有相應的刪除機制,導致內存被占用。如果這個集合類是全局性的變量 (比如類中的靜態屬性,全局性的 map 等即有靜態引用或 f
本文實例講述了Android編程之客戶端通過socket與服務器通信的方法。分享給大家供大家參考,具體如下:下面是一個demo,Android客戶端通過socket與服務
Google提出了全新的設計規范Material Design,扁平化的設計,加上明亮的色彩,有一種美不勝收的感覺。Material Design翻譯過來叫做&ldquo