<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                4.6.1 installd介紹 在前面對PKMS構造函數分析時介紹過一個Installer類型的對象mInstaller,它通過socket和后臺服務installd交互,以完成一些重要操作。這里先回顧一下PKMS中mInstaller的調用方法: ~~~ mInstaller = new Installer();//創建一個Installer對象 //對某個APK文件進行dexopt優化 mInstaller.dexopt(paths[i], Process.SYSTEM_UID,true); //掃描完系統Package后,調用moveFiles函數 mInstaller.moveFiles(); //當存儲空間不足時,調用該函數清理存儲空間 mInstaller.freeCache(freeStorageSize); ~~~ Installer的種種行為都和其背后的installd有關。下面來分析installd。 1. installd概貌 installd是一個native進程,代碼非常簡單,其功能就是啟動一個socket,然后處理來自Installer的命令,其代碼如下: installd.c ~~~ int main(const int argc, const char *argv[]) { charbuf[BUFFER_MAX]; structsockaddr addr; socklen_t alen; intlsocket, s, count; // if (初始化全局變量,如果失敗則退出) { initialize_globals(); initialize_directories(); ...... } ...... lsocket= android_get_control_socket(SOCKET_PATH); listen(lsocket, 5); fcntl(lsocket, F_SETFD, FD_CLOEXEC); for (;;){ alen= sizeof(addr); s =accept(lsocket, &addr, &alen); fcntl(s, F_SETFD, FD_CLOEXEC); for(;;) { unsigned short count; readx(s, &count, sizeof(count)); //執行installer發出的命令,具體解釋見下文 execute(s, buf); } close(s); } return0; } ~~~ installd支持的命令及參數信息都保存在數據結構cmds中,代碼如下: **installd.c** ~~~ struct cmdinfo cmds[] = {//第二個變量是參數個數,第三個參數是命令響應函數 {"ping", 0,do_ping }, {"install", 3,do_install }, {"dexopt", 3,do_dexopt }, {"movedex", 2,do_move_dex }, {"rmdex", 1,do_rm_dex }, {"remove", 2,do_remove }, {"rename", 2, do_rename }, {"freecache", 1,do_free_cache }, {"rmcache", 1,do_rm_cache }, {"protect", 2,do_protect }, {"getsize", 4,do_get_size }, {"rmuserdata", 2,do_rm_user_data }, {"movefiles", 0,do_movefiles }, {"linklib", 2,do_linklib }, {"unlinklib", 1,do_unlinklib }, {"mkuserdata", 3,do_mk_user_data }, {"rmuser", 1,do_rm_user }, }; ~~~ 下面來分析相關的幾個命令。 2. dexOpt命令分析 PKMS在需要對一個APK或jar包做dex優化時,會發送dexopt命令給installd,相應的處理函數為do_dexopt,代碼如下: **installd.c** ~~~ static int do_dexopt(char **arg, charreply[REPLY_MAX]) { returndexopt(arg[0], atoi(arg[1]), atoi(arg[2])); } ~~~ **commands.c** ~~~ int dexopt(const char *apk_path, uid_t uid, intis_public) { structutimbuf ut; structstat apk_stat, dex_stat; chardex_path[PKG_PATH_MAX]; chardexopt_flags[PROPERTY_VALUE_MAX]; char*end; int res,zip_fd=-1, odex_fd=-1; ...... //取出系統級的dexopt_flags參數 property_get("dalvik.vm.dexopt-flags", dexopt_flags,""); strcpy(dex_path, apk_path); end =strrchr(dex_path, '.'); if (end!= NULL) { strcpy(end, ".odex"); if(stat(dex_path, &dex_stat) == 0) { return 0; } } //得到一個字符串,用于描述dex文件名,位于/data/dalvik-cache/下 if(create_cache_path(dex_path, apk_path)) { return -1; } memset(&apk_stat, 0, sizeof(apk_stat)); stat(apk_path, &apk_stat); zip_fd =open(apk_path, O_RDONLY, 0); ...... unlink(dex_path); odex_fd= open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644); ...... pid_tpid; pid =fork(); if (pid== 0) { ......//uid設置 //創建一個新進程,然后對exec dexopt進程進行dex優化 run_dexopt(zip_fd,odex_fd, apk_path, dexopt_flags); exit(67); } else { //installd將等待dexopt完成優化工作 res= wait_dexopt(pid, apk_path); ...... } ......//資源清理 return-1; } ~~~ 讓人大跌眼鏡的是,dex優化工作竟然由installd委派給dexopt進程來實現。dex優化后會生成一個dex文件,一般位于/data/dalvik-cache/目錄中。這里給出一個示例,如圖4-12所示。 :-: ![](http://img.blog.csdn.net/20150803111157859?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖4-12 dex文件示例 >[info] **提示** :dexopt進程由android源碼/dalvik/dexopt/OptMain.cpp定義。感興趣的讀者可深入研究dex優化的工作原理。 3. movefiles命令分析 PKMS掃描完系統Package后,將發送該命令給installd,相應處理函數的代碼如下: **installd.c** ~~~ static int do_movefiles(char **arg, charreply[REPLY_MAX]) { returnmovefiles(); } [-->commands.c] int movefiles() { DIR *d; int dfd,subfd; structdirent *de; structstat s; charbuf[PKG_PATH_MAX+1]; intbufp, bufe, bufi, readlen; charsrcpkg[PKG_NAME_MAX]; chardstpkg[PKG_NAME_MAX]; charsrcpath[PKG_PATH_MAX]; chardstpath[PKG_PATH_MAX]; intdstuid=-1, dstgid=-1; inthasspace; //打開/system/etc/updatecmds/目錄 d =opendir(UPDATE_COMMANDS_DIR_PREFIX); if (d ==NULL) { gotodone; } dfd =dirfd(d); while((de = readdir(d))) { ......//解析該目錄下的文件,然后執行對應操作 } closedir(d); done: return0; } ~~~ 先來看/system/etc/updatecmds/目錄下到底是什么文件,這里給出一個示例,如圖4-13所示。 :-: ![](http://img.blog.csdn.net/20150803111217969?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖4-13 movefiles示例 以圖4-13中最后兩行為例,movefiles將把com.google.android.gsf下的databases目錄轉移到com.andorid.providers.im下。從文件中的注釋可知,movefiles的功能和系統升級有關。 4. doFreeCache 第3章介紹了DeviceStorageMonitorService,當系統空間不夠時,DSMS會調用PKMS的freeStorageAndNotify函數進行空間清理。該工作真正的實施者是installd,相應的處理命令為do_free_cache,其代碼如下: **installd.c** ~~~ static int do_free_cache(char **arg, charreply[REPLY_MAX]) { returnfree_cache((int64_t)atoll(arg[0])); } ~~~ **commands.c** ~~~ int free_cache(int64_t free_size) { constchar *name; int dfd,subfd; DIR *d; structdirent *de; int64_tavail; avail =disk_free();//獲取當前系統的剩余空間大小 if(avail < 0) return -1; if(avail >= free_size) return 0; d =opendir(android_data_dir.path);//打開/data/目錄 dfd =dirfd(d); while((de = readdir(d))) { if (de->d_type != DT_DIR) continue; name= de->d_name; ......//略過.和..文件 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); //刪除/data及各級子目錄中的cache文件夾 delete_dir_contents_fd(subfd, "cache"); close(subfd); ......//如果剩余空間恢復正常,則返回 } closedir(d); return-1;//清理空間后,仍然不滿足要求 } ~~~ installd的介紹就到此為止,這部分內容比較簡單,讀者完全可自行深入研究。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看