展会信息港展会大全

基于Phone模块的Service实现 android开发教程
来源:互联网   发布日期:2016-01-14 09:11:32   浏览:2176次  

导读:1 Android系统启动1.1 总体启动框架图(1) init进程启动(2) Native服务启动(3) System Server,Android服务启动(4) Home启动1.2 initial进程(system\core\init)init进程,它是一个由内核启动的用户级进程......

1Android系统启动

1.1总体启动框架图

(1) init进程启动

(2) Native服务启动

(3) System Server,Android服务启动

(4) Home启动

1.2initial进程(system\core\init)

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

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

servicemanamger

zygote 。。。。

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

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

1.3Zygote

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) runtime.start@AndroidRuntime.cpp

建立虚拟机

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

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

registerZygoteSocket();//登记Listen端口

startSystemServer();

进入Zygote服务框架。

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

1.4System 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.5Home启动

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

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

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

2Phone模块

为了对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去电流程

不论打电话的方式是何种(拨号盘拨打,通话记录中拨号,联系人中拨号。。),都会触发outgoingCallBroadcast的onCreate()函数,获得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.Java在packages\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 中添加。

赞助本站

人工智能实验室

相关热词: Service Phone 模块

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港