[mobilesafe] 03_缓存清理的原理

Android 4.0

缓存获取清理的原理

1、获取缓存大小getPackageInfoSize() /*@hide*/
2、onGetStatsCompleted()是在子线程中执行,直接更新ui会报错
要么用handler+message,要么用runOnUiThread()
PackageManager  中隐藏的方法:
 * @hide
     */
    public abstract void getPackageSizeInfo(String packageName,
            IPackageStatsObserver observer);

PackageManager 默认的实现类ApplicationPackageManager

private final IPackageManager mPM; 
ApplicationPackageManager(ContextImpl context,
                              IPackageManager pm) {
        mContext = context;
        mPM = pm;
    }
IPackageManager.aidl
权限:
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />  
问题:

获取缓存:
利用反射,来获取底层隐藏的api
获取缓存,代码,数据大小
package cn.zengfansheng.getCacheSize;
 
import java.lang.reflect.Method;
 
import android.app.Activity;
import android.content.Context;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.format.Formatter;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
 
public class MainActivity extends Activity {
 
    private EditText et_package;
    private TextView tv_cache;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        et_package = (EditText) this.findViewById(R.id.et_package);
        tv_cache = (TextView) this.findViewById(R.id.tv_cache);
    }
 
    public void getCache(View view) {
 
        // ApplicationPackageManager ap;//隐藏的类
        PackageManager pm = this.getPackageManager();
        /*
         PackageManager隐藏的api
         @hide
         public abstract void getPackageSizeInfo(String packageName,
            IPackageStatsObserver observer);
         */

        try {
            String packageName = et_package.getText().toString();
            Method method = PackageManager.class.getMethod("getPackageSizeInfo", String.class,IPackageStatsObserver.class);
 
            method.invoke(pm, packageName, new MyIPackageStatsbserver());
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    private class MyIPackageStatsbserver extends IPackageStatsObserver.Stub {
 
        // onGetStatsCompleted在另外的一个线程获取的数据. 所以不能直接更新ui
        @Override
        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded)
                throws RemoteException {
            long cacheSize = pStats.cacheSize;
            long codeSize = pStats.codeSize;
            long dataSize = pStats.dataSize;
            Context context = getApplicationContext();
            String cache = Formatter.formatFileSize(getApplicationContext(), cacheSize);
            String code = Formatter.formatFileSize(getApplicationContext(), codeSize);
            String data = Formatter.formatFileSize(context, dataSize);
            System.out.println("缓存大小:" + cache + "代码大小:" + code + "数据大小:"+ data);
            tv_cache.setText("缓存大小:"+cache+"代码大小:"+code+"数据大小:"+data);
        }
    }
}
结果: