当前位置:操作系统 > 安卓/Android >>

Android SDCard UnMounted 流程分析(三)

前一篇http://www.zzzyk.com/kf/201203/124633.html 讲到SDCard unmout onEvent 发送socket 到框架层,接下来分析框架层得到数据后的流程。
 MoutService
当android 系统启动时,system将MountService 添加到启动服务里面,而MountService 会开启一个线程来运行NativeDaemonConnector,由它来监听vold的消息,代码:
 mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG);
        mReady = false;
        Thread thread = new Thread(mConnector, VOLD_TAG);
        thread.start(); 

 该函数运行在MountService的构造函数里面,而NativeDaemonConnector 本身就是继承自Runnable。
NativeDaemonConnector
 Framework与vold 的通信是通过socket来实现的,不过该socket 由 android做了一个封装,LocalSocket 实现的socket功能。
NativeDaecomConnector 位于framework/base/service/java/com/android/server目录下, 监听vold 的消息代码在继承自Runnable对象的run方法里面 :
@Override
    public void run() {
        HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
        thread.start();
        mCallbackHandler = new Handler(thread.getLooper(), this);

        while (true) {
            try {
                listenToSocket();
            } catch (Exception e) {
                Slog.e(TAG, "Error in NativeDaemonConnector", e);
                SystemClock.sleep(5000);
            }
        }
    } 

 
NativeDaemonConnector 类实例化了一个LocalSocket来与vold 通信。LocalSocket 里面有一个类LocalSocketImpl,该类部分是通过JNI实现的。
关于socket 内部如何通信,这个不是我们所关心的内容,因为如果要深入进去估计没完没了,有兴趣的朋友可以参考源码进入SocketListener查看:
建立连接
SocketListener::SocketListener
 
当main初始化CommandListener 后,会为socketName 传入一个叫vold 的字符串
SocketListener::startListener
 
等待并接收连接请求
SocketListener::runListener
 
获得命令参数
bool FrameworkListener::onDataAvailable
 
dispatchCommand 到相应的命令类,并返回一部分消息给上层
FrameworkListener::dispatchCommand
 再回过头看NativeDaemonConnector 的listenToSocket,代码中实例化了一个LocalSocketAddress的实例,并传入一个叫"vold"字符串的socket 名称,这与CommandListener中继承了FrameworkListener时给的"vold"名称是一致的,两个socket名称一致则可以互相进行通讯了,代码如下:
private void listenToSocket() throws IOException {
        LocalSocket socket = null;
    Slog.w(TAG,String.format("NativeDaemonConnector--->listenToSocket:start"));
        try {
            socket = new LocalSocket();
            LocalSocketAddress address = new LocalSocketAddress(mSocket,
                    LocalSocketAddress.Namespace.RESERVED);

            socket.connect(address);

            InputStream inputStream = socket.getInputStream();
            mOutputStream = socket.getOutputStream();

            mCallbacks.onDaemonConnected();

            byte[] buffer = new byte[BUFFER_SIZE];
            int start = 0;

            while (true) {
                int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
                if (count < 0) break;

                // Add our starting point to the count and reset the start.
                count += start;
                start = 0;

                for (int i = 0; i < count; i++) {
                    if (buffer[i] == 0) {
                        String event = new String(buffer, start, i - start);//解析socket 的数据并获取event
                        if (LOCAL_LOGD) Slog.d(TAG, String.format("RCV <- {%s}", event));

                        String[] tokens = event.split(" ", 2);
                        try {
                            int code = Integer.parseInt(tokens[0]);

                            if (code >= ResponseCode.UnsolicitedInformational) {
                                mCallbackHandler.sendMessage(
                                        mCallbackHandler.obtainMessage(code, event));//发送消息给handler
                            } else {
                                try {
                                    mResponseQueue.put(event);

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,