清除APK缓存和获取APK的数据大小

现在诸多APK都提供了清除自己缓存的按钮,APK清除自己缓存的功能和系统应用程序管理里面清除缓存不一样。在APK里清除缓存可以清除APKCache目录、外部Cahce目录以及自己定义存储目,而应用程序管理里面清除缓存是调用了系统提供的远程接口,这个远程接口去清除APK系统目录下的缓存,这个清除的更干净些,当然这个需要系统权限,所以第三方APK只能戛然止步。

如果有系统签名文件,清除APK系统缓存可以实现远程接口IPackageDataObserver.aidl来做,别忘了添加android.permission.CLEAR_APP_USER_DATA权限,并且只能在源码下才能编译通过;如果没有系统签名文件,那么就只能手动来清除能清除的文件了。

所以,在自己的应用程序中,可以这样来做。首先,要清楚自己的应用程序在哪些目录中存放了文件,然后一个个去清除它们即可。

cache目录、外部cache目录、自定义存储目录,这是一般情况下能找到并且是APK存放文件的目录,只要清除它们下面的子目录和文件即可。

示意代码:

/**
	 * 清除app的缓存,由于权限问题,没有办法清除app在系统中的所有缓存,只能清除cache目录和app在外部存储存放临时文件的目录(
	 * 或许是自己定义的目录)
	 */
	public void clearAPPCache(ClearCacheCallBack callback) {
		try {
			// 1、清除APP cache目录下的内容
			File appCacheDir = this.getCacheDir();
			delFolder(appCacheDir.getAbsolutePath());
			if (Environment.MEDIA_MOUNTED.equals(Environment
					.getExternalStorageState())
					|| !Environment.isExternalStorageRemovable()) {
				// 2、清除APP外部cache目录下的内容
				File appExCacheDir = this.getExternalCacheDir();
				if (appExCacheDir != null) {
					delFolder(appExCacheDir.getAbsolutePath());
				}
				// 3、清除APP在外部自定义的缓存目录
				File appExDir = new File(MyApp.EX_DIR);
				if (appExDir != null) {
					delFolder(appExDir.getAbsolutePath());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			callback.clearResult(0);
		}
		callback.clearResult(1);
	}

	interface ClearCacheCallBack {
		public void clearResult(int resultCode);
	}

	public static void delFolder(String folderPath) {
		try {
			delAllFile(folderPath); // 删除完里面所有内容
			String filePath = folderPath;
			filePath = filePath.toString();
			java.io.File myFilePath = new java.io.File(filePath);
			myFilePath.delete(); // 删除空文件夹
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + File.separator + tempList[i]);// 先删除文件夹里面的文件
				delFolder(path + File.separator + tempList[i]);// 再删除空文件夹
				flag = true;
			}
		}
		return flag;
	}

另外获取APK的数据大小,可以通过远程接口IPackageStatsObserver.aidl来获取;

首先实现接口:

/**
	 * 通过远程调用接口来获取应用程序的各种大小
	 */
	public class PkgSizeObserver extends IPackageStatsObserver.Stub {
		@Override
		public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
				throws RemoteException {
			long cachesize; // 缓存大小
			long datasize; // 数据大小
			long codesize; // 应用程序大小
			long totalsize; // 总大小
			synchronized (Integer.class) {
				cachesize = pStats.cacheSize; // 缓存大小
				datasize = pStats.dataSize; // 数据大小
				codesize = pStats.codeSize; // 应用程序大小
				totalsize = cachesize + datasize + codesize;
				MyApp.Log("cachesize = " + formateFileSize(cachesize)
						+ " ,datasize = " + formateFileSize(datasize)
						+ " ,codesize = " + formateFileSize(codesize)
						+ " ,totalsize = " + formateFileSize(totalsize));
			}
		}
	}
其次,通过反射机制获取pm里面的具体方法:

PackageManager pm = getPackageManager();
			try {
				Method getPackageSizeInfo = pm.getClass().getDeclaredMethod(
						"getPackageSizeInfo", String.class,
						IPackageStatsObserver.class);
				getPackageSizeInfo.invoke(pm, this.getPackageName().toString(),new PkgSizeObserver());
			} catch (Exception ex) {
				ex.printStackTrace();
			}



你可能感兴趣的:(android,缓存)