>>分享Android开发相关的技术 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 19435 个阅读者 刷新本主题
 * 贴子主题:  Android SDCard UnMounted 流程分析 回复文章 点赞(0)  收藏  
作者:mary    发表时间:2020-03-31 12:44:32     消息  查看  搜索  好友  邮件  复制  引用

            

Android SDCard框架

     Android SDCard框架,我们修改一般涉及到四大模块                      
  1. Linux Kernel 用于检测热拔插,作为框架开发者来说,这者不用涉及
  2. Vold 作为Kernel 与 Framework 之间的桥梁
  3. Framework 操作Vold ,给Vold 下发操作命令
  4. UI 与Framework 交互,用于挂载/卸载SD卡

框架涉及的源码位置

                   Vold :System/vold

                 为vold 提供接口:System/Netd

                 其他涉及的部分:System/core/libsysutils/src

                                            System/core/include/sysutils

                  Framework:frameworks/base/services/java/com/android/server

                  访问和提供接口类:framework/base/core/java/android/os/storage/

                  可能还要参考的库:framework/base/libs/storage

                                                   framework/base/native

                  UI:Settings/src/com/android/setting/deviceinfo                      

SDCard UnMounted流程分析

初始化

     VolumeManager, CommandListener, NetlinkManager 都是在 main()函数里面初始化的。

     其中 VolumeManager,NetlinkManager 内部采用单例模式。

(1) Class NetlinkManager 主要是创建于内核通信的 socket,接收来自底层的信息,然后传交给VolumeManager 处理。

(2) class CommandListener 主要收到上层 MountService 通过 doMountVolume 发来的命令,分析后,转交给 VolumeManager 处理;VolumeManager 处理信息后,或报告给上层 MountService,

或交给 volume 执行具体操作。CommandListener在main()初始化后,之后开始监听,会开一个线程不停的监听来自内核的消息。

               深入main文件

         在Vold 的main.cpp里面,启动一个线程用来监听kernel 发出unMounted 的uevent事件,代码:

      NetlinkManager *nm;

     // NetlinkManager内部使用的单例模式

      if (!(nm = NetlinkManager::Instance())) {

            SLOGE( " Unable to create NetlinkManager ");

            exit( 1);

        };

     // 开始监听,从服务启动就一直监听

     if ( nm->start()) {

            SLOGE( " Unable to start NetlinkManager (%s) ", strerror(errno));

            exit( 1);

        }

          NetlinkManager的start 函数是实例化了一个NetlinkHandler(继承关系:NetlinkHandler->NetlinkListener->SocketLinstener),并调用handler 的start方法,如下代码:

       mHandler =  new NetlinkHandler(mSock);

         if ( mHandler->start()) {

            SLOGE( " Unable to start NetlinkHandler: %s ", strerror(errno));

             return - 1;

        }

       深入NetlinkHandler 的start函数,见代码:

      int NetlinkHandler::start() {

         return  this-> startListener();

    }  

       上面有说过NetlinkHandler其实是SocketLinstener的子类,NetlinkHandler直接调用父类的startListener 方法,startListener开启了一个线程用来执行threadStart函数,代码太多,贴出主心代码:

       if (pthread_create(&mThread, NULL,  SocketListener::threadStart,  this)) {

            SLOGE( " pthread_create (%s) ", strerror(errno));

             return - 1;

        }  

     而threadStart函数则调用了runListener方法,代码如下:

      void *SocketListener::threadStart( void *obj) {

        SocketListener *me = reinterpret_cast<SocketListener *>(obj);

                     me->runListener();

        pthread_exit(NULL);

         return NULL;

    }  

              runListener会判断socket 有无信息可读,不会阻滞UI,最后调用onDataAvailable函数,代码:

      void SocketListener::runListener() {

                 SocketClientCollection *pendingList =  new SocketClientCollection();

         //代码有所省略

       while (!pendingList->empty()) {

             /* Pop the first item from the list */

             it = pendingList->begin();

             SocketClient* c = *it;

             pendingList->erase(it);

             /* Process it, if false is returned and our sockets are

              * connection-based, remove and destroy it */


             if (! onDataAvailable(c) && mListen) {

                 /* Remove the client from our array */

                 pthread_mutex_lock(&mClientsLock);

                 for (it = mClients->begin(); it != mClients->end(); ++it) {

                     if (*it == c) {

                         mClients->erase(it);

                         break;

                     }

                 }

                 pthread_mutex_unlock(&mClientsLock);

                 /* Remove our reference to the client */

                 c->decRef();

             }

         }

            }

    }  

       onDataAvailable会处理来自uEvent 的命令,并最终调用onEvent函数,onDataAvailable 位于System/core/libsysutils/src/NetlinkListener.cpp 这个主要处理一些socket方法的知识,一般不用修改。

         最后由Netlinklinstener 来解析 ,代码:

      bool NetlinkListener::onDataAvailable(SocketClient *cli)

    {

         int socket = cli->getSocket();

        ssize_t count;

                    count = TEMP_FAILURE_RETRY( uevent_kernel_multicast_recv(socket, mBuffer,  sizeof(mBuffer)));

         if (count <  0) {

            SLOGE( " recvmsg failed (%s) ", strerror(errno));

             return  false;

        }

                    NetlinkEvent *evt =  new NetlinkEvent();

         if (!evt->decode(mBuffer, count, mFormat)) {

            SLOGE( " Error decoding NetlinkEvent ");

        }  else {

             onEvent(evt);

        }

                    delete evt;

         return  true;

    }

小结

     NetlinkManager其实就是用来处理uEvent 命令,并最终发送到vold/NetlinkHandler 的onEvent 。

          

----------------------------
原文链接:https://blog.51cto.com/terryblog/813712

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-04-18 17:22:14 重新编辑]
网站系统异常


系统异常信息
Request URL: http://www.javathinker.net/WEB-INF/lybbs/jsp/topic.jsp?postID=3122

java.lang.NullPointerException

如果你不知道错误发生的原因,请把上面完整的信息提交给本站管理人员