当前位置: 移动技术网 > 移动技术>移动开发>Android > Android教程之开机流程全面解析

Android教程之开机流程全面解析

2019年07月24日  | 移动技术网移动技术  | 我要评论
本文详细讲述了android的开机流程。分享给大家供大家参考,具体如下: 开机过程中无线模块的初始化过程;如果sim卡锁开启,或者pin被锁住的时候,会要求输入pin或者

本文详细讲述了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 中有:

复制代码 代码如下:
final windowmanagerpolicy mpolicy = policymanager.makenewwindowmanager();

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

复制代码 代码如下:
setwifienabledstate(enable ? wifi_state_enabling : wifi_state_disabling, uid);

更新 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程序设计有所帮助。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网