转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47375595
眼下,市场上非常多Android手机软件都具有清理SD卡缓存的功能,比方360。金山等等。那么这些软件是怎样实现清理sd卡缓存数据功能的呢?以下,我就给大家演示下。这些功能是怎样实现的吧。
一、原理
首先我们还是讲一下这个功能实现的原理吧。
将Android手机中经常使用的一些应用缓存文件夹。全部放在一个数据库表中。将这个表中的文件夹查询出来放在一个List集合中,我们暂且将这个list集合定义为paths,之后我们去换获取到sd卡中全部的文件文件夹。遍历sdk下全部的文件文件夹。假设paths中包括某一个文件夹,则递归删除这个文件夹文件。
原理又啰嗦完了,非常easy吧,那就让我们一起来实现这些功能吧。
二、实现
实现分为两个步骤,数据库的准备和代码实现
1、数据库准备
这个演示样例中用到了一个存放应用缓存文件夹的数据库clearpath.db。首先将这个数据库放置在应用程序项目的assets文件夹下
如图:
2、代码实现
在这个演示样例中,我将这个功能代码都分成一个个方法写在了MainActivity中,我们主要分析一下这个类中的每一个方法就能够了。
1)拷贝数据库的方法copyDb
这种方法实现的功能是将assets文件夹下的数据库复制到/data/data/应用程序包名/files文件夹下。同一时候返回数据库文件对象。
详细实现代码例如以下:
/** * 拷贝数据库。并返回数据库文件对象 * @return */ private File copyDb(){ //将数据库复制到files文件夹 File file = new File(getFilesDir(), "clearpath.db"); if(!file.exists()){ try { InputStream in = getAssets().open("clearpath.db"); OutputStream out = new FileOutputStream(file); byte[] buffer = new byte[1024]; int len = 0; while((len = in.read(buffer)) != -1){ out.write(buffer, 0, len); } out.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } } return file; }
2)获取数据库中要清理的文件文件夹集合的方法getPaths
这种方法实现的功能是调用copyDb方法拷贝数据库,并获取数据库文件对象,查询数据库中存放的全部的文件文件夹,并将这些文件夹封装到一个list集合中返回。
详细代码实现例如以下:
/** * 获取数据库中要清理的文件文件夹集合 * @return */ private List<String> getPaths(){ //复制数据库 List<String >list = new ArrayList<String>(); File file = copyDb(); if(file != null){ SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY); if(db.isOpen()){ Cursor c = db.query("softdetail", new String[]{"filepath"}, null, null, null, null, null); while(c.moveToNext()){ String path = c.getString(c.getColumnIndex("filepath")); list.add(path); } c.close(); db.close(); } } return list; }
3)递归删除文件delete
这种方法主要实现了递归删除文件的操作,首先遍历文件文件夹,假设当前文件是文件夹,则遍历子文件夹,继续调用自身delete方法,假设是文件。则调用File的delete方法。
详细实现代码例如以下:
/** * 递归删除文件 * @param file */ private void delete(File file){ if(file.isDirectory()){ File[] files = file.listFiles(); for(File f : files){ delete(f); } }else{ file.delete(); } }
4)获取文件集合paths
我们定义一个全局list集合paths,并在oncreate方法中调用getPaths方法,给这个集合赋值。这样这个集合中封装了数据库中全部的文件路径。
之所以我们将paths定义为全局变量。并在oncreate方法中调用getPaths方法为其赋值,是为了提高性能。由于从数据库中读取数据是一个耗费性能的操作,这种方法仅仅在onCreate中运行一次。避免了在点击事件中每点击button一次。就运行一次。这样明显提高了应用程序的性能。
详细实现代码例如以下:
private List<String> paths; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); paths = this.getPaths(); }
5)button点击事件clearData
这种方法主要是响应了button的点击事件。实现清理缓存的功能,在这里我们将清理功能放到一个子线程中运行,通过Looper机制来提醒用户清理完毕。
详细代码实现例如以下:
//button点击事件 public void clearData(View v){ new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()); File[] files = file.listFiles(); if(files != null && files.length > 0){ for(File f : files){ String name = "/" + f.getName(); //paths集合中包括name if(paths.contains(name)){ delete(f); } } } Looper.prepare(); Toast.makeText(MainActivity.this, "SD卡缓存清理完毕", Toast.LENGTH_SHORT).show(); Looper.loop(); } }).start(); }
6)MainActivity总体实现代码
package com.lyz.test.cache; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.os.Environment; import android.os.Looper; import android.view.Menu; import android.view.View; import android.widget.Toast; /** * 主程序入口 * @author liuyazhuang * */ public class MainActivity extends Activity { private List<String> paths; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); paths = this.getPaths(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } //button点击事件 public void clearData(View v){ new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()); File[] files = file.listFiles(); if(files != null && files.length > 0){ for(File f : files){ String name = "/" + f.getName(); //paths集合中包括name if(paths.contains(name)){ delete(f); } } } Looper.prepare(); Toast.makeText(MainActivity.this, "SD卡缓存清理完毕", Toast.LENGTH_SHORT).show(); Looper.loop(); } }).start(); } /** * 递归删除文件 * @param file */ private void delete(File file){ if(file.isDirectory()){ File[] files = file.listFiles(); for(File f : files){ delete(f); } }else{ file.delete(); } } /** * 拷贝数据库,并返回数据库文件对象 * @return */ private File copyDb(){ //将数据库复制到files文件夹 File file = new File(getFilesDir(), "clearpath.db"); if(!file.exists()){ try { InputStream in = getAssets().open("clearpath.db"); OutputStream out = new FileOutputStream(file); byte[] buffer = new byte[1024]; int len = 0; while((len = in.read(buffer)) != -1){ out.write(buffer, 0, len); } out.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } } return file; } /** * 获取数据库中要清理的文件文件夹集合 * @return */ private List<String> getPaths(){ //复制数据库 List<String >list = new ArrayList<String>(); File file = copyDb(); if(file != null){ SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY); if(db.isOpen()){ Cursor c = db.query("softdetail", new String[]{"filepath"}, null, null, null, null, null); while(c.moveToNext()){ String path = c.getString(c.getColumnIndex("filepath")); list.add(path); } c.close(); db.close(); } } return list; } }
7)布局文件activity_main
这个布局非常easy,我们就是放置了一个button。
详细实现代码例如以下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="clearData" android:text="清理SD卡数据" /> </RelativeLayout>
3、应用授权
这里,我们要清除sd卡中的数据,全部要对写sd卡进行授权。我们在AndroidManifest.xml文件里加入例如以下授权信息
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <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程序猿最主要的开发常识和规范。我在这里仅仅是为了方便直接写在了类和布局文件里。