>>分享Android开发相关的技术 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 19434 个阅读者 刷新本主题
 * 贴子主题:  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 重新编辑]
  Java面向对象编程-->Java语言中的修饰符
  JavaWeb开发-->开发JavaMail Web应用
  JSP与Hibernate开发-->数据库事务的概念和声明
  Java网络编程-->ServerSocket用法详解
  精通Spring-->绑定表单
  Vue3开发-->Vue CLI脚手架工具
  Android安卓面试复盘
  Android ListView高度问题
  通过Https访问的Not trusted Server Certificate的问题的解决...
  Android Fragments 详细使用
  Android 自定义Menu
  Android中的几个布局
  Android ExpandableListView 使用范例
  Android 手势操作GestureDetector
  编译Irrlicht On Android
  Android 消息推送
  Android SDCard Mount 流程分析
  Android 活动(Activity)
  Android中shape的使用-Kofi
  MotionLayout 运动布局入门
  RecyclerView顶部阴影透明度渐变效果
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。