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


    转载请注明出处: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程序猿最主要的开发常识和规范。我在这里仅仅是为了方便直接写在了类和布局文件里。

  • 相关阅读:
    超时检测
    非阻塞IO
    阻塞IO
    IO的概念
    http_server实例代码
    套接字中的recv与send的注意事项
    tcp流式套接字和udp数据报套接字编程区别
    TCP的粘包
    socket创建UDP服务端和客户端
    面向连接与面向非连接的传输服务区别
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6839940.html
Copyright © 2020-2023  润新知