Android之——清理手机SD卡缓存

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47375595

目前,市场上很多Android手机软件都具有清理SD卡缓存的功能,比如360,金山等等。那么这些软件是如何实现清理sd卡缓存数据功能的呢?下面,我就给大家演示下,这些功能是如何实现的吧。

一、原理

首先我们还是讲一下这个功能实现的原理吧。

将Android手机中常用的一些应用缓存目录,全部放在一个数据库表中,将这个表中的目录查询出来放在一个List集合中,我们暂且将这个list集合定义为paths,之后我们去换获取到sd卡中所有的文件目录,遍历sdk下所有的文件目录,如果paths中包含某一个目录,则递归删除这个目录文件。

原理又啰嗦完了,很简单吧,那就让我们一起来实现这些功能吧。

二、实现

实现分为两个步骤,数据库的准备和代码实现

1、数据库准备

这个示例中用到了一个存放应用缓存目录的数据库clearpath.db,首先将这个数据库放置在应用程序项目的assets目录下

如图:

2、代码实现

在这个示例中,我将这个功能代码都分成一个个方法写在了MainActivity中,我们主要分析一下这个类中的每个方法就可以了。

1)拷贝数据库的方法copyDb

这个方法实现的功能是将assets目录下的数据库拷贝到/data/data/应用程序包名/files目录下,同时返回数据库文件对象。

具体实现代码如下:

[java]  view plain  copy
  1. /** 
  2.  * 拷贝数据库,并返回数据库文件对象 
  3.  * @return 
  4.  */  
  5. private File copyDb(){  
  6.     //将数据库拷贝到files目录  
  7.     File file = new File(getFilesDir(), "clearpath.db");  
  8.     if(!file.exists()){  
  9.         try {  
  10.             InputStream in = getAssets().open("clearpath.db");  
  11.             OutputStream out = new FileOutputStream(file);  
  12.             byte[] buffer = new byte[1024];  
  13.             int len = 0;  
  14.             while((len = in.read(buffer)) != -1){  
  15.                 out.write(buffer, 0, len);  
  16.             }  
  17.             out.close();  
  18.             in.close();  
  19.         } catch (Exception e) {  
  20.             e.printStackTrace();  
  21.         }  
  22.     }  
  23.     return file;  
  24. }  

2)获取数据库中要清理的文件目录集合的方法getPaths

这个方法实现的功能是调用copyDb方法拷贝数据库,并获取数据库文件对象,查询数据库中存放的所有的文件目录,并将这些目录封装到一个list集合中返回。

具体代码实现如下:

[java]  view plain  copy
  1. /** 
  2.  * 获取数据库中要清理的文件目录集合 
  3.  * @return 
  4.  */  
  5. private List<String> getPaths(){  
  6.     //复制数据库  
  7.     List<String >list = new ArrayList<String>();  
  8.     File file = copyDb();  
  9.     if(file != null){  
  10.         SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);  
  11.         if(db.isOpen()){  
  12.             Cursor c = db.query("softdetail"new String[]{"filepath"}, nullnullnullnullnull);  
  13.             while(c.moveToNext()){  
  14.                 String path = c.getString(c.getColumnIndex("filepath"));  
  15.                 list.add(path);  
  16.             }  
  17.             c.close();  
  18.             db.close();  
  19.         }  
  20.     }  
  21.     return list;  
  22. }  

3)递归删除文件delete

这个方法主要实现了递归删除文件的操作,首先遍历文件目录,如果当前文件是目录,则遍历子目录,继续调用自身delete方法,如果是文件,则调用File的delete方法。

具体实现代码如下:

[java]  view plain  copy
  1. /** 
  2.  * 递归删除文件 
  3.  * @param file 
  4.  */  
  5. private void delete(File file){  
  6.     if(file.isDirectory()){  
  7.         File[] files = file.listFiles();  
  8.         for(File f : files){  
  9.             delete(f);  
  10.         }  
  11.     }else{  
  12.         file.delete();  
  13.     }  
  14. }  

4)获取文件集合paths

我们定义一个全局list集合paths,并在oncreate方法中调用getPaths方法,给这个集合赋值。这样这个集合中封装了数据库中所有的文件路径。之所以我们将paths定义为全局变量,并在oncreate方法中调用getPaths方法为其赋值,是为了提高性能。因为从数据库中读取数据是一个耗费性能的操作,这个方法只在onCreate中执行一次,避免了在点击事件中每点击按钮一次,就执行一次。这样明显提高了应用程序的性能。

具体实现代码如下:

[java]  view plain  copy
  1. private List<String> paths;  
  2. @Override  
  3. protected void onCreate(Bundle savedInstanceState) {  
  4.     super.onCreate(savedInstanceState);  
  5.     setContentView(R.layout.activity_main);  
  6.     paths = this.getPaths();  
  7. }  

5)按钮点击事件clearData

这个方法主要是响应了按钮的点击事件,实现清理缓存的功能,在这里我们将清理功能放到一个子线程中执行,通过Looper机制来提醒用户清理完成。

具体代码实现如下:

[java]  view plain  copy
  1. //按钮点击事件  
  2. public void clearData(View v){  
  3.     new Thread(new Runnable() {  
  4.         @Override  
  5.         public void run() {  
  6.             // TODO Auto-generated method stub  
  7.             File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath());  
  8.             File[] files = file.listFiles();  
  9.             if(files != null && files.length > 0){  
  10.                 for(File f : files){  
  11.                     String name = "/" + f.getName();  
  12.                     //paths集合中包含name  
  13.                     if(paths.contains(name)){  
  14.                         delete(f);  
  15.                     }  
  16.                 }  
  17.             }  
  18.             Looper.prepare();  
  19.             Toast.makeText(MainActivity.this"SD卡缓存清理完成", Toast.LENGTH_SHORT).show();  
  20.             Looper.loop();  
  21.         }  
  22.     }).start();  
  23. }  

6)MainActivity整体实现代码

[java]  view plain  copy
  1. package com.lyz.test.cache;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.InputStream;  
  6. import java.io.OutputStream;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. import android.app.Activity;  
  11. import android.database.Cursor;  
  12. import android.database.sqlite.SQLiteDatabase;  
  13. import android.os.Bundle;  
  14. import android.os.Environment;  
  15. import android.os.Looper;  
  16. import android.view.Menu;  
  17. import android.view.View;  
  18. import android.widget.Toast;  
  19.   
  20. /** 
  21.  * 主程序入口 
  22.  * @author liuyazhuang 
  23.  * 
  24.  */  
  25. public class MainActivity extends Activity {  
  26.   
  27.   
  28.     private List<String> paths;  
  29.   
  30.     @Override  
  31.     protected void onCreate(Bundle savedInstanceState) {  
  32.         super.onCreate(savedInstanceState);  
  33.         setContentView(R.layout.activity_main);  
  34.         paths = this.getPaths();  
  35.     }  
  36.   
  37.     @Override  
  38.     public boolean onCreateOptionsMenu(Menu menu) {  
  39.         // Inflate the menu; this adds items to the action bar if it is present.  
  40.         getMenuInflater().inflate(R.menu.main, menu);  
  41.         return true;  
  42.     }  
  43.       
  44.     //按钮点击事件  
  45.     public void clearData(View v){  
  46.         new Thread(new Runnable() {  
  47.             @Override  
  48.             public void run() {  
  49.                 // TODO Auto-generated method stub  
  50.                 File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath());  
  51.                 File[] files = file.listFiles();  
  52.                 if(files != null && files.length > 0){  
  53.                     for(File f : files){  
  54.                         String name = "/" + f.getName();  
  55.                         //paths集合中包含name  
  56.                         if(paths.contains(name)){  
  57.                             delete(f);  
  58.                         }  
  59.                     }  
  60.                 }  
  61.                 Looper.prepare();  
  62.                 Toast.makeText(MainActivity.this"SD卡缓存清理完成", Toast.LENGTH_SHORT).show();  
  63.                 Looper.loop();  
  64.             }  
  65.         }).start();  
  66.     }  
  67.       
  68.     /** 
  69.      * 递归删除文件 
  70.      * @param file 
  71.      */  
  72.     private void delete(File file){  
  73.         if(file.isDirectory()){  
  74.             File[] files = file.listFiles();  
  75.             for(File f : files){  
  76.                 delete(f);  
  77.             }  
  78.         }else{  
  79.             file.delete();  
  80.         }  
  81.     }  
  82.       
  83.     /** 
  84.      * 拷贝数据库,并返回数据库文件对象 
  85.      * @return 
  86.      */  
  87.     private File copyDb(){  
  88.         //将数据库拷贝到files目录  
  89.         File file = new File(getFilesDir(), "clearpath.db");  
  90.         if(!file.exists()){  
  91.             try {  
  92.                 InputStream in = getAssets().open("clearpath.db");  
  93.                 OutputStream out = new FileOutputStream(file);  
  94.                 byte[] buffer = new byte[1024];  
  95.                 int len = 0;  
  96.                 while((len = in.read(buffer)) != -1){  
  97.                     out.write(buffer, 0, len);  
  98.                 }  
  99.                 out.close();  
  100.                 in.close();  
  101.             } catch (Exception e) {  
  102.                 e.printStackTrace();  
  103.             }  
  104.         }  
  105.         return file;  
  106.     }  
  107.       
  108.     /** 
  109.      * 获取数据库中要清理的文件目录集合 
  110.      * @return 
  111.      */  
  112.     private List<String> getPaths(){  
  113.         //复制数据库  
  114.         List<String >list = new ArrayList<String>();  
  115.         File file = copyDb();  
  116.         if(file != null){  
  117.             SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);  
  118.             if(db.isOpen()){  
  119.                 Cursor c = db.query("softdetail"new String[]{"filepath"}, nullnullnullnullnull);  
  120.                 while(c.moveToNext()){  
  121.                     String path = c.getString(c.getColumnIndex("filepath"));  
  122.                     list.add(path);  
  123.                 }  
  124.                 c.close();  
  125.                 db.close();  
  126.             }  
  127.         }  
  128.         return list;  
  129.     }  
  130. }  

7)布局文件activity_main

这个布局很简单,我们就是放置了一个按钮。

具体实现代码如下:

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context=".MainActivity" >  
  10.   
  11.     <Button  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="wrap_content"  
  14.         android:onClick="clearData"  
  15.         android:text="清理SD卡数据" />  
  16.   
  17. </RelativeLayout>  

3、应用授权

这里,我们要清除sd卡中的数据,所有要对写sd卡进行授权,我们在AndroidManifest.xml文件中添加如下授权信息

[html]  view plain  copy
  1. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

三、运行效果

四、温馨提示

大家可以到链接http://download.csdn.net/detail/l1028386804/8980767下载Android清理SD卡缓存数据库文件,可以到链接http://download.csdn.net/detail/l1028386804/8980789下载Android清理SD卡缓存完整示例源代码

本实例中,为了方面,我把一些文字直接写在了布局文件中和相关的类中,大家在真实的项目中要把这些文字写在string.xml文件中,在外部引用这些资源,切记,这是作为一个Android程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l1028386804/article/details/47375595

猜你喜欢

转载自blog.csdn.net/zhang1223665986/article/details/80709104