1. 程式人生 > >Android實現清除應用程式快取

Android實現清除應用程式快取

我使用的是反射的方法來獲取某個應用程式的快取大小,但是沒能實現通過反射的方法來清除該應用快取,所以我只能呼叫系統的設定意圖來清除快取。而且在真機上沒什麼問題,模擬器上就有些問題了。

1.需要三個AIDL檔案


注意:在新增三個aidl檔案後一定要Rebuild Project一下,否則會報錯。

1.

IPackageDataObserver.aidl 
package android.content.pm;oneway interface IPackageDataObserver {
    void onRemoveCompleted(in String packageName, boolean succeeded);
}
2.
IPackageStatsObserver.aidl
package android.content.pm;
import android.content.pm.PackageStats;
oneway interface IPackageStatsObserver { void onGetStatsCompleted(in PackageStats pStats, boolean succeeded); }

3.

PackageStats.aidl
package android.content.pm;parcelable PackageStats;

需要的許可權:

  <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
  <uses-permission 
android:name="android.permission.CLEAR_APP_CACHE" /> <!-- <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA"/> <uses-permission android:name="android.permission.DELETE_CACHE_FILES"/>-->

主要程式碼:

package zy.just.com.clearcachedemo;

import android.content.Intent;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.text.format.Formatter;
import android.view.View;
import android.widget.EditText;

import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class MainActivity extends AppCompatActivity {

    public static final String ENCODING="UTF-8";//常量,代表編碼格式。
    private EditText et_size;
    private PackageManager packageManager;
    private PackageInfo packageInfo;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        init();
        createCache();
    }

    public void createCache() {
        InputStream in = getResources().openRawResource(R.mipmap.pic_1);
        BufferedInputStream bis = new BufferedInputStream(in);
        try {
            FileOutputStream fos = openFileOutput("pic_1.png", MODE_PRIVATE);
            byte[] buffer=new byte[1024];
            int len = -1;
            while ((len=bis.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
            fos.close();
            bis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void init() {
        packageManager = getPackageManager();
    }

    private void initView() {
        et_size = (EditText) findViewById(R.id.et_size);
    }

    public void clear(View view){

//        Toast.makeText(MainActivity.this,"點選了clear按鈕",0).show();
//        try {
//            Method[] methods = PackageManager.class.getMethods();
//            for(Method m:methods){
//                if("deleteApplicationCacheFiles".equals(m.getName())){
//                    m.invoke(packageManager,packageInfo.packageName,new ClearCacheObserver());
//                }
//                if("deleteApplicationCacheFiles".equals(m.getName())){
//                    m.invoke(packageManager,packageInfo.packageName,new ClearCacheObserver());
//                }
//            }
////            method = PackageManager.class.getDeclaredMethod("clearApplicationUserData",String.class,IPackageDataObserver.class);
////            method.invoke(packageManager,packageInfo.packageName,new ClearCacheObserver());
////            method = PackageManager.class.getDeclaredMethod("deleteApplicationCacheFiles",String.class,IPackageDataObserver.class);
////            method.invoke(packageManager,packageInfo.packageName,new ClearCacheObserver());
//        } catch (InvocationTargetException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }

        Intent intent = new Intent();
        intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        // dat=package:com.itheima.mobileguard
        intent.setData(Uri.parse("package:" + packageInfo.packageName));
        startActivity(intent);

    }

    @Override
    protected void onResume() {
        super.onResume();
        showCacheSize();
    }

    private void showCacheSize(){

        if(packageManager!=null){
            try {
                packageInfo = packageManager.getPackageInfo("zy.just.com.clearcachedemo", 0);
                getCacheSize(packageInfo);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 獲取某個包名對應的應用程式的快取大小
     * @param packageInfo  應用程式的包資訊
     *
     * IPackageStatsObserver.class編譯器報找不到的問題,只需要rebuild一下就行了。
     */
    private void getCacheSize(PackageInfo packageInfo) {

        try {
            //通過反射獲取到當前的方法。
            Method method = PackageManager.class.getDeclaredMethod("getPackageSizeInfo",String.class,IPackageStatsObserver.class);
            /**
             * 第一個引數:呼叫該方法的物件
             * 第二個引數:應用包名
             * 第三個引數:IPackageStatsObserver型別的aidl物件。
             */
            method.invoke(packageManager,packageInfo.packageName,new MyPackObserver(packageInfo));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    private class MyPackObserver extends android.content.pm.IPackageStatsObserver.Stub{

        private PackageInfo info;

        public MyPackObserver(PackageInfo info){
            this.info = info;
        }

        @Override
        public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
            long cacheSize = pStats.cacheSize;
            et_size.setText(Formatter.formatFileSize(getApplicationContext(), cacheSize));
        }
    }

//    class ClearCacheObserver extends IPackageDataObserver.Stub {
//        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
//            getCacheSize(packageInfo);
//        }
//    }
}


相關推薦

Android實現清除應用程式快取

我使用的是反射的方法來獲取某個應用程式的快取大小,但是沒能實現通過反射的方法來清除該應用快取,所以我只能呼叫系統的設定意圖來清除快取。而且在真機上沒什麼問題,模擬器上就有些問題了。 1.需要三個AIDL檔案 注意:在新增三個aidl檔案後一定要Rebuild Proje

記憶體池的設計和實現 -- C++應用程式效能優化

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

關於android 中獲取應用程式的包資訊

 Android系統為我們提供了很多服務管理的類,包括ActivityManager、PowerManager(電源管理)、AudioManager(音訊管理) 等。除此之外,還提供了一個PackageManger管理類,它的主要職責是管理應用程式包。 通過它,我們就可以獲取應用程

Android開發系統應用程式

一、配置清單檔案 在 manifest 標籤裡新增屬性:android:sharedUserId=“android.uid.system” 二、打包apk android studio : Build -> Make Project / Rebuild P

Android Launcher啟動應用程式流程原始碼解析

帶著問題看原始碼 點選桌面Launcher圖示後做了哪些工作? 應用程式什麼時候被建立的? Application和MainActivity的onCreate()方法什麼時候被呼叫的? 概述 在Android系統中,啟動四大元件中的任何一個都可以啟動應用程式。但絕大部分時候我們是通過點選Laun

android 如何保持應用程式存活率

在茫茫大海中,尋求應用程式存活率解決方案,一般都是啟動服務,儲存活率,也有的是在AndroidManifest.xml中新增屬性,比如: <application android:name="*******" android:allow

從零開始學 Web 之 HTML5(三)網路監聽,全屏,檔案讀取,地理定位介面,應用程式快取

一、網路監聽介面 ononline:網路連通時觸發 onoffline:網路斷開時觸發 window.addEventListener("online", function(){}); window.addEventListener("offline", function(){}); 二、全屏介面 全

Android 重啟應用程式 的兩種方式

/** * 重新啟動App -> 殺程序,會短暫黑屏,啟動慢 */ public void restartApp() { //啟動頁

HTML5 應用程式快取--manifest

HTML5 引入了應用程式快取,這意味著 web 應用可進行快取,並可在沒有因特網連線時進行訪問。 應用程式快取為應用帶來三個優勢: - 離線瀏覽 - 使用者可在應用離線時使用它們 - 速度 - 已快取資源載入得更快 - 減少伺服器負載 - 瀏覽器

android——徹底關閉——應用程式

最近學習做android的遊戲開發時候,發現一個關於android退出時不能徹底關閉的問題,比如:一個程式裡new 出了N多個Thread,這樣在退出程式的可能不能完全關閉,最後發現,只用finish()方法,有時候不能徹底退出,個人感覺還是要在適當的地方加上:Syste

HTML5應用程式快取(Application Cache)

最近做專案的時候,需要將web頁面快取到本地,經過調查,決定使用HTML5的應用程式快取功能。 使用HTML5,通過建立 manifest 檔案,可以輕鬆地建立 web 應用的離線版本。 請注意,根據MDN文件,該特性已經從 Web 標準中刪除。推薦使用Se

Android Studio修改應用程式的包名PackName

問題: 修改了一下包名,發現依據包名getPackageName()創建出來的資料夾還是原來的包名 分析: 只在AndroidManifest修改了 package的值,結果是不行的 還需要在b

html5 web應用程式快取

話說到web應用程式快取,這個東西,我覺得挺有用的。以前,個人看到網頁版的美圖秀秀,而自己的電腦本地也安裝了美圖秀秀,就覺得這兩者沒必要在網頁版上也實現吧。不過,後來覺得,還是網頁版的方便多了,因為不需要自己安裝程式啊,至少自己的電腦裡面不會因多一個應用程式,而很亂。但是,

安卓開發之清理手機應用程式快取

清理手機應用程式快取。    拿到模組後,先實現UI介面。介面實現後開始思考整個模組要實現的功能,然後是要使用的API。    第一步:先拿到包管理器    PackageManager pm=getPackageManager();    第二步:利用包管理器拿到所有安裝

Android M PackageManager應用程式許可權管理原始碼剖析及runtime permission實戰

Android應用許可權授予部分主要分為兩部分,第一部分是在PKMS啟動之後,且掃描完所有的app後,會對應用程式分配linux使用者組ID,即授予他們所申請的資源訪問許可權。 第一部分主要是對install等許可權進行無條件授予,而許多核心app的預設許可權則還沒有授

基於.NET goshiney框架實現應用程式

goshiney框架從2013年中期開始伴隨著農信通公共解決方案專案“偷偷”開搞,後面由於專案中止、個人離職等原因,一度被丟棄在硬碟...為了養家餬口,目前不得不暫時放下專業研究,利用這些程式碼定製一些資訊系統,也算使其產生了一定的用途... 隨著多個橫向專案的應用,整個框

SpringSecurity 禁用使用者後 實現清除指定使用者快取

問題出現的場景: 一般在類似於資訊管理平臺,通常會有對使用者的狀態進行操作,我遇到的問題是,當管理員使用者,禁用普通使用者後,普通使用者仍然可以登入。 出現的原因: SpringSecurity在使用者登陸訪問系統過程中,會將使用者的登陸資訊儲存到ca

清理應用程式快取

1、獲取應用程式快取資訊 2、清理快取(也可以不用步驟1,直接清理,步驟1只是為了知道哪些程式有快取) 1) Method getPackageSizeInfo = pm.getClass().getMethod("getPackageSizeInfo", String.c

Android應用開發】-(18)靜默方式實現批量安裝解除安裝應用程式

     前段時間做了一個批量安裝解除安裝應用程式的小應用,由於安裝解除安裝應用程式的部分API是隱藏的,所以必須在ubuntu下下載Android系統原始碼,並編譯之後使用MM命令編譯生成APK檔案,其實也難。思路是這樣的,在XX/packages/apps目錄下有一個Pa

Android實現退出整個應用程式程式碼;

工作上需要實現雙擊退出應用程式的效果,在網上看到有什麼System.exit(0);,執行下來,然而這並不能實現退出應用程式,而只是退出當前activity;和finish效果差不多; 後來有一種思路就是,每開啟一個activity,就把當前activity儲存在一個Li