Perform the following operations:
Set-> application-> select an application-> application information
The following page is displayed:
The disk space occupied by the application is displayed.
First, let's talk about the results, which files (folders) will be calculated for these items ).
1. Application, Composed of three elements
/Data/com. myapp/lib, that is, the so library folder size/data/app/com.myapp-1.apk, copy the original apk file/data/dalvik-cache/data@app@com.myapp-1.apk @ classes. dex, dalvik VM cache dex files
2. USB storage (Application). The size after the program is installed (or moved to) the SD card. /Sdcard/Android/..., refer to "application.
3. Data=/Data/com. myapp/directory size-cache subdirectory size-lib subdirectory size
4. SD card=/Sdcard/Android/data/com. myapp/directory size-/sdcard/Android/data/com. myapp/cache directory size
(TotalIs the sum of the above four)
5. Cache=/Data/com. myapp/cache directory size +/sdcard/Android/data/com. myapp/cache directory size
The following describes how to do the Android4.2 source code. In more detail, the analysis process will be cumbersome. Let's teach it to fish.
Based on the application information interface Settings name, guess the source code
Android4.2/packages/apps/Settings/src/com/android/settings/applications/InstalledAppDetails. java
Responsible. The corresponding xml is
Android4.2/packages/apps/Settings/res/layout/installed_app_details.xml
The function used to refresh the disk size is
InstalledAppDetaileds. refreshSizeInfo ()
Reverse lookup Based on code clues
MDataSize. setText (getSizeStr (dataSize ));
->
Long dataSize = mAppEntry. dataSize;
->
MAppEntry = mState. getEntry (packageName );
->
MState. requestSize (mAppEntry.info. packageName );
ApplicationsState mState
->
Android4.2/packages/apps/Settings/src/com/android/settings/applications/ApplicationState. java
MPm. getPackageSizeInfo (packageName, mBackgroundHandler. mStatsObserver );
Final PackageManager mPm
->
Android4.2/frameworks/base/core/java/android/app/ApplicationPackageManager. java
Public void getPackageSizeInfo (String packageName, int userHandle,
IPackageStatsObserver observer ){
MPM. getPackageSizeInfo (packageName, userHandle, observer );
Private final IPackageManager mPM;
->
IPackageManager is an interface. It is implemented by searching for file content. According to java syntax, the keyword "extends IPackageManager" can be used"
You can use the shell command line to obtain the following results:
Liuhx @ uc ~ /Desktop/android4.2 $ grep-rnsw "extends IPackageManager "*
Frameworks/base/services/java/com/android/server/pm/PackageManagerService. java: 172: public class PackageManagerService extends IPackageManager. Stub {
->
Android4.2/frameworks/base/services/java/com/android/server/pm/PackageManagerService. java
Public void getPackageSizeInfo (
Message msg = mHandler. obtainMessage (INIT_COPY );
Msg. obj = new MeasureParams (stats, observer );
MHandler. sendMessage (msg );
->
Internal class MeasureParams
Void handleStartCopy () throws RemoteException {
MSuccess = getPackageSizeInfoLI (mStats. packageName, mStats. userHandle, mStats );
->
GetPackageSizeInfoLI Function
Int res = mInstaller. getSizeInfo (packageName, userHandle, p. mPath, publicSrcDir,
AsecPath, pStats );
Final Installer mInstaller
->
Frameworks/base/services/java/com/android/server/pm/Installer. java
Public int getSizeInfo (
String s = transaction (builder. toString ());
->
Private synchronized String transaction (String cmd ){
If (! WriteCommand (cmd )){
->
Private boolean writeCommand (String _ cmd)
MOut. write (buf, 0, 2 );
MOut. write (cmd, 0, len );
->
OutputStream mOut;
LocalSocketAddress address = new LocalSocketAddress ("installd ",
LocalSocketAddress. Namespace. RESERVED );
MSocket. connect (address );
MOut = mSocket. getOutputStream ();
It is speechless and uses socket to communicate.
->
Find the file content. The keyword is "installd". Note that it contains double quotation marks.
Expected result:
Liuhx @ uc ~ /Desktop/android4.2 $ grep-rnsw "\" installd \""*
Cts/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/rootprocess.pdf. java: 33: "installd ",
Frameworks/base/services/java/com/android/server/pm/Installer. java: 51: LocalSocketAddress address = new LocalSocketAddress ("installd ",
Frameworks/base/cmds/installd. h: 18: # define LOG_TAG "installd"
Frameworks/base/cmds/installd. h: 49: # define SOCKET_PATH "installd"
Sdk/files/ant/build. xml: 1355:
Sdk/files/ant/build. xml: 1392:
->
Frameworks/base/cmds/installd. h
Int get_size (const char * pkgname, int persona, const char * apkpath, const char * fwdlock_apkpath,
Const char * asecpath, int64_t * codesize, int64_t * datasize, int64_t * cachesize,
Int64_t * asecsize );
Or
Frameworks/base/cmds/installd. c
Static int do_get_size (char ** arg, char reply [REPLY_MAX])
Res = get_size (arg [0], atoi (arg [1]), arg [2], arg [3], arg [4],
& Codesize, & datasize, & cachesize, & asecsize );
->
The get_size function is not implemented in installd. c. You can search the file content according to the function declaration, but since it is a C language, it may be to implement function separation.
So in the installd. c directory, you can see the implementation in another code file. Reprinted please indicate the source: http://blog.csdn.net/hursing
->
Frameworks/base/cmds/installd/commands. c
Here is the source code for computing.
int get_size(const char *pkgname, int persona, const char *apkpath, const char *fwdlock_apkpath, const char *asecpath, int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, int64_t* _asecsize){ DIR *d; int dfd; struct dirent *de; struct stat s; char path[PKG_PATH_MAX]; int64_t codesize = 0; int64_t datasize = 0; int64_t cachesize = 0; int64_t asecsize = 0; /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. */ if (validate_system_app_path(apkpath) && strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) { if (stat(apkpath, &s) == 0) { codesize += stat_size(&s); } } /* count the forward locked apk as code if it is given */ if (fwdlock_apkpath != NULL && fwdlock_apkpath[0] != '!') { if (stat(fwdlock_apkpath, &s) == 0) { codesize += stat_size(&s); } } /* count the cached dexfile as code */ if (!create_cache_path(path, apkpath)) { if (stat(path, &s) == 0) { codesize += stat_size(&s); } } /* add in size of any libraries */ if (!create_pkg_path_in_dir(path, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) { d = opendir(path); if (d != NULL) { dfd = dirfd(d); codesize += calculate_dir_size(dfd); closedir(d); } } /* compute asec size if it is given */ if (asecpath != NULL && asecpath[0] != '!') { if (stat(asecpath, &s) == 0) { asecsize += stat_size(&s); } } if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, persona)) { goto done; } d = opendir(path); if (d == NULL) { goto done; } dfd = dirfd(d); /* most stuff in the pkgdir is data, except for the "cache" * directory and below, which is cache, and the "lib" directory * and below, which is code... */ while ((de = readdir(d))) { const char *name = de->d_name; if (de->d_type == DT_DIR) { int subfd; int64_t statsize = 0; int64_t dirsize = 0; /* always skip "." and ".." */ if (name[0] == '.') { if (name[1] == 0) continue; if ((name[1] == '.') && (name[2] == 0)) continue; } if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { statsize = stat_size(&s); } subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); if (subfd >= 0) { dirsize = calculate_dir_size(subfd); } if(!strcmp(name,"lib")) { codesize += dirsize + statsize; } else if(!strcmp(name,"cache")) { cachesize += dirsize + statsize; } else { datasize += dirsize + statsize; } } else if (de->d_type == DT_LNK && !strcmp(name,"lib")) { // This is the symbolic link to the application's library // code. We'll count this as code instead of data, since // it is not something that the app creates. if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { codesize += stat_size(&s); } } else { if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { datasize += stat_size(&s); } } } closedir(d);done: *_codesize = codesize; *_datasize = datasize; *_cachesize = cachesize; *_asecsize = asecsize; return 0;}
The above figure shows the usage of the internal disk, which is not consistent. There are also clues:
The internal class MeasureParams. handleStartCopy () function of PackageManagerService. java:
void handleStartCopy() throws RemoteException { synchronized (mInstallLock) { mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); } final boolean mounted; if (Environment.isExternalStorageEmulated()) { mounted = true; } else { final String status = Environment.getExternalStorageState(); mounted = (Environment.MEDIA_MOUNTED.equals(status) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); } if (mounted) { final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); final File externalCacheDir = userEnv .getExternalStorageAppCacheDirectory(mStats.packageName); final long externalCacheSize = mContainerService .calculateDirectorySize(externalCacheDir.getPath()); mStats.externalCacheSize = externalCacheSize; final File externalDataDir = userEnv .getExternalStorageAppDataDirectory(mStats.packageName); long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir .getPath()); if (externalCacheDir.getParentFile().equals(externalDataDir)) { externalDataSize -= externalCacheSize; } mStats.externalDataSize = externalDataSize; final File externalMediaDir = userEnv .getExternalStorageAppMediaDirectory(mStats.packageName); mStats.externalMediaSize = mContainerService .calculateDirectorySize(externalMediaDir.getPath()); final File externalObbDir = userEnv .getExternalStorageAppObbDirectory(mStats.packageName); mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir .getPath()); } }
The disk usage on the SD card is calculated here.
The linux stat function is used for internal disk computing.
Some directory and file constants are defined in installd. h.
Read the code carefully and you will get the results at the beginning of the article.
The size of the disk occupied by the code calculation result is obtained. However, because the memory has the concept of "4 K alignment", the size of the disk occupied is not equal to the file size. For example, a 2.98K file is displayed as 4 K in the application information.
Reprinted please indicate the source: http://blog.csdn.net/hursing