Android 获取缓存大小和清除缓存功能 前言

前言

我们常常会看到某某APP中会有清除APP浏览时产生的缓存清理功能,今天闲来无事也试试实现这功能,虽然说第三方的清理工具可以帮你清理,但是如果你的手机物理内存比较小的话你还会安装第三方软件么?虽然现在三四百的安卓手机内存都比较大了,但是提高用户体验APP自身带一个清理缓存的功能还是有必要的。

看一下效果图:

我们来考虑一个问题我们应用内的缓存数据存放在哪里?

我们的应用程序一般会产生以下几种类型的数据:

file-普通的文件存储

database-数据库文件(.db文件)

sharedPreference-配置数据(.xml文件)

cache-图片缓存文件


应用内数据的所有路径:

/data/data/com.xxx.xxx/cache - 应用内缓存(注:对应方法getCacheDir())

/data/data/com.xxx.xxx/databases - 应用内数据库

/data/data/com.xxx.xxx/shared_prefs - 应用内配置文件

/data/data/com.xxx.xxx/files - 应用内文件(注:对应方法getFilesDir())

提供一个工具类:

  1. package com.example.androidclearcache;
  2. import java.io.File;
  3. import java.math.BigDecimal;
  4. import android.content.Context;
  5. import android.os.Environment;
  6. import android.text.TextUtils;
  7. /** * 本应用数据清除管理器 */
  8. public class DataCleanManager {
  9. /**
  10. * * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * *
  11. *
  12. * @param context
  13. */
  14. public static void cleanInternalCache(Context context) {
  15. deleteFilesByDirectory(context.getCacheDir());
  16. }
  17. /**
  18. * * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * *
  19. *
  20. * @param context
  21. */
  22. public static void cleanDatabases(Context context) {
  23. deleteFilesByDirectory( new File( "/data/data/" + context.getPackageName() + "/databases"));
  24. }
  25. /**
  26. * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) *
  27. *
  28. * @param context
  29. */
  30. public static void cleanSharedPreference(Context context) {
  31. deleteFilesByDirectory( new File( "/data/data/" + context.getPackageName() + "/shared_prefs"));
  32. }
  33. /**
  34. * * 按名字清除本应用数据库 * *
  35. *
  36. * @param context
  37. * @param dbName
  38. */
  39. public static void cleanDatabaseByName(Context context, String dbName) {
  40. context.deleteDatabase(dbName);
  41. }
  42. /**
  43. * * 清除/data/data/com.xxx.xxx/files下的内容 * *
  44. *
  45. * @param context
  46. */
  47. public static void cleanFiles(Context context) {
  48. deleteFilesByDirectory(context.getFilesDir());
  49. }
  50. /**
  51. * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache)
  52. *
  53. * @param context
  54. */
  55. public static void cleanExternalCache(Context context) {
  56. if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
  57. deleteFilesByDirectory(context.getExternalCacheDir());
  58. }
  59. }
  60. /**
  61. * * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * *
  62. *
  63. * @param filePath
  64. */
  65. public static void cleanCustomCache(String filePath) {
  66. deleteFilesByDirectory( new File(filePath));
  67. }
  68. /**
  69. * * 清除本应用所有的数据 * *
  70. *
  71. * @param context
  72. * @param filepath
  73. */
  74. public static void cleanApplicationData(Context context, String... filepath) {
  75. cleanInternalCache(context);
  76. cleanExternalCache(context);
  77. cleanDatabases(context);
  78. cleanSharedPreference(context);
  79. cleanFiles(context);
  80. if (filepath == null) {
  81. return;
  82. }
  83. for (String filePath : filepath) {
  84. cleanCustomCache(filePath);
  85. }
  86. }
  87. /**
  88. * * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * *
  89. *
  90. * @param directory
  91. */
  92. private static void deleteFilesByDirectory(File directory) {
  93. if (directory != null && directory.exists() && directory.isDirectory()) {
  94. for (File item : directory.listFiles()) {
  95. item.delete();
  96. }
  97. }
  98. }
  99. // 获取文件
  100. // Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/
  101. // 目录,一般放一些长时间保存的数据
  102. // Context.getExternalCacheDir() -->
  103. // SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
  104. public static long getFolderSize(File file) throws Exception {
  105. long size = 0;
  106. try {
  107. File[] fileList = file.listFiles();
  108. for ( int i = 0; i < fileList.length; i++) {
  109. // 如果下面还有文件
  110. if (fileList[i].isDirectory()) {
  111. size = size + getFolderSize(fileList[i]);
  112. } else {
  113. size = size + fileList[i].length();
  114. }
  115. }
  116. } catch (Exception e) {
  117. e.printStackTrace();
  118. }
  119. return size;
  120. }
  121. /**
  122. * 删除指定目录下文件及目录
  123. *
  124. * @param deleteThisPath
  125. * @param filepath
  126. * @return
  127. */
  128. public static void deleteFolderFile(String filePath, boolean deleteThisPath) {
  129. if (!TextUtils.isEmpty(filePath)) {
  130. try {
  131. File file = new File(filePath);
  132. if (file.isDirectory()) { // 如果下面还有文件
  133. File files[] = file.listFiles();
  134. for ( int i = 0; i < files.length; i++) {
  135. deleteFolderFile(files[i].getAbsolutePath(), true);
  136. }
  137. }
  138. if (deleteThisPath) {
  139. if (!file.isDirectory()) { // 如果是文件,删除
  140. file.delete();
  141. } else { // 目录
  142. if (file.listFiles().length == 0) { // 目录下没有文件或者目录,删除
  143. file.delete();
  144. }
  145. }
  146. }
  147. } catch (Exception e) {
  148. // TODO Auto-generated catch block
  149. e.printStackTrace();
  150. }
  151. }
  152. }
  153. /**
  154. * 格式化单位
  155. *
  156. * @param size
  157. * @return
  158. */
  159. public static String getFormatSize(double size) {
  160. double kiloByte = size / 1024;
  161. double megaByte = kiloByte / 1024;
  162. if (megaByte < 1) {
  163. BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
  164. return result1.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
  165. }
  166. double gigaByte = megaByte / 1024;
  167. if (gigaByte < 1) {
  168. BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
  169. return result2.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
  170. }
  171. double teraBytes = gigaByte / 1024;
  172. if (teraBytes < 1) {
  173. BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
  174. return result3.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
  175. }
  176. BigDecimal result4 = new BigDecimal(teraBytes);
  177. return result4.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
  178. }
  179. public static String getCacheSize(File file) throws Exception {
  180. return getFormatSize(getFolderSize(file));
  181. }
  182. }

完整demo代码:

  1. package com.example.androidclearcache;
  2. import android.os.Bundle;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.view.animation.Animation;
  9. import android.view.animation.AnimationUtils;
  10. import android.widget.ImageView;
  11. import android.widget.LinearLayout;
  12. import android.widget.TextView;
  13. import java.io.File;
  14. import android.app.Activity;
  15. import android.app.Dialog;
  16. import android.content.Context;
  17. public class MainActivity extends Activity implements OnClickListener {
  18. public LinearLayout layout;
  19. public TextView tv_cashe;
  20. private Dialog dialog;
  21. private Handler handler = new Handler() {
  22. public void handleMessage(android.os.Message msg) {
  23. switch (msg.what) {
  24. case 0x01:
  25. dialog.dismiss();
  26. tv_cashe.setText( "0.0KB");
  27. break;
  28. case 0x02:
  29. dialog.dismiss();
  30. break;
  31. }
  32. };
  33. };
  34. @Override
  35. protected void onCreate(Bundle savedInstanceState) {
  36. super.onCreate(savedInstanceState);
  37. setContentView(R.layout.activity_main);
  38. layout = (LinearLayout) findViewById(R.id.layout);
  39. tv_cashe=(TextView) findViewById(R.id.textView2);
  40. //获得应用内部缓存(/data/data/com.example.androidclearcache/cache)
  41. File file = new File( this.getCacheDir().getPath());
  42. try {
  43. tv_cashe.setText(DataCleanManager.getCacheSize(file));
  44. } catch (Exception e) {
  45. e.printStackTrace();
  46. }
  47. layout.setOnClickListener( this);
  48. }
  49. @Override
  50. public void onClick(View v) {
  51. switch (v.getId()) {
  52. case R.id.layout:
  53. Message msg = new Message();
  54. dialog = createLoadingDialog(MainActivity. this, "清理中....");
  55. dialog.show();
  56. try {
  57. DataCleanManager.cleanInternalCache(getApplicationContext());
  58. msg.what = 0x01;
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. msg.what = 0x02;
  62. }
  63. handler.sendMessageDelayed(msg, 1000);
  64. break;
  65. default:
  66. break;
  67. }
  68. }
  69. // 自定义的清理对话框
  70. public static Dialog createLoadingDialog(Context context, String msg) {
  71. LayoutInflater inflater = LayoutInflater.from(context);
  72. View v = inflater.inflate(R.layout.loading_dialog, null); // 得到加载view
  73. LinearLayout layout = (LinearLayout) v.findViewById(R.id.dialog_view); // 加载布局
  74. // main.xml中的ImageView
  75. ImageView spaceshipImage = (ImageView) v.findViewById(R.id.dialog_img);
  76. TextView tipTextView = (TextView) v.findViewById(R.id.tipTextView); // 提示文字
  77. // 加载动画
  78. Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(context, R.anim.load_animation);
  79. // 使用ImageView显示动画
  80. spaceshipImage.startAnimation(hyperspaceJumpAnimation);
  81. tipTextView.setText(msg); // 设置加载信息
  82. Dialog loadingDialog = new Dialog(context, R.style.loading_dialog); // 创建自定义样式dialog
  83. loadingDialog.setCancelable( true); // 不可以用“返回键”取消
  84. loadingDialog.setCanceledOnTouchOutside( false);
  85. loadingDialog.setContentView(layout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
  86. LinearLayout.LayoutParams.FILL_PARENT)); // 设置布局
  87. return loadingDialog;
  88. }
  89. }

测试效果中因为不是网页浏览所以cashe缓存比较小,楼主使用RE文件管理器往cashe中导入了一个30M的文件用来展示效果


文章参考地址:http://blog.csdn.net/wwj_748/article/details/42737607


附上demo下载地址:http://download.csdn.net/detail/qq_31546677/9906229
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_31546677/article/details/75635492
文章标签: 缓存

我们常常会看到某某APP中会有清除APP浏览时产生的缓存清理功能,今天闲来无事也试试实现这功能,虽然说第三方的清理工具可以帮你清理,但是如果你的手机物理内存比较小的话你还会安装第三方软件么?虽然现在三四百的安卓手机内存都比较大了,但是提高用户体验APP自身带一个清理缓存的功能还是有必要的。

看一下效果图:

我们来考虑一个问题我们应用内的缓存数据存放在哪里?

我们的应用程序一般会产生以下几种类型的数据:

file-普通的文件存储

database-数据库文件(.db文件)

sharedPreference-配置数据(.xml文件)

cache-图片缓存文件


应用内数据的所有路径:

/data/data/com.xxx.xxx/cache - 应用内缓存(注:对应方法getCacheDir())

/data/data/com.xxx.xxx/databases - 应用内数据库

/data/data/com.xxx.xxx/shared_prefs - 应用内配置文件

/data/data/com.xxx.xxx/files - 应用内文件(注:对应方法getFilesDir())

提供一个工具类:

  1. package com.example.androidclearcache;
  2. import java.io.File;
  3. import java.math.BigDecimal;
  4. import android.content.Context;
  5. import android.os.Environment;
  6. import android.text.TextUtils;
  7. /** * 本应用数据清除管理器 */
  8. public class DataCleanManager {
  9. /**
  10. * * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * *
  11. *
  12. * @param context
  13. */
  14. public static void cleanInternalCache(Context context) {
  15. deleteFilesByDirectory(context.getCacheDir());
  16. }
  17. /**
  18. * * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * *
  19. *
  20. * @param context
  21. */
  22. public static void cleanDatabases(Context context) {
  23. deleteFilesByDirectory( new File( "/data/data/" + context.getPackageName() + "/databases"));
  24. }
  25. /**
  26. * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) *
  27. *
  28. * @param context
  29. */
  30. public static void cleanSharedPreference(Context context) {
  31. deleteFilesByDirectory( new File( "/data/data/" + context.getPackageName() + "/shared_prefs"));
  32. }
  33. /**
  34. * * 按名字清除本应用数据库 * *
  35. *
  36. * @param context
  37. * @param dbName
  38. */
  39. public static void cleanDatabaseByName(Context context, String dbName) {
  40. context.deleteDatabase(dbName);
  41. }
  42. /**
  43. * * 清除/data/data/com.xxx.xxx/files下的内容 * *
  44. *
  45. * @param context
  46. */
  47. public static void cleanFiles(Context context) {
  48. deleteFilesByDirectory(context.getFilesDir());
  49. }
  50. /**
  51. * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache)
  52. *
  53. * @param context
  54. */
  55. public static void cleanExternalCache(Context context) {
  56. if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
  57. deleteFilesByDirectory(context.getExternalCacheDir());
  58. }
  59. }
  60. /**
  61. * * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * *
  62. *
  63. * @param filePath
  64. */
  65. public static void cleanCustomCache(String filePath) {
  66. deleteFilesByDirectory( new File(filePath));
  67. }
  68. /**
  69. * * 清除本应用所有的数据 * *
  70. *
  71. * @param context
  72. * @param filepath
  73. */
  74. public static void cleanApplicationData(Context context, String... filepath) {
  75. cleanInternalCache(context);
  76. cleanExternalCache(context);
  77. cleanDatabases(context);
  78. cleanSharedPreference(context);
  79. cleanFiles(context);
  80. if (filepath == null) {
  81. return;
  82. }
  83. for (String filePath : filepath) {
  84. cleanCustomCache(filePath);
  85. }
  86. }
  87. /**
  88. * * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * *
  89. *
  90. * @param directory
  91. */
  92. private static void deleteFilesByDirectory(File directory) {
  93. if (directory != null && directory.exists() && directory.isDirectory()) {
  94. for (File item : directory.listFiles()) {
  95. item.delete();
  96. }
  97. }
  98. }
  99. // 获取文件
  100. // Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/
  101. // 目录,一般放一些长时间保存的数据
  102. // Context.getExternalCacheDir() -->
  103. // SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据
  104. public static long getFolderSize(File file) throws Exception {
  105. long size = 0;
  106. try {
  107. File[] fileList = file.listFiles();
  108. for ( int i = 0; i < fileList.length; i++) {
  109. // 如果下面还有文件
  110. if (fileList[i].isDirectory()) {
  111. size = size + getFolderSize(fileList[i]);
  112. } else {
  113. size = size + fileList[i].length();
  114. }
  115. }
  116. } catch (Exception e) {
  117. e.printStackTrace();
  118. }
  119. return size;
  120. }
  121. /**
  122. * 删除指定目录下文件及目录
  123. *
  124. * @param deleteThisPath
  125. * @param filepath
  126. * @return
  127. */
  128. public static void deleteFolderFile(String filePath, boolean deleteThisPath) {
  129. if (!TextUtils.isEmpty(filePath)) {
  130. try {
  131. File file = new File(filePath);
  132. if (file.isDirectory()) { // 如果下面还有文件
  133. File files[] = file.listFiles();
  134. for ( int i = 0; i < files.length; i++) {
  135. deleteFolderFile(files[i].getAbsolutePath(), true);
  136. }
  137. }
  138. if (deleteThisPath) {
  139. if (!file.isDirectory()) { // 如果是文件,删除
  140. file.delete();
  141. } else { // 目录
  142. if (file.listFiles().length == 0) { // 目录下没有文件或者目录,删除
  143. file.delete();
  144. }
  145. }
  146. }
  147. } catch (Exception e) {
  148. // TODO Auto-generated catch block
  149. e.printStackTrace();
  150. }
  151. }
  152. }
  153. /**
  154. * 格式化单位
  155. *
  156. * @param size
  157. * @return
  158. */
  159. public static String getFormatSize(double size) {
  160. double kiloByte = size / 1024;
  161. double megaByte = kiloByte / 1024;
  162. if (megaByte < 1) {
  163. BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
  164. return result1.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
  165. }
  166. double gigaByte = megaByte / 1024;
  167. if (gigaByte < 1) {
  168. BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
  169. return result2.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
  170. }
  171. double teraBytes = gigaByte / 1024;
  172. if (teraBytes < 1) {
  173. BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
  174. return result3.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
  175. }
  176. BigDecimal result4 = new BigDecimal(teraBytes);
  177. return result4.setScale( 2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
  178. }
  179. public static String getCacheSize(File file) throws Exception {
  180. return getFormatSize(getFolderSize(file));
  181. }
  182. }

完整demo代码:

  1. package com.example.androidclearcache;
  2. import android.os.Bundle;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.view.animation.Animation;
  9. import android.view.animation.AnimationUtils;
  10. import android.widget.ImageView;
  11. import android.widget.LinearLayout;
  12. import android.widget.TextView;
  13. import java.io.File;
  14. import android.app.Activity;
  15. import android.app.Dialog;
  16. import android.content.Context;
  17. public class MainActivity extends Activity implements OnClickListener {
  18. public LinearLayout layout;
  19. public TextView tv_cashe;
  20. private Dialog dialog;
  21. private Handler handler = new Handler() {
  22. public void handleMessage(android.os.Message msg) {
  23. switch (msg.what) {
  24. case 0x01:
  25. dialog.dismiss();
  26. tv_cashe.setText( "0.0KB");
  27. break;
  28. case 0x02:
  29. dialog.dismiss();
  30. break;
  31. }
  32. };
  33. };
  34. @Override
  35. protected void onCreate(Bundle savedInstanceState) {
  36. super.onCreate(savedInstanceState);
  37. setContentView(R.layout.activity_main);
  38. layout = (LinearLayout) findViewById(R.id.layout);
  39. tv_cashe=(TextView) findViewById(R.id.textView2);
  40. //获得应用内部缓存(/data/data/com.example.androidclearcache/cache)
  41. File file = new File( this.getCacheDir().getPath());
  42. try {
  43. tv_cashe.setText(DataCleanManager.getCacheSize(file));
  44. } catch (Exception e) {
  45. e.printStackTrace();
  46. }
  47. layout.setOnClickListener( this);
  48. }
  49. @Override
  50. public void onClick(View v) {
  51. switch (v.getId()) {
  52. case R.id.layout:
  53. Message msg = new Message();
  54. dialog = createLoadingDialog(MainActivity. this, "清理中....");
  55. dialog.show();
  56. try {
  57. DataCleanManager.cleanInternalCache(getApplicationContext());
  58. msg.what = 0x01;
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. msg.what = 0x02;
  62. }
  63. handler.sendMessageDelayed(msg, 1000);
  64. break;
  65. default:
  66. break;
  67. }
  68. }
  69. // 自定义的清理对话框
  70. public static Dialog createLoadingDialog(Context context, String msg) {
  71. LayoutInflater inflater = LayoutInflater.from(context);
  72. View v = inflater.inflate(R.layout.loading_dialog, null); // 得到加载view
  73. LinearLayout layout = (LinearLayout) v.findViewById(R.id.dialog_view); // 加载布局
  74. // main.xml中的ImageView
  75. ImageView spaceshipImage = (ImageView) v.findViewById(R.id.dialog_img);
  76. TextView tipTextView = (TextView) v.findViewById(R.id.tipTextView); // 提示文字
  77. // 加载动画
  78. Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(context, R.anim.load_animation);
  79. // 使用ImageView显示动画
  80. spaceshipImage.startAnimation(hyperspaceJumpAnimation);
  81. tipTextView.setText(msg); // 设置加载信息
  82. Dialog loadingDialog = new Dialog(context, R.style.loading_dialog); // 创建自定义样式dialog
  83. loadingDialog.setCancelable( true); // 不可以用“返回键”取消
  84. loadingDialog.setCanceledOnTouchOutside( false);
  85. loadingDialog.setContentView(layout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
  86. LinearLayout.LayoutParams.FILL_PARENT)); // 设置布局
  87. return loadingDialog;
  88. }
  89. }

测试效果中因为不是网页浏览所以cashe缓存比较小,楼主使用RE文件管理器往cashe中导入了一个30M的文件用来展示效果


文章参考地址:http://blog.csdn.net/wwj_748/article/details/42737607


附上demo下载地址:http://download.csdn.net/detail/qq_31546677/9906229

猜你喜欢

转载自blog.csdn.net/daimengs/article/details/80926280