在安卓开发中,应用会有清理缓存的功能.但是清理缓存这个功能,安卓里面是有相应的方法,不过google设置成了hide,不能直接调用.
onGetStatsCompleted(PackageStats pStats, boolean succeeded)这个方法,通过该方法的pStats参数可以得到应用的缓存,数据缓存,代码容量缓存,在这过程中还需要用到系统的aidl文件IPackageStatsObserver:
/**
** Copyright 2007, The Android Open Source Project
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package android.content.pm;
import android.content.pm.PackageStats;
/**
* API for package data change related callbacks from the Package Manager.
* Some usage scenarios include deletion of cache directory, generate
* statistics related to code, data, cache usage(TODO)
* {@hide}
*/
oneway interface IPackageStatsObserver {
void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);
}
PackageStats:
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.content.pm;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
/**
* implementation of PackageStats associated with a
* application package.
*/
public class PackageStats implements Parcelable {
/** Name of the package to which this stats applies. */
public String packageName;
/** @hide */
public int userHandle;
/** Size of the code (e.g., APK) */
public long codeSize;
/**
* Size of the internal data size for the application. (e.g.,
* /data/data/<app>)
*/
public long dataSize;
/** Size of cache used by the application. (e.g., /data/data/<app>/cache) */
public long cacheSize;
/**
* Size of the secure container on external storage holding the
* application's code.
*/
public long externalCodeSize;
/**
* Size of the external data used by the application (e.g.,
* <sdcard>/Android/data/<app>)
*/
public long externalDataSize;
/**
* Size of the external cache used by the application (i.e., on the SD
* card). If this is a subdirectory of the data directory, this size will be
* subtracted out of the external data size.
*/
public long externalCacheSize;
/** Size of the external media size used by the application. */
public long externalMediaSize;
/** Size of the package's OBBs placed on external media. */
public long externalObbSize;
public static final Parcelable.Creator<PackageStats> CREATOR
= new Parcelable.Creator<PackageStats>() {
public PackageStats createFromParcel(Parcel in) {
return new PackageStats(in);
}
public PackageStats[] newArray(int size) {
return new PackageStats[size];
}
};
public String toString() {
final StringBuilder sb = new StringBuilder("PackageStats{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(" ");
sb.append(packageName);
if (codeSize != 0) {
sb.append(" code=");
sb.append(codeSize);
}
if (dataSize != 0) {
sb.append(" data=");
sb.append(dataSize);
}
if (cacheSize != 0) {
sb.append(" cache=");
sb.append(cacheSize);
}
if (externalCodeSize != 0) {
sb.append(" extCode=");
sb.append(externalCodeSize);
}
if (externalDataSize != 0) {
sb.append(" extData=");
sb.append(externalDataSize);
}
if (externalCacheSize != 0) {
sb.append(" extCache=");
sb.append(externalCacheSize);
}
if (externalMediaSize != 0) {
sb.append(" media=");
sb.append(externalMediaSize);
}
if (externalObbSize != 0) {
sb.append(" obb=");
sb.append(externalObbSize);
}
sb.append("}");
return sb.toString();
}
public PackageStats(String pkgName) {
packageName = pkgName;
userHandle = UserHandle.myUserId();
}
/** @hide */
public PackageStats(String pkgName, int userHandle) {
this.packageName = pkgName;
this.userHandle = userHandle;
}
public PackageStats(Parcel source) {
packageName = source.readString();
userHandle = source.readInt();
codeSize = source.readLong();
dataSize = source.readLong();
cacheSize = source.readLong();
externalCodeSize = source.readLong();
externalDataSize = source.readLong();
externalCacheSize = source.readLong();
externalMediaSize = source.readLong();
externalObbSize = source.readLong();
}
public PackageStats(PackageStats pStats) {
packageName = pStats.packageName;
userHandle = pStats.userHandle;
codeSize = pStats.codeSize;
dataSize = pStats.dataSize;
cacheSize = pStats.cacheSize;
externalCodeSize = pStats.externalCodeSize;
externalDataSize = pStats.externalDataSize;
externalCacheSize = pStats.externalCacheSize;
externalMediaSize = pStats.externalMediaSize;
externalObbSize = pStats.externalObbSize;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int parcelableFlags){
dest.writeString(packageName);
dest.writeInt(userHandle);
dest.writeLong(codeSize);
dest.writeLong(dataSize);
dest.writeLong(cacheSize);
dest.writeLong(externalCodeSize);
dest.writeLong(externalDataSize);
dest.writeLong(externalCacheSize);
dest.writeLong(externalMediaSize);
dest.writeLong(externalObbSize);
}
}
//deleteApplicationCacheFiles
这是都是隐藏的,不能直接调用,,需要用到反射
/**
* Attempts to delete the cache files associated with an application.
* Since this may take a little while, the result will
* be posted back to the given observer. A deletion will fail if the calling context
* lacks the {@link android.Manifest.permission#DELETE_CACHE_FILES} permission, if the
* named package cannot be found, or if the named package is a "system package".
*
* @param packageName The name of the package to delete
* @param observer An observer callback to get notified when the cache file deletion
* is complete.
* {@link android.content.pm.IPackageDataObserver#onRemoveCompleted(String, boolean)}
* will be called when that happens. observer may be null to indicate that
* no callback is desired.
*
* @hide
*/
public abstract void deleteApplicationCacheFiles(String packageName,
IPackageDataObserver observer);
清理缓存有几种方法:
1.清除本地上的缓存,通过跌代找到要删除的文件和文件夹,删除就行
2.让用户自己清理,直接跳到设置页面:
Intent intent = new Intent();
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:"+你的包名);
startActivity(intent);
3.使用系统的方法来清理缓存:
//先获取到当前应用有没有缓存,并保存它的图标,包名等信息
private void getCache(final String packageName) {
Method[] methods = PackageManager.class.getDeclaredMethods();
for (Method method : methods) {
if ("getPackageSizeInfo".equals(method.getName())) {
try {
method.invoke(pm, packageName,new IPackageStatsObserver.Stub() {
@Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)throws RemoteException {
long cacheSize = pStats.cacheSize;
// System.out.println("缓存大小" + cacheSize);
if (cacheSize > 0) {
// 有缓存
cacheInfo = new AppCacheinfo();
cacheInfo.size = cacheSize;
//System.out.println(cacheInfo.count);
cacheInfo.appPackName = packageName;
try {
cacheInfo.appIcon = pm.getApplicationInfo(packageName, 0).loadIcon(pm);
cacheInfo.appName = pm.getApplicationInfo(packageName, 0).loadLabel(pm).toString();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//开始清理缓存
//pm.deleteApplicationCacheFiles(info.packName, new ClearCacheObserver());
// Method[] methods = PackageManager.class.getMethods();
// for(Method method:methods){
// if("deleteApplicationCacheFiles".equals(method.getName())){
// try {
// method.invoke(pm, info.packName,new ClearCacheObserver());
// Toast.makeText(getActivity(), "清理成功", 0).show();
// } catch (Exception e) {
// e.printStackTrace();
// Toast.makeText(getActivity(), "清理失败", 0).show();
// }
// return;
// }
// }
也可以这样
让应用申请一个很大的内存的空间.
//告知服务器,我们要申请一个很大的内存空间
Method[] methods = PackageManager.class.getDeclaredMethods();
for(Method method:methods){
if("freeStorageAndNotify".equals(method.getName())){
try {
method.invoke(pm, Long.MAX_VALUE,new IPackageDataObserver.Stub(){
@Override
public void onRemoveCompleted(String packageName,
boolean succeeded) throws RemoteException {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}