日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【android】音乐播放器之数据存储总结

發(fā)布時間:2024/3/24 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【android】音乐播放器之数据存储总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
學習Android有一個多月,看完了《第一行代碼》以及mars老師的第一期視頻通過音樂播放器小項目加深對知識點的理解。從本文開始,將詳細的介紹簡單仿多米音樂播放器的實現(xiàn),以及網(wǎng)絡(luò)解析數(shù)據(jù)獲取百度音樂最新排行音樂以及下載功能。

? ? ? ??功能介紹如下:?? ?

? ? ? ??1、獲取本地歌曲列表,實現(xiàn)歌曲播放功能。?
? ? ? ? 2、利用jsoup解析網(wǎng)頁數(shù)據(jù),從網(wǎng)絡(luò)獲取歌曲列表,同時實現(xiàn)歌曲和歌詞下載到手機本地的功能。?
? ? ? ? 3、通知欄提醒,實現(xiàn)仿QQ音樂播放器的通知欄功能.?
? ? ?

? ? ???涉及的技術(shù)有:?
? ? ? ?1、jsoup解析網(wǎng)絡(luò)網(wǎng)頁,從而獲取需要的數(shù)據(jù)?
? ? ? ?2、android中訪問網(wǎng)絡(luò),獲取文件到本地的網(wǎng)絡(luò)請求技術(shù),以及下載文件到本地實現(xiàn)斷點下載?
? ? ? ?3、線程池?
? ? ? ?4、圖片緩存?
? ? ? ?5、service一直在后臺運行?
? ? ? ?6、Activity與Fragment間的切換以及通信?
? ? ? ?7、notification通知欄設(shè)計?
? ? ? ?8、自定義廣播?
? ? ? ?9、android系統(tǒng)文件管

? ? ? ?音樂播放器思路及源碼下載見:【android】音樂播放器之設(shè)計思路

? ? ? 這篇文章主要來談?wù)刟ndroid數(shù)據(jù)存儲以及音樂播放器用到的一些存儲技術(shù)和緩存技術(shù)。當然小編也還是會順帶擴展下音樂播放器用到的其他方方面面的知識如果可能的話~!~!!!哈哈哈。先來總結(jié)寫目前android目前主要的5中數(shù)據(jù)存儲方式吧。

數(shù)據(jù)存儲方式

Android 的數(shù)據(jù)存儲有5種方式:

1. SharedPreferences存儲數(shù)據(jù)?
   SharedPreferences數(shù)據(jù)存儲,也叫作xml存儲。這是將數(shù)據(jù)存儲“data/data/程序包名/share_prefs”路徑下的到xml文件中。 ??
2. 文件存儲數(shù)據(jù)?
   分為內(nèi)部儲存和外部存儲。內(nèi)部存儲是應(yīng)用程序使用Android為自己分配的內(nèi)存空間,數(shù)據(jù)存儲到“/data/data/程序包名/files”路徑下的相應(yīng)文件中。外部存儲是使用手機sdcard的內(nèi)存(這個sdcard并不是我們經(jīng)常說的那個可以拆卸替換的SD卡,那個SD卡我們稱之為擴展卡),使用這部分內(nèi)存要聲明相應(yīng)的權(quán)限。?
3. SQLite數(shù)據(jù)庫存儲數(shù)據(jù)?
  使用數(shù)據(jù)庫進行存儲,這個一般數(shù)據(jù)量比較大的時候。 ??
4. 使用ContentProvider存儲數(shù)據(jù)?
  這個比較眼熟,ContentProvider也是Android的四大組件之一。ContentProvider一般是第三方提供的數(shù)據(jù)存儲方式,向我們手機中的通訊錄聯(lián)系人,照片,音樂等……?
5. 網(wǎng)絡(luò)存儲數(shù)據(jù)?
   這個是將數(shù)據(jù)上傳到網(wǎng)絡(luò)上進行存儲。?

? ? ?下面就具體的看看每種存儲方式,先看看sharepreferences存儲技術(shù):

SharedPreferences存儲數(shù)據(jù)

SharedPreferences是一種輕型的數(shù)據(jù)存儲方式,實際上是基于XML文件存儲的“key-value”鍵值對數(shù)據(jù)。通常用來存儲程序的一些配置信息。其存儲在“data/data/程序包名/shared_prefs“目錄下。?
  ?
使用SharedPreferences來存儲數(shù)據(jù)首相我們要獲得SharedPreferences的對象。

獲得SharedPreferences的對象

  獲得SharedPreferences對象的方法有三種:?
(1)通過Context的getSharedPrerences(key, [模式])方法獲取SharedPreferences對象;方法的第一個參數(shù)是用于指定SharedPreferences文件的名稱,第二個參數(shù)是指定操作模式,主要有兩種模式進行選擇:MODE_PRIVATE,?MODE_MULTI_PROCESS。默認操作是MODE_PRIVATE。除此之外還有MODE_EORLD_READEABLE,MODE_WORLD_WRITEABLE兩種。?
(2)通過Activity類提供的getPrerences(key)方法獲取到SharedPreferences對象;該方法會創(chuàng)建一個以當前活動類名作為SharedPreferences文件名的文件。?
(3)通過PreferencesManager類中的getDefaultPreferernces()方法獲得;這是一個靜態(tài)的方法,他接受一個Context參數(shù),并將當前應(yīng)用程序的包名作為SharedPreferences文件名。

下面我們來看一下如何使用SharedPreferences讀寫數(shù)據(jù)……

寫數(shù)據(jù)

步驟:

(1)根據(jù)Context的getSharedPrerences(key, [模式])方法獲取SharedPreferences對象;?
(2)利用SharedPreferences的editor()方法獲取Editor對象;?
(3)通過Editor的putXXX()方法,將鍵值對存儲數(shù)據(jù);?
(4)通過Editor的commit()方法將數(shù)據(jù)提交到SharedPreferences內(nèi)。

讀數(shù)據(jù)

步驟:

(1)根據(jù)Context的getSharedPrerences(key, [模式])方法獲取SharedPreference對象;?
(2)通過SharedPreference對象的getXXX方法獲得數(shù)據(jù)。例如:getString(String s, String s1)方法有兩個位參數(shù),第一個s為要獲得的值的鍵,第二個s1為如果鍵值不存在返回的默認的String類型的值。

文件存儲數(shù)據(jù)

  文件存儲是Android中最基本的一種存儲方式,他不對存儲的內(nèi)容進行任何格式化的處理,所有的數(shù)據(jù)都是原封不動的保存在文件中的,因此他比較適合于存儲一些簡單的二進制數(shù)據(jù)或文本數(shù)據(jù)。?
  文件存儲也分兩種:內(nèi)部存儲和外部存儲。?

內(nèi)部存儲

  指Android為應(yīng)用程序分配的內(nèi)存。?
通過Context類中封裝好的輸入流和輸出流的獲取方法獲得數(shù)據(jù)/data/data//files目錄下存儲的數(shù)據(jù)。

files目錄下寫數(shù)據(jù)

  通過Context的封裝好的方法?openFileOutput(String filename, int mode)獲得數(shù)據(jù)流:?
? ? ? ?String filename參數(shù):在/data/data//files目錄下存儲時的文件名。?
? ? ? ?int mode參數(shù):文件的操作模式,主要有兩種模式可選擇:MODE_PRIVATE,?MODE_APPEND。默認為MODE_PRIVATE,當指定相同文件名進行讀寫的時候,新的內(nèi)容會覆蓋原有內(nèi)容;MODE_APPEND模式會在已存在的文件的最后追加新的內(nèi)容。(還得多嘮叨嘮叨~!~)除此之外有兩種模式:MODE_WORLD_READABLEMODE_WORLD_WRITEABLE,這兩種模式表示允許其他應(yīng)用程序?qū)ξ覀兊某绦蛭募M行讀寫操作。

files目錄下讀數(shù)據(jù)

   通過Context的封裝好的方法?openFileInput(String filename)獲得數(shù)據(jù)流:?

? ? ? ? ? ?String filename參數(shù):在/data/data//files目錄下讀取時的文件名。

外部存儲

? ? ? ? ? 對于多數(shù)情況下每個用戶都有自己的努力存儲空間,應(yīng)用僅對當前用戶的外部存儲空間有訪問權(quán)限:WRITE_EXTERNAL_STORAGE為對外部存儲空間的寫權(quán)限;READ_EXTERNAL_STORAGE為對外部存儲空間的寫權(quán)限;這些都需要在AndroidManifest.fex文件夾中聲明。

? ? ? ? ?READ_EXTERNAL_STORAGE:用于獲取主要的外部存儲目錄,當然這個目錄當前很有可能不能訪問,這就需要通過狀態(tài)判斷getExternalStorageState?

? ? ? ? ?getExternalStorageState:可以被用于獲取當前的狀態(tài);

? ? ? ? ?getExternalFileDir:返回的是應(yīng)用所在的目錄,當應(yīng)用被卸載后系統(tǒng)清理的就是這個目錄

? ? ? ? ?getExternalCacheDir:用于返回應(yīng)用外部的緩存目錄

SQLite數(shù)據(jù)庫存儲數(shù)據(jù)

? ? ? ?SQLite是一個輕量級關(guān)系型數(shù)據(jù)庫,既然是關(guān)系型數(shù)據(jù)庫,那操作起來其實跟mysql、sql server差不多的。?
? ? ? ?SQLite 和其他數(shù)據(jù)庫最大的不同就是對數(shù)據(jù)類型的支持,創(chuàng)建一個表時,可以在 CREATE TABLE 語句中指定某列的數(shù)據(jù)類型,但是你可以把任何數(shù)據(jù)類型放入任何列中。當某個值插入數(shù)據(jù)庫時,SQLite 將檢查它的類型。如果該類型與關(guān)聯(lián)的列不匹配,則 SQLite 會嘗試將該值轉(zhuǎn)換成該列的類型。如果不能轉(zhuǎn)換,則該值將作為其本身具有的類型存儲。比如可以把一個字符串(String)放入 INTEGER 列。SQLite 稱這為“弱類型”(manifest typing.)。?
  對數(shù)據(jù)庫SQLite進行操作,我們要借助于SQLiteOpenHelper類進行操作。對數(shù)據(jù)庫的操作也就是”增、刪、改、查“。在學習數(shù)據(jù)庫的操作之前我們首先要學會如何創(chuàng)建數(shù)據(jù)庫……

創(chuàng)建數(shù)據(jù)庫

  數(shù)據(jù)庫的操作借助于SQLiteOpenHelper,SQLiteOpenHelper是一個抽象類,我們我們在使用SQLiteOpenHelper時要先創(chuàng)建一個MySQLiteOpenHelper繼承SQLiteOpenHelper類。?
  SQLiteOpenHelper有兩個非常重要的方法:getReadableDatabase()方法返回數(shù)據(jù)庫是一個只讀的;getWriteableDatabase()方法獲得是一個可讀寫的數(shù)據(jù)庫對象。這里我們使用getWriteableDatabase()方法獲得數(shù)據(jù)庫Database對象。?

添加數(shù)據(jù)

  使用SQLiteDatabase的insert(String table, String nullColumnHack, ContentValues values)方法插入數(shù)據(jù)。這個方法包含三個參數(shù):?
  我們先列舉一條SQLite中的插入語句:INSERT INTO user (name, passwords)] VALUES ("張三", "123456");?
String table:操作的數(shù)據(jù)表的名稱。?
String nullColumnHack:用于我們在未指定添加數(shù)據(jù)的情況下,為數(shù)據(jù)表中可以添加null值的數(shù)據(jù)填入null值。一般這個參數(shù)我們傳入null。?
ContentValues values:用于傳遞數(shù)據(jù),通常我們通過ContentValues 類的對象的putXXX()方法封裝數(shù)據(jù),然后將數(shù)據(jù)添加進數(shù)據(jù)庫。?
  ContentValues 類,類似于java中的Map,以鍵值對的方式保存數(shù)據(jù)。

刪除數(shù)據(jù)

  使用SQLiteDatabase的delete(String table, String whereClause, String[] whereArgs)方法刪除數(shù)據(jù)。這個方法包含三個參數(shù):?
  我們先列舉一條SQLite中的刪除語句:DELETE FROM user WHERE name="張三"。?
String table:操作的數(shù)據(jù)表的名稱。?
String whereClause:約束刪除行的條件。相當于SQLite語句中“where name=?“內(nèi)容。?
String[] whereArgs:與前一個參數(shù)對應(yīng)約束刪除行的條件。相當于”where name=”張三““中的”張三“。?
注意:如果參數(shù)String whereClause和參數(shù)String[] whereArgs都傳null的話,就是刪除所有行。

修改數(shù)據(jù)

  使用SQLiteDatabase的 update (String table, ContentValues values, String whereClause, String[] whereArgs)方法刪除數(shù)據(jù)。這個方法包含四個參數(shù):?
  我們先列舉一條SQLite中的修改語句:UPDATE user SET name= "李四", passwords= "123" WHERE name="張三"。?
String table:操作的數(shù)據(jù)表的名稱。?
ContentValues values:用于傳遞數(shù)據(jù),通常我們通過ContentValues 類的對象的putXXX()方法封裝數(shù)據(jù),然后將數(shù)據(jù)添加進數(shù)據(jù)庫。?
String whereClause:約束修改行的條件。相當于SQLite語句中“where name=?“內(nèi)容。?
String[] whereArgs:與前一個參數(shù)對應(yīng)約束刪除行的條件。相當于”where name=”張三““中的”張三“。

查詢數(shù)據(jù)

  對于”查“操作,SQLiteDatabase提供了多種方法。?
  我們先列舉一條SQLite中的修改語句:SELECT passwords="123" FROM user。?
(1)使用SQL語句進行查詢。這里SQLiteDatabase提供了方法:

  • rawQuery (String sql, String[] selectionArgs):該方法返回 Cursor類的對象,用于操作查詢的結(jié)果。

(2)使用SQLiteDatabase內(nèi)定方法查詢:

  • query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit):這個方法有N多個參數(shù)啊……String table是操作的數(shù)據(jù)表的名稱;String selection是篩選的字段選項;String[] selectionArgs是字段選項對應(yīng)的值;String groupBy是篩選結(jié)果的分組依據(jù);String having是在由groupBy子句創(chuàng)建的分組上設(shè)置條件;String orderBy是結(jié)果的排序方式,String limit是篩選結(jié)果的顯示限制,例如“2, 3”是指從篩選結(jié)果的第2個開始顯示3個。

ContentProvider存儲數(shù)據(jù)

? ? ? ? ContentProvider內(nèi)容提供器,主要用于在不同應(yīng)用程序之間實現(xiàn)數(shù)據(jù)的共享功能。舉例來說,我們開發(fā)一個應(yīng)用程序,我們不可能只使用自己的數(shù)據(jù),也會用到其他應(yīng)用的數(shù)據(jù),像手機中的通訊錄聯(lián)系人,圖片,音樂等是使用到最多的。我們使用的SharedPreferences,文件存儲以及數(shù)據(jù)庫SQLite都是從存儲的應(yīng)用內(nèi)部的數(shù)據(jù),實現(xiàn)不同應(yīng)用間的數(shù)據(jù)共享就要使用到ContentProvider。?
  ContentProvider使用方法有兩種:一種是使用現(xiàn)有的內(nèi)容提供器來讀取和操作相應(yīng)程序中的數(shù)據(jù);另一種是創(chuàng)建自己的內(nèi)容提供器給我們的應(yīng)用提供外部訪問接口。?
  ?
  這里我們只講解使用已有的內(nèi)容提供器來讀取和操作相應(yīng)程序的數(shù)據(jù)。

ContentResolver的使用

  想要訪問內(nèi)容提供器中的內(nèi)容我們需要借助ContentResolver類。?
  ContentResolver為我們提供了”增“insert(Uri url, ContentValues values),“刪”delete(Uri url, String where, String[] selectionArgs),“改”update(Uri uri, ContentValues values, String where, String[] selectionArgs),“查”query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)方法對內(nèi)容提供器中的內(nèi)容進行操作,是不是很眼熟,對啊,和SQLiteDatabase中的增刪改查操作是一樣的,在此我們不再具體描述。

ContentResolver的使用

  想要訪問內(nèi)容提供器中的內(nèi)容我們需要借助ContentResolver類。?
  ContentResolver為我們提供了”增“insert(Uri url, ContentValues values),“刪”delete(Uri url, String where, String[] selectionArgs),“改”update(Uri uri, ContentValues values, String where, String[] selectionArgs),“查”query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)方法對內(nèi)容提供器中的內(nèi)容進行操作,是不是很眼熟,對啊,和SQLiteDatabase中的增刪改查操作是一樣的,在此我們不再具體描述。

Uri的使用

  在SQLiteDatabase中,對數(shù)據(jù)庫的操作是通過接受數(shù)據(jù)庫的表名進行操作的,而在ContentResolver中是不接受表名的,而接受Uri對象。通過Uri指定操作的內(nèi)容“位置”。?
  Uri由兩部分組成:權(quán)限和路徑。權(quán)限是對于不同的應(yīng)用程序進行區(qū)分的,一般用應(yīng)用程序的包名;路徑是對于同一應(yīng)用程序的不同表進行區(qū)分的。例如,我們有一個應(yīng)用程序的包名是“com.example.ontentproviderdemo”,應(yīng)用程序中有一個表“table”,則Uri為:“content://com.example.ontentproviderdemo/table”。

查詢通訊錄

  我們以查詢通訊錄中的內(nèi)容為例,看一下ContentProvider的使用。通過Android提供的ContentProvider內(nèi)容提供器訪問通訊錄中的聯(lián)系人數(shù)據(jù)。?
1. 讀取聯(lián)系人是需要權(quán)限的,首先在AndroidManifext中加入權(quán)限

2. 創(chuàng)建ContentResolver對象對ContentProvider進行操作。 ?
3. 創(chuàng)建一個Uri對象,指定訪問通訊錄。這里我們使用Android已經(jīng)解析好的Uri即可:ContactsContract.CommonDataKinds.Phone.CONTENT_URI ?
4. 查找聯(lián)系人內(nèi)容使用ContentResolver的query()方法,返回一個Cursor對象。

? ? ? 音樂播放器主要用到了文件存儲技術(shù)、sharepreferences存儲技術(shù)以及LruCache緩存技術(shù),當然如果你感興趣也可以自己玩玩數(shù)據(jù)庫啥的~!~

? ? 在PlayService啟動階段,會初始化本地音樂列表(見 【android】音樂播放器之service服務(wù)設(shè)計)通過MusicUtils訪問外部存儲設(shè)備sdcard讀取本地音樂:

public class MusicUtils {// 存放歌曲列表public static ArrayList<Music> sMusicList = new ArrayList<Music>();public static void initMusicList() {// 獲取歌曲列表sMusicList.clear();sMusicList.addAll(LocalMusicUtils.queryMusic(getBaseDir()));}/*** 獲取內(nèi)存卡根* @return*/public static String getBaseDir() {String dir = null;if (!Environment.getExternalStorageState().equals(Environment.MEDIA_UNMOUNTED)) {dir = Environment.getExternalStorageDirectory() + File.separator;} else {dir = App.sContext.getFilesDir() + File.separator;}return dir;}/*** 獲取應(yīng)用程序使用的本地目錄* @return*/public static String getAppLocalDir() {String dir = null;if (!Environment.getExternalStorageState().equals(Environment.MEDIA_UNMOUNTED)) {dir = Environment.getExternalStorageDirectory() + File.separator+ "Music" + File.separator;} else {dir = App.sContext.getFilesDir() + File.separator + "Music" + File.separator;}return mkdir(dir);}/*** 獲取音樂存放目錄* @return*/public static String getMusicDir() {String musicDir = getAppLocalDir();return mkdir(musicDir);}/*** 獲取歌詞存放目錄* * @return*/public static String getLrcDir() {String lrcDir = getAppLocalDir();return mkdir(lrcDir);}/*** 創(chuàng)建文件夾* @param dir* @return*/public static String mkdir(String dir) {File f = new File(dir);if (!f.exists()) {for (int i = 0; i < 5; i++) {if(f.mkdirs()) return dir;}return null;}return dir;} /*** 獲取目錄下的歌曲* @param dirName*/public static ArrayList<Music> queryMusic(String dirName) {ArrayList<Music> results = new ArrayList<Music>();Cursor cursor = App.sContext.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,MediaStore.Audio.Media.DATA + " like ?",new String[] { dirName + "Music/" + "%" },MediaStore.Audio.Media.DEFAULT_SORT_ORDER);if(cursor == null) return results;// id title singer data time imageMusic music;for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {// 如果不是音樂String isMusic = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_MUSIC));if (isMusic != null && isMusic.equals("")) continue;String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));if(isRepeat(title, artist)) continue;music = new Music();music.setId(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));music.setTitle(title.toString());music.setArtist(artist.toString());music.setUri(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));music.setLength(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)));music.setImage(getAlbumImage(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID))));results.add(music);}cursor.close();return results;}? ? ?代碼非常的簡單,逐一的訪問sdcard讀取.mp3/.lrc文件,解析出歌名、著作填充到適配器中去。對于SharePreferences,我們知識將一些共享數(shù)據(jù)存儲在其中,比如每次播放歌曲在本地列表中的position等,部分代碼如下:

/*** 播放* @param position 音樂列表的位置* @return 當前播放的位置*/public int play(int position) {if(position < 0) position = 0;if(position >= MusicUtils.sMusicList.size()) position = MusicUtils.sMusicList.size() - 1;try {mPlayer.reset();mPlayer.setDataSource(MusicUtils.sMusicList.get(position).getUri());mPlayer.prepare();start();if(mListener != null) mListener.onChange(position);} catch (Exception e) {e.printStackTrace();}mPlayingPosition = position;SpUtils.put(Constants.PLAY_POS, mPlayingPosition);if(!readyNotification){startNotification();}else{setRemoteViews();}return mPlayingPosition;} public class SpUtils {public static void put(final String key, final Object value) {SharedPreferences sp = App.sContext.getSharedPreferences(Constants.SP_NAME, Context.MODE_PRIVATE);SharedPreferences.Editor editor = sp.edit();if(value instanceof Integer) {editor.putInt(key, (Integer) value);}else if(value instanceof Float) {editor.putFloat(key, (Float) value);}else if(value instanceof Boolean) {editor.putBoolean(key, (Boolean) value);}else if(value instanceof Long) {editor.putLong(key, (Long) value);}else {editor.putString(key, (String) value);}editor.commit();}public static Object get(Context context, String key, Object defaultObject) {SharedPreferences sp = App.sContext.getSharedPreferences(Constants.SP_NAME,Context.MODE_PRIVATE);if (defaultObject instanceof String) {return sp.getString(key, (String) defaultObject);} else if (defaultObject instanceof Integer) {return sp.getInt(key, (Integer) defaultObject);} else if (defaultObject instanceof Boolean) {return sp.getBoolean(key, (Boolean) defaultObject);} else if (defaultObject instanceof Float) {return sp.getFloat(key, (Float) defaultObject);} else if (defaultObject instanceof Long) {return sp.getLong(key, (Long) defaultObject);}return defaultObject;}/*** 移除某個key值已經(jīng)對應(yīng)的值* @param context* @param key*/public static void remove(Context context, String key) {SharedPreferences sp = context.getSharedPreferences(Constants.SP_NAME,Context.MODE_PRIVATE);sp.edit().remove(key).commit();}/*** 清除所有數(shù)據(jù)* @param context*/public static void clear(Context context) {SharedPreferences sp = context.getSharedPreferences(Constants.SP_NAME,Context.MODE_PRIVATE);sp.edit().clear().commit();} }? ? ?讀取本地音樂時,其中圖片顯示部分用到了圖片緩存技術(shù)MusicIconLoader類的實現(xiàn),在MusicIconLoader類中除調(diào)用 BitmapFactory提供的方法對圖片大小進行處理外(見Android高效加載大圖、多圖解決方案,有效避免程序OOM)還使用了LruCache緩存技術(shù),上面這篇文章講的很清楚,就直接看代碼吧:

? ? ?

public class MusicIconLoader { private static MusicIconLoader sInstance;private LruCache<String, Bitmap> mCache;// 獲取MusicIconLoader的實例public synchronized static MusicIconLoader getInstance() {if(sInstance == null) sInstance = new MusicIconLoader();return sInstance;}// 構(gòu)造方法, 初始化LruCacheprivate MusicIconLoader() {int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8);mCache = new LruCache<String, Bitmap>(maxSize) {protected int sizeOf(String key, Bitmap value) { // return value.getByteCount();return value.getRowBytes() * value.getHeight();}};}// 根據(jù)路徑獲取圖片public Bitmap load(final String uri) {if(uri == null) return null;final String key = Encrypt.md5(uri);Bitmap bmp = getFromCache(key);if(bmp != null) return bmp;bmp = BitmapFactory.decodeFile(uri);addToCache(key, bmp);return bmp;}// 從內(nèi)存中獲取圖片private Bitmap getFromCache(final String key) {return mCache.get(key);}// 將圖片緩存到內(nèi)存中private void addToCache(final String key, final Bitmap bmp) {if(getFromCache(key) == null && key != null && bmp != null) mCache.put(key, bmp);} }






總結(jié)

以上是生活随笔為你收集整理的【android】音乐播放器之数据存储总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 你懂的在线观看网站 | 在线视频1卡二卡三卡 | 第一章豪妇荡乳黄淑珍 | 波多野结衣网址 | 免费福利小视频 | 国产精品综合 | 日日夜夜精品免费 | 免费高清视频在线观看 | 国产一级高清视频 | 哺乳援交吃奶在线播放 | 国产欧美日韩激情 | 日韩高清在线观看一区 | 亚洲a影院| www.久久精品视频 | 欧美日韩中文在线视频 | 国产欧美一区二区三区精品酒店 | 97成人免费| 久久精品中文闷骚内射 | 国产日本亚洲 | 国产激情毛片 | 四虎免看黄| 色老头综合网 | 国产粉嫩av | 免费人成在线观看视频播放 | 入禽太深免费视频 | 日本女人hd| 日韩高清不卡在线 | jizz国产在线观看 | 97黄色网| 奇米影视在线观看 | 瑟瑟在线观看 | 久久久久久久9999 | 久久国产精品99久久人人澡 | 色妞网站 | 国模在线视频 | 亚洲乱色熟女一区二区 | 日韩欧美三级在线 | 欧美偷拍另类 | 国产欧美一区二区精品性色超碰 | 伊人久久久久噜噜噜亚洲熟女综合 | 天堂а√在线中文在线新版 | 国内一级视频 | 粉嫩av懂色av蜜臀av分享 | 国产一线在线观看 | 国产欧美日韩 | 最新国产精品自拍 | avtt2015| 色婷五月| 在线观看的av网站 | 久热免费视频 | 日韩avv| 欧美亚洲一区二区三区四区 | 亚洲欧美激情小说另类 | 久草视频免费在线观看 | 久草中文视频 | 三级黄色短视频 | 男生插女生的网站 | 99国产精品欲 | 在线成人av | 最新黄色网址在线观看 | 老司机午夜剧场 | 日韩精品在线免费 | jizz韩国 | 中文在线а√天堂官网 | 影音先锋资源av | 农村老熟妇乱子伦视频 | 91视频一区二区 | 美女裸片 | 四虎成人免费视频 | 精品人妻无码中文字幕18禁 | 国产一区亚洲二区三区 | jzjzjzjzj亚洲成熟少妇 | 日本一本在线观看 | 精品欧美国产 | 一区二区三区高清在线观看 | 日韩激情图片 | 精品中文在线 | 国产欧美一区二区三区四区 | 亚洲午夜无码久久久久 | 手机看片一区二区 | jzzjzz日本丰满少妇 | 国产麻豆乱码精品一区二区三区 | 亚洲婷婷丁香 | 国产精品久久久国产盗摄 | 人妻一区二区三 | av在线播放免费 | 麻豆视频在线观看免费网站黄 | 都市激情久久 | 伊人春色网 | 亚洲精品视频久久久 | 少妇人禽zoz0伦视频 | 亚洲一区二区三区四区av | av免费看网站 | 欧美性猛交乱大交3 | 91九色国产在线 | 熟女丰满老熟女熟妇 | 亚洲一区二区在线视频 | 高潮又黄又刺激 | 女优在线观看 |