如何以编程方式计算已安装应用程序的所有缓存大小?

时间:2015-02-09 10:38:37

标签: android caching memory-management

我只想显示所有已安装的应用程序名称列表以及缓存大小。缓存大小必须与Android设备中显示的本机设置应用程序相同。

我能够列出所有已安装的应用程序pkg名称,但无法计算本机设置应用程序显示的相同高速缓存大小(我在谈论设置中清除高速缓存选项的位置)。

pkNames = getPackageManager().getInstalledPackages(0);

                    ArrayAdapter<PackageInfo> adapter = new ArrayAdapter<PackageInfo>(this,
                            android.R.layout.simple_list_item_1, pkNames);
                     final PackageManager pm = getPackageManager();
                    for(int i =0;i<pkNames.size();i++)
                    {
                        ApplicationInfo applicationInfo = pm.getApplicationInfo(pkNames.get(i).packageName.toString(), 0);
                        File file = new File(applicationInfo.publicSourceDir);
                        long size = file.length();
                        System.out.println("application name == "+pkNames.get(i).packageName.toString()+"  ,and size of cache is == "+size(this, size));
                    } 

我使用此代码,但它会给我该应用程序的.apk大小。 :( 请帮忙 提前谢谢。

2 个答案:

答案 0 :(得分:12)

直接获取已安装应用程序的缓存大小,无法获取。 使用PackageManger时,我们无法直接获取有关已安装包大小的详细信息,因为抽象getPackageSizeInfo方法无法直接访问,因此使用Java Reflection可以调用它。如果将来可能无效方法名称更改或任何更改的内容。

您需要创建AIDL IPackageStatsObserver。aidl&amp; PackageStats.aidl应该在android.content.pm包中,因为您无法直接访问它们。

<强> IPackageStatsObserver.aidl

package android.content.pm;
import android.content.pm.PackageStats;
oneway interface IPackageStatsObserver {
void onGetStatsCompleted(in android.content.pm.PackageStats pStats, boolean succeeded);
}

<强> PackageStats.aidl

package android.content.pm;
parcelable PackageStats;

IPackageStatsObserver.aidl&amp; PackageStats.aidl都将它保存在android.content.pm包中。 的 IDataStatus

public interface IDataStatus {
    public void onStatusListner(String msg);
}

<强>活动

    public class MyScreen extends Activity implements OnClickListener {
    public static final int FETCH_PACKAGE_SIZE_COMPLETED = 100;
    public static final int ALL_PACAGE_SIZE_COMPLETED = 200;
    IDataStatus onIDataStatus;
    TextView lbl_cache_size;
    ProgressDialog pd;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.btn_get_cacheSize).setOnClickListener(this);
        lbl_cache_size = (TextView) findViewById(R.id.lbl_cache_size);
        // clearCache();
    }

    private void showProgress(String message) {
        pd = new ProgressDialog(this);
        pd.setIcon(R.drawable.ic_launcher);
        pd.setTitle("Please Wait...");
        pd.setMessage(message);
        pd.setCancelable(false);
        pd.show();

    }

    long packageSize = 0, size = 0;
    AppDetails cAppDetails;
    public ArrayList<PackageInfoStruct> res;

    private void getpackageSize() {
        cAppDetails = new AppDetails(this);
        res = cAppDetails.getPackages();
        if (res == null)
            return;
        for (int m = 0; m < res.size(); m++) {
            PackageManager pm = getPackageManager();
            Method getPackageSizeInfo;
            try {
                getPackageSizeInfo = pm.getClass().getMethod(
                        "getPackageSizeInfo", String.class,
                        IPackageStatsObserver.class);
                getPackageSizeInfo.invoke(pm, res.get(m).pname,
                        new cachePackState());
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }

        }
        handle.sendEmptyMessage(ALL_PACAGE_SIZE_COMPLETED);
        Log.v("Total Cache Size", " " + packageSize);

    }

    private Handler handle = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case FETCH_PACKAGE_SIZE_COMPLETED:
                if (packageSize > 0)
                    size = (packageSize / 1024000);
                lbl_cache_size.setText("Cache Size : " + size + " MB");
                break;
            case ALL_PACAGE_SIZE_COMPLETED:
                if (null != pd)
                    if (pd.isShowing())
                        pd.dismiss();

                break;
            default:
                break;
            }

        }

    };

    private class cachePackState extends IPackageStatsObserver.Stub {

        @Override
        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
                throws RemoteException {
            Log.d("Package Size", pStats.packageName + "");
            Log.i("Cache Size", pStats.cacheSize + "");
            Log.w("Data Size", pStats.dataSize + "");
            packageSize = packageSize + pStats.cacheSize;
            Log.v("Total Cache Size", " " + packageSize);
            handle.sendEmptyMessage(FETCH_PACKAGE_SIZE_COMPLETED);
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btn_get_cacheSize:
            size = 0;
            packageSize = 0;
            showProgress("Calculating Cache Size..!!!");
            /**
             * You can also use async task
             * */
            new Thread(new Runnable() {

                @Override
                public void run() {
                    getpackageSize();
                }
            }).start();

            break;
        }
    }

}

<强> AppDetails

public class AppDetails {
    Activity mActivity;
    public ArrayList<PackageInfoStruct> res = new ArrayList<PackageInfoStruct>();
    public ListView list;
    public String app_labels[];

    public AppDetails(Activity mActivity) {
        this.mActivity = mActivity;

    }

    public ArrayList<PackageInfoStruct> getPackages() {
        ArrayList<PackageInfoStruct> apps = getInstalledApps(false); /*
                                                                     * false =
                                                                     * no system
                                                                     * packages
                                                                     */
        final int max = apps.size();
        for (int i = 0; i < max; i++) {
            apps.get(i);
        }
        return apps;
    }

    private ArrayList<PackageInfoStruct> getInstalledApps(boolean getSysPackages) {

        List<PackageInfo> packs = mActivity.getPackageManager()
                .getInstalledPackages(0);
        try {
            app_labels = new String[packs.size()];
        } catch (Exception e) {
            Toast.makeText(mActivity.getApplicationContext(), e.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }
        for (int i = 0; i < packs.size(); i++) {
            PackageInfo p = packs.get(i);
            if ((!getSysPackages) && (p.versionName == null)) {
                continue;
            }
            PackageInfoStruct newInfo = new PackageInfoStruct();
            newInfo.appname = p.applicationInfo.loadLabel(
                    mActivity.getPackageManager()).toString();
            newInfo.pname = p.packageName;
            newInfo.datadir = p.applicationInfo.dataDir;
            newInfo.versionName = p.versionName;
            newInfo.versionCode = p.versionCode;
            newInfo.icon = p.applicationInfo.loadIcon(mActivity
                    .getPackageManager());
            res.add(newInfo);

            app_labels[i] = newInfo.appname;
        }
        return res;
    }

    class PackageInfoStruct {
        String appname = "";
        String pname = "";
        String versionName = "";
        int versionCode = 0;
        Drawable icon;
        String datadir = "";
    }
}

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

  <Button
        android:id="@+id/btn_get_cacheSize"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Get Cache Size" />

    <TextView
        android:id="@+id/lbl_cache_size"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Cache Size : " />

</LinearLayout>

答案 1 :(得分:1)

使用以下路径将应用程序缓存文件夹放入内存

“/数据/数据/ com.your.package.appname /缓存”

计算磁盘上的应用程序缓存大小。