Android教程之开机流程全面解析
本文详细讲述了android的开机流程。分享给大家供大家参考,具体如下:
开机过程中无线模块的初始化过程;如果sim卡锁开启,或者pin被锁住的时候,会要求输入pin或者puk,但是这个解锁动作必须在系统初始化完成以后才能进行。(图形系统都还没有初始化怎么输入密码阿?)当系统初始化完成以后会调用 wm.systemready()来通知大家。这时候该做什么就做什么。
开机过程中无线模块的初始化过程:
rild 调用参考实现 reference-ril.c (hardware\ril\reference-ril) 中的函数:
const ril_radiofunctions *ril_init(const struct ril_env *env, int argc, char **argv) ret = pthread_create(&s_tid_mainloop, &attr, mainloop, null); static void *mainloop(void *param) ret = at_open(fd, onunsolicited); ril_requesttimedcallback(initializecallback, null, &timeval_0);
在 initializecallback 函数中对猫进行了初始化。
static void initializecallback(void *param) { atresponse *p_response = null; int err; setradiostate (radio_state_off); at_handshake(); /* note: we don't check errors here. everything important will be handled in onattimeout and onatreaderclosed */ /* atchannel is tolerant of echo but it must */ /* have verbose result codes */ at_send_command("ate0q0v1", null); /* no auto-answer */ at_send_command("ats0=0", null); /* extended errors */ at_send_command("at+cmee=1", null); /* network registration events */ err = at_send_command("at+creg=2", &p_response); /* some handsets -- in tethered mode -- don't support creg=2 */ if (err < 0 || p_response->success == 0) { at_send_command("at+creg=1", null); } at_response_free(p_response); /* gprs registration events */ at_send_command("at+cgreg=1", null); /* call waiting notifications */ at_send_command("at+ccwa=1", null); /* alternating voice/data off */ at_send_command("at+cmod=0", null); /* not muted */ at_send_command("at+cmut=0", null); /* +cssu unsolicited supp service notifications */ at_send_command("at+cssn=0,1", null); /* no connected line identification */ at_send_command("at+colp=0", null); /* hex character set */ at_send_command("at+cscs=\"hex\"", null); /* ussd unsolicited */ at_send_command("at+cusd=1", null); /* enable +cgev gprs event notifications, but don't buffer */ at_send_command("at+cgerep=1,0", null); /* sms pdu mode */ at_send_command("at+cmgf=0", null); #ifdef use_ti_commands at_send_command("at%cpi=3", null); /* ti specific -- notifications when sms is ready (currently ignored) */ at_send_command("at%cstat=1", null); #endif /* use_ti_commands */ /* assume radio is off on error */ if (isradioon() > 0) { setradiostate (radio_state_sim_not_ready); } }
默认状况下假设射频模块是好的,
通过 setradiostate (radio_state_sim_not_ready) 来触发对无线模块的初始化。
通过 static void onradiopoweron() 对无线模块初始化。
首先通过 pollsimstate(null); 轮询 sim卡状态 。
static void pollsimstate (void *param) { atresponse *p_response; int ret; if (sstate != radio_state_sim_not_ready) { // no longer valid to poll return; } switch(getsimstatus()) { case ril_sim_absent: case ril_sim_pin: case ril_sim_puk: case ril_sim_network_personalization: default: setradiostate(radio_state_sim_locked_or_absent); return; case ril_sim_not_ready: ril_requesttimedcallback (pollsimstate, null, &timeval_simpoll); return; case ril_sim_ready: setradiostate(radio_state_sim_ready); return; } }
读取sim卡状态的函数是:getsimstatus()
err = at_send_command_singleline("at+cpin?", "+cpin:", &p_response);
它向猫发送了at命令 at+cpin? 来查询无线模块的状态,如果无线模块还没有就绪,那么他隔1秒钟继续调用
sim卡状态轮询函数 pollsimstate,直到获得sim卡状态。
当sim卡状态为就绪,那么通过 setradiostate(radio_state_sim_ready) 设置变量 sstate 为:
radio_state_sim_ready,这时候会调用函数 static void onsimready()来进一步初始化无线模块。
发送的at命令有:
at_send_command_singleline("at+csms=1", "+csms:", null); at_send_command("at+cnmi=1,2,2,1,1", null);
如果sim卡锁开启,或者pin被锁住的时候,会要求输入pin或者puk,但是这个解锁动作必须在系统初始化完成以后才能进行。(图形系统都还没有初始化怎么输入密码阿?)当系统初始化完成以后会调用 wm.systemready()来通知大家。这时候该做什么就做什么。
wm.systemready()的调用会触发解锁界面。具体流程如下:
因为有: windowmanagerservice wm = null;
所以 wm.systemready()
调用的是 windowmanagerservice 中的函数:
public void systemready() { mpolicy.systemready(); }
windowmanagerservice 中有:
policymanager.makenewwindowmanager 调用的是文件 policymanager.java 中的函数:
public static windowmanagerpolicy makenewwindowmanager() { return spolicy.makenewwindowmanager(); }
spolicy.makenewwindowmanager 调用的是文件 policy.java 中的函数:
public phonewindowmanager makenewwindowmanager() { return new phonewindowmanager(); }
因为 phonewindowmanager 继承自 windowmanagerpolicy
所以 mpolicy.systemready() 最终调用的是文件 phonewindowmanager.java 中的函数:
public void systemready() mkeyguardmediator.onsystemready(); dokeyguard(); showlocked(); message msg = mhandler.obtainmessage(show); mhandler.sendmessage(msg);
发送 show 的消息。
文件 keyguardviewmediator.java 中的消息处理函数:
public void handlemessage(message msg) 对 show 消息进行了处理。
如果 msg.what 等于 show 那么执行:
handleshow(); private void handleshow() ... mcallback.onkeyguardshow(); mkeyguardviewmanager.show(); mshowing = true;
mkeyguardviewmanager.show() 调用的是文件 keyguardviewmanager.java 中的函数:
public synchronized void show() ... mkeyguardview = mkeyguardviewproperties.createkeyguardview(mcontext, mupdatemonitor, this); ...
mkeyguardviewproperties.createkeyguardview 调用的是文件 lockpatternkeyguardviewproperties.java中的函数:
public keyguardviewbase createkeyguardview(context context, keyguardupdatemonitor updatemonitor, keyguardwindowcontroller controller) { return new lockpatternkeyguardview(context, updatemonitor, mlockpatternutils, controller); }
new lockpatternkeyguardview 调用了类 lockpatternkeyguardview 的构造函数:
public lockpatternkeyguardview( context context, keyguardupdatemonitor updatemonitor, lockpatternutils lockpatternutils, keyguardwindowcontroller controller) ... mlockscreen = createlockscreen(); addview(mlockscreen); final unlockmode unlockmode = getunlockmode(); munlockscreen = createunlockscreenfor(unlockmode); munlockscreenmode = unlockmode; addview(munlockscreen); updatescreen(mmode);
执行上面的程序然后弹出解锁界面,getunlockmode 获得锁类型,通常有三种:
enum unlockmode { pattern, //图案锁 simpin, //输入pin或者puk account //账号锁 }
通过上面的过程我们可以知道,在系统初始化阶段启动rild的时候,rild与猫进行了通信,并对猫进行初始化。保存了网络的一系列状态。
待机状态下,飞行模式切换流程分析:
飞行模式切换比较复杂,它状态改变时涉及到极大模块状态切换:
gsm模块,蓝牙模块,wifi模块。
飞行模式的enabler层会发送广播消息:action_airplane_mode_changed
private void setairplanemodeon(boolean enabling) { mcheckboxpref.setenabled(false); mcheckboxpref.setsummary(enabling ? r.string.airplane_mode_turning_on : r.string.airplane_mode_turning_off); // change the system setting settings.system.putint(mcontext.getcontentresolver(), settings.system.airplane_mode_on, enabling ? 1 : 0); // post the intent intent intent = new intent(intent.action_airplane_mode_changed); intent.putextra("state", enabling); mcontext.sendbroadcast(intent); }
因为gsm ,蓝牙,wifi模块分别注册了对 action_airplane_mode_changed 消息的监测,所以收到该消息后,模块会进行切换。
bluetoothdeviceservice.java
开启蓝牙:enable(false);
关闭蓝牙:disable(false);
phoneapp.java (packages\apps\phone\src\com\android\phone)
设置gsm模块状态 phone.setradiopower(enabled);
wifiservice.java
设置 wifi 状态 setwifienabledblocking(wifienabled, false, process.myuid());
gsm模块切换过程分析:
phone.setradiopower(enabled)调用的是:
文件 gsmphone.java 中的的函数:
public void setradiopower(boolean power) msst.setradiopower(power);
因为有 servicestatetracker msst;
msst.setradiopower 调用的是文件 servicestatetracker.java 中的函数:
public void setradiopower(boolean power) mdesiredpowerstate = power; setpowerstatetodesired(); cm.setradiopower(true, null);
或者
cm.setradiopower(false, null);
因为有:
commandsinterface cm; public final class ril extends basecommands implements commandsinterface
所以 cm.setradiopower 调用的是文件 ril.java 中的函数:
public void setradiopower(boolean on, message result) rilrequest rr = rilrequest.obtain(ril_request_radio_power, result); rr.mp.writeint(1); ... send(rr)
通过 send 向 rild 发送 ril_request_radio_power 请求来开启或者关闭gsm模块。
rild 数据接收流程:
收到 ril_request_radio_power 执行:
requestradiopower(data, datalen, t);
然后根据条件往无线模块发送模块开启和关闭请求
主要的at命令有:
err = at_send_command("at+cfun=0", &p_response); err = at_send_command("at+cfun=1", &p_response);
蓝牙模块切换过程分析:
enable(false);
蓝牙开启调用文件 bluetoothdeviceservice.java 中的函数:
public synchronized boolean enable(boolean savesetting) setbluetoothstate(bluetoothdevice.bluetooth_state_turning_on); menablethread = new enablethread(savesetting); menablethread.start(); ---- disable(false)
蓝牙关闭调用文件 中的函数:
public synchronized boolean disable(boolean savesetting) setbluetoothstate(bluetoothdevice.bluetooth_state_turning_off);
wifi模块切换过程分析:
广播 wifi 状态改变的消息:wifi_state_changed_action
更新 wifi 状态:
private void updatewifistate()
如果需要使能开启 wifi 那么会发送:
sendenablemessage(true, false, mlastenableuid); sendstartmessage(strongestlockmode == wifimanager.wifi_mode_scan_only); mwifihandler.sendemptymessage(message_stop_wifi);
消息循环中处理命令消息:
public void handlemessage(message msg)
如果使能wifi:setwifienabledblocking(true, msg.arg1 == 1, msg.arg2);
开启wifi:
mwifistatetracker.setscanonlymode(msg.arg1 != 0); setwifienabledblocking(false, msg.arg1 == 1, msg.arg2);
断开
mwifistatetracker.disconnectandstop();
开启过程步骤:
1> 装载 wifi 驱动: wifinative.loaddriver()
2> 启动后退 daemo supplicant: wifinative.startsupplicant()
关闭过程步骤:
1> 停止后退 daemo supplicant:wifinative.stopsupplicant()
2> 卸载 wifi 驱动: wifinative.unloaddriver()
如果 wifi 状态默认为开启那么 wifiservice 服务的构造函数:
wifiservice(context context, wifistatetracker tracker) boolean wifienabled = getpersistedwifienabled(); setwifienabledblocking(wifienabled, false, process.myuid());
会开启wifi模块。
更多关于android相关内容感兴趣的读者可查看本站专题:《android数据库操作技巧总结》、《android编程之activity操作技巧总结》、《android文件操作技巧汇总》、《android编程开发之sd卡操作方法汇总》、《android开发入门与进阶教程》、《android资源操作技巧汇总》、《android视图view技巧总结》及《android控件用法总结》
希望本文所述对大家android程序设计有所帮助。
上一篇: java堆排序原理与实现方法分析