1
Android
系统启动

1.1 总体启动框架图

(1) init进程启动

(2) Native服务启动

(3) System Server,Android服务启动

(4) Home启动



1.2 initial进程(system\core\init)

init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。

Init进程一起来就根据init.rc和init.xxx.rc脚本文件建立了几个基本的服务:

servicemanamger

zygote 。。。。

最后Init并不退出,而是担当起property service的功能。

关于init的详细信息,参考相关文章。

1.3 Zygote

Servicemanager和zygote进程就奠定了Android的基础。Zygote这个进程起来才会建立起真正的Android运行空间,初始化建立的Service都是Navtive service.在.rc脚本文件中zygote的描述:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

所以Zygote从main(…)--frameworks\base\cmds\app_main.cpp开始。

(1) main(…)---frameworks\base\cmds\app_main.cpp

建立Java Runtime

runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);

(2) [email protected]

建立虚拟机

运行:com.android.internal.os.ZygoteInit:main函数。

(3)main()---com.android.internal.os.ZygoteInit//正真的Zygote。

registerZygoteSocket();//登记Listen端口

startSystemServer();

进入Zygote服务框架。

经过这几个步骤,Zygote就建立好了,利用Socket通讯,接收ActivityManangerService的请求,Fork应用程序。

1.4 System Server

startSystemServer(com.android.internal.os.ZygoteInit)在Zygote上fork了一个进程: com.android.server.SystemServer.于是SystemServer(SystemServer.java)就建立了。Android的所有服务循环框架都是建立SystemServer(SystemServer.java)上。在SystemServer.java中看不到循环结构,只是可以看到建立了init2的实现函数,建立了一大堆服务,并AddService到service Manager。

main() ( com/android/server/SystemServer )

{

init1();

}

Init1()是在Native空间实现的(com_andoird_server_systemServer.cpp)。我们一看这个函数就知道了,init1->system_init() (System_init.cpp)

在system_init()我们看到了循环闭合管理框架。

{

Call "com/android/server/SystemServer", "init2"

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}

init2()@SystemServer.java中建立了Android中所有要用到的服务。

这个init2()建立了一个线程,来New Service和AddService来建立服务

在其上建立了多个android服务,包括我们以后的指纹识别,也会是在这个总的服务框架内实施,需要做到信息的收发处理,可以理解为。与底层JNI如何通信,与上层app如何相互传递信息。

对于如何建立某个功能模块的服务,不需要关注太多底层的东西(包括init,zygote等等)。需要关注如上的第步 System Server

1.5 Home启动

ServerThread(SystemServer.java)后半段,我们可以看到系统在启动完所有的Android服务后,做了这样一些动作:

(1) 使用xxx.systemReady()通知各个服务,系统已经就绪。

(2) 特别对于ActivityManagerService.systemReady(回调)

2 Phone模块

为了对android的server如何工作有个大致的了解,以Phone模块电话为例。

流程图



2.1 过程分析

Phone服务:是指Phone所能提供的各种服务(来电去电,短信,SIM的锁定,数据连结传输等)与service不是同一个概念。

Phone 中的service是ITelephony和ITelephonyRegistry的实现类,PhoneInterfaceManager.java和TelephonyRegistry.java,后续说明。

GSMPhone 管理了电话服务的内部功能,也对RIL层进行了封装,上层应用不能直接跟RIL本地代码打交道,而是间接通过GSMPhone.但是应用层为了更方便的访问电话服务,需要在GSMPhone之上的TelephonyManager。

TelephonyManager通过两个IBinder接口ITelephony和ITelephonyRegistry来完成这项工作。

ITelephony是电话服务用户(用户层或框架其他部分)主动进行RIL访问的路径,它的服务端实现类不在代码中,而是在Phone应用PhoneInterfaceManager.java(packages/apps/Phone/src/com/android/phone/)中。PhoneInterfaceManager.publish中以”phone”为名注册该服务,提供拨号界面、呼叫、挂机等呼叫相关控制,也提供SIM PIN、开关Radio等操作,他的实现是通过调用Phone接口来操作。

ItelephonyRegistry提供一个通知机制,将底层状态变更通知给电话服务的用户(用户层或框架其他部分),是用户被动通知的路径,通知消息如网络状态、信号强弱更新、电话状态更新等。它的服务端实现在框架代码中TelephonyRegistry.java(frameworks/base/services/java/com/android/server/)。

底层通知的来源,是GSMPhone通过PhoneNotifier的实现者DefaultPhoneNotifier将具体的事件转化为函数调用并且通知到TelephonyRegistry。TelephonyRegistry再通过两种方式通知给用户,其一是广播事件,另外一种是通过服务用户在TelephonyRegistry中注册的IphoneStateListener接口,实现回调。

SystemServer.java实现了电话服务的添加

………

ServiceManager.addService("telephony.registry",new TelephonyRegistry(context));

………

对于在SystemServer.java中添加的Service,SystemServer.java 中的init1()函数保证了Service在后台不断运行,具体的底层实现,需要查看文档和源码。

2.2 去电流程

不论打电话的方式是何种(拨号盘拨打,通话记录中拨号,联系人中拨号。。),都会触发outgoingCallBroadcastonCreate()函数,获得Action & Number,并对其进行判断,并且广播给outgoingCallReceiver内部类,发送Intent.ACTION_NEW_OUTGOING_CALL消息。

outgoingCallReceiver收到Intent消息,调用onReceiver() -> doReceiver(),启动InCallScreen界面。

进入InCallScreen后,可以分为15个函数调用。

具体的分析如下:

1.进入InCallScreen类中,如果是第一次进入,调用onCreate()函数(1),如果在通话过程再一次的拨打电话,调用onNewIntent()函数(2)。两个函数都会调用IntentResolveIntent()函数(3),在这个函数中调用InCallScreen类中的成员方法placeCall()函数(4)

InCallScreen中的placeCall()函数调用类PhoneUtils.placeCall()函数(5)PhoneUtils.placeCall()函数调用phone.dial()函数,至此app层的函数调用结束,转到frameworks层。

InCallScreen.java PhoneUtils.Javapackages\apps\phone\src\com\android\phone…

(6) PhoneUtils.java

static int placeCall(Phone phone, String number, Uri contactRef)

(7) Connection cn = phone.dial(number); 

GSMPhone.java

phone应用程序中,通过PhoneFactory来获取GSMPhone实例。

GSMPhone()....

(8)dial(String dialString)

(9)mCT.dial(mmi.dialingNumber, mmi.getCLIRMode()); (PS: GsmCallTracker mCT)

GsmCallTracker.java

GsmCallTracker dial (String dialString)...

(10)dial (String dialString, int clirMode) {

...

(11)cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());

(ps: CommandInterface cm = phone.mCM)

...

}

因为 RIL.java (frameworks\base\telephony\java\com\android\internal\telephony):

public final class RIL extends BaseCommands implements CommandsInterface所以 cm.dial

实际上调用的是 RIL.java 中的dial -(12)

RIL.java

(12)dial (String address, int clirMode, Message result)

LRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);

(13)send()

(14) msg.sendToTarget();

target.sendMessage(this); (frameworks/base/core/java/android/os/Message.java)

//Handler.java (frameworks\base\core\java\android\os)

boolean sendMessage(Message msg){

return sendMessageDelayed(msg, 0);

}

--> return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);

---> sent = queue.enqueueMessage(msg, uptimeMillis);

(15) RIL.java

class RILSender extends Handler implements Runnable{

//把消息放入到消息队列

public void handleMessage(Message msg)

..

s.getOutputStream().write(dataLength);

s.getOutputStream().write(data);

...

因为在 RIL.java 文件中有 static final String SOCKET_NAME_RIL = "rild";

run()函数中有:

s = new LocalSocket();

l = new LocalSocketAddress(SOCKET_NAME_RIL,

LocalSocketAddress.Namespace.RESERVED);

s.connect(l);

...

mSocket = s;}

所以可以确定s.getOutputStream().write(data) 是往 rild socket写数据。

到这里,frameworks 请求结束,通过socket转到RIL层处理 dial请求。

2.3 来电流程

1.创建GsmPhone时,mCT = new GsmCallTracker(this);

2.创建GsmCallTracker时:

cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); -->

mCallStateRegistrants.add(r);

3.RIL中的RILReceiver线程首先读取从rild中传来的数据:processResponse -> processUnsolicited

4.对应于incoming call,RIL收到RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 消息,触发mCallStateRegistrants中的所有记录。

5.GsmCallTracker处理EVENT_CALL_STATE_CHANGE,调用pollCallsWhenSafe

6.函数pllCallsWhenSafe 处理:

lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);

cm.getCurrentCalls(lastRelevantPoll);

7.RIL::getCurrentCalls

RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);

...

send(rr);

8.接着RIL调用processSolicited处理RIL_REQUEST_GET_CURRENT_CALLS的返回结果

9.GsmCallTracker的handleMessage被触发,处理事件EVENT_POLL_CALLS_RESULT,调用函数

handlePollCalls

10.handlPollCalls 调用

phone.notifyNewRingingConnection(newRinging);

11.PhoneApp中创建CallNotifier

12.CallNotifier注册:

registerForNewRingingConnection ->

mNewRingingConnectionRegistrants.addUnique(h, what, obj);

2.4 小结

Phone模块的分析,并对具体的来电、去电流程的跟踪,电话服务的框架式可以确定的,但是具体的实现细节还不清楚,这也是接下来的工作。

对于今后的新模块Service,大体可以这样实现:

1. Service完成的内容要明确,实现可以按照大多数模块那样编写AIDL文件,产生对应的java文件,通过继承与实现方式,来具体实现Service内容

2. 上层不可以直接的调用Service内的函数,需要通过一个xxxManager.java来方便的操作Service发送的消息。如Phone中的TelephonyManager.java来管理操作,具体的操作又是通过ITelephony ITelephonyRegistry来完成。

3. Service响应底层的事件,通过Broadcast发送Intent消息,应用层接收到消息事件,进行相应的处理。

4. Service可以设置监听,等到有反馈时,进行处理

5. Service启动可以在SystemServer.java 中添加。

更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)按键消息path
  3. Android注入完全剖析
  4. Android(安卓)设备连接电脑显示offline
  5. 深入理解Android消息机制
  6. android wifi开发
  7. android wrapper C调用java api
  8. Android跨进程通信IPC之11——Binder驱动
  9. Android(安卓)Low Memory Killer

随机推荐

  1. Android屏幕方向的改变
  2. TabLayout+ViewPager实现Android底部滑动
  3. Android获取相册中图片的路径 4.4版本前
  4. Android中的基础----在按钮上显示图像的
  5. Android之粘性广播理解
  6. 【android】7、五大存储
  7. Android(安卓)Volley框架使用方法详解
  8. Android(安卓)WakeLock解析
  9. android 基于百度地图api获取经纬度
  10. Android——编译系统初始化设置