編輯:關於Android編程
目前,市場上很多Android手機軟件都具有清理SD卡緩存的功能,比如360,金山等等。那麼這些軟件是如何實現清理sd卡緩存數據功能的呢?下面,我就給大家演示下,這些功能是如何實現的吧。
首先我們還是講一下這個功能實現的原理吧。
將Android手機中常用的一些應用緩存目錄,全部放在一個數據庫表中,將這個表中的目錄查詢出來放在一個List集合中,我們暫且將這個list集合定義為paths,之後我們去換獲取到sd卡中所有的文件目錄,遍歷sdk下所有的文件目錄,如果paths中包含某一個目錄,則遞歸刪除這個目錄文件。
原理又啰嗦完了,很簡單吧,那就讓我們一起來實現這些功能吧。
實現分為兩個步驟,數據庫的准備和代碼實現
這個示例中用到了一個存放應用緩存目錄的數據庫clearpath.db,首先將這個數據庫放置在應用程序項目的assets目錄下
如圖:
在這個示例中,我將這個功能代碼都分成一個個方法寫在了MainActivity中,我們主要分析一下這個類中的每個方法就可以了。
這個方法實現的功能是將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; }
這個方法實現的功能是調用copyDb方法拷貝數據庫,並獲取數據庫文件對象,查詢數據庫中存放的所有的文件目錄,並將這些目錄封裝到一個list集合中返回。
具體代碼實現如下:
/** * 獲取數據庫中要清理的文件目錄集合 * @return */ private ListgetPaths(){ //復制數據庫 List list = new ArrayList (); 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; }
這個方法主要實現了遞歸刪除文件的操作,首先遍歷文件目錄,如果當前文件是目錄,則遍歷子目錄,繼續調用自身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(); } }
我們定義一個全局list集合paths,並在oncreate方法中調用getPaths方法,給這個集合賦值。這樣這個集合中封裝了數據庫中所有的文件路徑。之所以我們將paths定義為全局變量,並在oncreate方法中調用getPaths方法為其賦值,是為了提高性能。因為從數據庫中讀取數據是一個耗費性能的操作,這個方法只在onCreate中執行一次,避免了在點擊事件中每點擊按鈕一次,就執行一次。這樣明顯提高了應用程序的性能。
具體實現代碼如下:
private Listpaths; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); paths = this.getPaths(); }
這個方法主要是響應了按鈕的點擊事件,實現清理緩存的功能,在這裡我們將清理功能放到一個子線程中執行,通過Looper機制來提醒用戶清理完成。
具體代碼實現如下:
//按鈕點擊事件 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(); }
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 Listpaths; @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; } //按鈕點擊事件 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 getPaths(){ //復制數據庫 List list = new ArrayList (); 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; } }
這個布局很簡單,我們就是放置了一個按鈕。
具體實現代碼如下:
這裡,我們要清除sd卡中的數據,所有要對寫sd卡進行授權,我們在AndroidManifest.xml文件中添加如下授權信息
簡介這是一個基於AlertDialog和Dialog這兩個類封裝的多種彈出框樣式,其中提供各種簡單樣式的彈出框使用說明。同時也可自定義彈出框。項目地址:http://ww
在B站或者其他視頻網站看視頻時,常常會打開彈幕效果,邊看節目邊看大家的吐槽。彈幕看起來很有意思,今天我們就來實現一個簡單的彈幕效果。 從直觀上,彈幕效果就是在一
Android本身自帶的SQLite,大家一定都用過,然而在使用它時,我們往往需要做許多額外的工作,像編寫 SQL 語句與解析查詢結果等。所以,適用於 Android 的
現在Android的開發者基本上都使用Android Studio進行開發(如果你還在使用eclipse那也行,畢竟你樂意怎麼樣都行)。使用好Android Studio