Android應(yīng)用在運(yùn)行之中會(huì)產(chǎn)生一些數(shù)據(jù)坐漏,比如圖片的緩存歇僧,數(shù)據(jù)庫(kù)文件,配置文件等等垫挨。我們開發(fā)時(shí)可能會(huì)有這樣的一個(gè)需求清除應(yīng)用內(nèi)緩存的數(shù)據(jù)韩肝,可以讓用戶選擇刪除應(yīng)用內(nèi)產(chǎn)生的數(shù)據(jù),這也是比較人性化的設(shè)計(jì)點(diǎn)九榔。過(guò)多的緩存會(huì)占用手機(jī)的存儲(chǔ)空間哀峻,據(jù)說(shuō)也會(huì)降低手機(jī)的IO性能。 下面這是簡(jiǎn)書Android APP中提供了清除緩存的設(shè)計(jì):
那么Android應(yīng)用在運(yùn)行中會(huì)產(chǎn)生哪些數(shù)據(jù)呢哲泊?它們都被存放在哪里剩蟀?然后我們根據(jù)產(chǎn)生數(shù)據(jù)的位置實(shí)現(xiàn)清除功能
首先簡(jiǎn)單講講Android的四種數(shù)據(jù)存儲(chǔ)方式
1、SharePreference:
一種輕型的數(shù)據(jù)存儲(chǔ)方式切威,實(shí)際上是基于XML文件存儲(chǔ)的“key-value”鍵值對(duì)數(shù)據(jù)育特;通常用來(lái)存儲(chǔ)程序的一些配置信息。
SharePreference的存儲(chǔ)目錄:
其存儲(chǔ)在“data/data/程序包名/shared_prefs目錄下先朦。
SharePreference修改和存儲(chǔ)數(shù)據(jù)
- 根據(jù)Context的getSharedPrerences(key, [模式])方法獲取SharedPreference對(duì)象缰冤;
- 利用SharedPreference的editor()方法獲取Editor對(duì)象;
- 通過(guò)Editor的putXXX()方法喳魏,將鍵值對(duì)存儲(chǔ)數(shù)據(jù)棉浸;
- 通過(guò)Editor的commit()方法將數(shù)據(jù)提交到SharedPreference內(nèi)
2、SQLite
SQLite是一個(gè)輕量級(jí)關(guān)系型數(shù)據(jù)庫(kù)刺彩,既然是關(guān)系型數(shù)據(jù)庫(kù)迷郑,那操作起來(lái)其實(shí)跟mysql枝恋、sql server差不多的。
Android提供了強(qiáng)大數(shù)據(jù)庫(kù)管理庫(kù)嗡害,同時(shí)也支持運(yùn)行哦原生命令鼓择,實(shí)現(xiàn)數(shù)據(jù)庫(kù)的增刪改查
3、 File
Android中可以在設(shè)備本身的存儲(chǔ)設(shè)備或外接的存儲(chǔ)設(shè)備中創(chuàng)建用于保存數(shù)據(jù)的文件就漾。在默認(rèn)狀態(tài)下呐能,文件是不能在不同程序間共享的。
File可以通過(guò)FileInputStream和FileOutputStream對(duì)文件進(jìn)行操作抑堡。
4摆出、ContentProvider
ContentProvider相對(duì)于其它的方式比較復(fù)雜,當(dāng)然其功能相對(duì)于其它的方式也是革命性的改變首妖。它能夠?qū)崿F(xiàn)跨應(yīng)用之間的數(shù)據(jù)操作偎漫。利用ContentResolver對(duì)象的delete、update有缆、insert象踊、query等方法去操ContentProvider的對(duì)象,讓ContentProvider對(duì)象的方法去對(duì)數(shù)據(jù)操作杯矩。
實(shí)現(xiàn)方式為:
- 在A程序中定義一個(gè)ContentProvider,重載其增刪查改等方法袖外;
- 在A程序中的AndroidManifest.xml中注冊(cè)ContentProvider史隆;
- 在B程序中通過(guò)ContentResolver和Uri來(lái)獲取ContentProvider的數(shù)據(jù),同樣利用Resolver的增刪查改方法來(lái)獲得和處理數(shù)據(jù)
Android應(yīng)用的數(shù)據(jù)存儲(chǔ)路徑
應(yīng)用內(nèi)數(shù)據(jù)的所有路徑和對(duì)應(yīng)的數(shù)據(jù)清除代碼:
- /data/data/com.xxx.xxx/cache - 應(yīng)用內(nèi)緩存(注:對(duì)應(yīng)方法**getCacheDir() **)
public static void cleanInternalCache(Context context) {
deleteFilesByDirectory(context.getCacheDir());
}
- /data/data/com.xxx.xxx/databases - 應(yīng)用內(nèi)數(shù)據(jù)庫(kù)
public static void cleanDatabases(Context context) {
deleteFilesByDirectory(new File("/data/data/"
+ context.getPackageName() + "/databases"));
}
- /data/data/com.xxx.xxx/shared_prefs - 應(yīng)用內(nèi)配置文件
public static void cleanSharedPreference(Context context) {
deleteFilesByDirectory(new File("/data/data/"
+ context.getPackageName() + "/shared_prefs"));
}
- /data/data/com.xxx.xxx/files - 應(yīng)用內(nèi)文件(注:對(duì)應(yīng)方法getFilesDir())
public static void cleanFiles(Context context) {
deleteFilesByDirectory(context.getFilesDir());
}
由于Android應(yīng)用數(shù)據(jù)存儲(chǔ)的權(quán)限比較寬泛曼验,一個(gè)Android應(yīng)用幾乎可以在SD卡任意位置創(chuàng)建一個(gè)目錄和文件泌射,所以上面的幾個(gè)存儲(chǔ)路徑只是Android應(yīng)用最基本的存儲(chǔ)路徑。更多的清除代碼實(shí)現(xiàn)在下面的清除工具類中將于更詳細(xì)的講解
清除工具類的代碼實(shí)現(xiàn)
為了方便使用鬓照,下面時(shí)我封裝好的數(shù)據(jù)清除工具類:
package cn.wangbaiyuan.utils;
/**
* Created by BrainWang on 2017-02-21.
*/
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import android.content.Context;
import android.os.Environment;
/**
* 清除緩存
*
*/
public class CleanDataUtil {
/** * 清除本應(yīng)用內(nèi)部緩存(/data/data/com.xxx.xxx/cache) * * @param context */
public static void cleanInternalCache(Context context) {
deleteFilesByDirectory(context.getCacheDir());
}
/** * 清除本應(yīng)用所有數(shù)據(jù)庫(kù)(/data/data/com.xxx.xxx/databases) * * @param context */
public static void cleanDatabases(Context context) {
deleteFilesByDirectory(new File("/data/data/"
+ context.getPackageName() + "/databases"));
}
/**
* * 清除本應(yīng)用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * @param
* context
*/
public static void cleanSharedPreference(Context context) {
deleteFilesByDirectory(new File("/data/data/"
+ context.getPackageName() + "/shared_prefs"));
}
/** * 按名字清除本應(yīng)用數(shù)據(jù)庫(kù) * * @param context * @param dbName */
public static void cleanDatabaseByName(Context context, String dbName) {
context.deleteDatabase(dbName);
}
/** * 清除/data/data/com.xxx.xxx/files下的內(nèi)容 * * @param context */
public static void cleanFiles(Context context) {
deleteFilesByDirectory(context.getFilesDir());
}
/**
* * 清除外部cache下的內(nèi)容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param
* context
*/
public static void cleanExternalCache(Context context) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
deleteFilesByDirectory(context.getExternalCacheDir());
}
}
/** * 清除自定義路徑下的文件熔酷,使用需小心,請(qǐng)不要誤刪豺裆。而且只支持目錄下的文件刪除 * * @param filePath */
public static void cleanCustomCache(String filePath) {
deleteFilesByDirectory(new File(filePath));
}
/** * 清除本應(yīng)用所有的數(shù)據(jù) * * @param context * @param filepath */
public static void cleanApplicationData(Context context, String... filepath) {
cleanInternalCache(context);
cleanExternalCache(context);
cleanDatabases(context);
cleanSharedPreference(context);
cleanFiles(context);
for (String filePath : filepath) {
cleanCustomCache(filePath);
}
}
/** * 刪除方法 這里只會(huì)刪除某個(gè)文件夾下的文件拒秘,如果傳入的directory是個(gè)文件,將不做處理 * * @param directory */
private static void deleteFilesByDirectory(File directory) {
if (directory != null && directory.exists() && directory.isDirectory()) {
for (File item : directory.listFiles()) {
item.delete();
}
}
}
/**
* 清除所有緩存留储,相當(dāng)于設(shè)置里應(yīng)用管理中的“清除數(shù)據(jù)”翼抠,清除數(shù)據(jù)時(shí)應(yīng)用將會(huì)退出
* @param context
*/
public static void clearAppUserData(Context context) {
try {
Runtime.getRuntime().exec("pm clear " + context.getPackageName());
} catch (IOException e) {
e.printStackTrace();
}
}
}
系統(tǒng)設(shè)置應(yīng)用管理的”清除數(shù)據(jù)“的實(shí)現(xiàn)方法
在Android系統(tǒng)設(shè)置的應(yīng)用管理中,提供了”清除數(shù)據(jù)“的功能获讳,這一功能對(duì)應(yīng)用數(shù)據(jù)的清除更加徹底,我們可以在代碼中實(shí)現(xiàn)類似的需求活喊,不過(guò)下面代碼的執(zhí)行將使應(yīng)用退出:
/**
* 清除所有緩存丐膝,相當(dāng)于設(shè)置里應(yīng)用管理中的“清除數(shù)據(jù)”,清除數(shù)據(jù)時(shí)應(yīng)用將會(huì)退出
* @param context
*/
public static void clearAppUserData(Context context) {
try {
Runtime.getRuntime().exec("pm clear " + context.getPackageName());
} catch (IOException e) {
e.printStackTrace();
}
}
碼字辛苦,歡迎客官打賞