androidcursor遍歷
❶ android 下使用Cursor如何獲得專輯圖片
android下使用cursor獲取專輯圖片,主要是在資料庫裡面先保存專輯圖片的url地址,當使用cursor游標遍歷資料庫數據的時候,使用資源操作類進行載入相應的url,如下代碼:
Cursor cursor = context.getContentResolver().query(Media.EXTERNAL_CONTENT_URI, columns, null, null, null);
Log.e("cursor" , (cursor==null) + "");
while(cursor.moveToNext()) {
// 查找封面圖片
long albumId = cursor.getLong(5);
// 讀取專輯圖片
String album_uri = "content://media/external/audio/albumart"; // 專輯Uri對應的字元串
Uri albumUri = ContentUris.withAppendedId(Uri.parse(album_uri), albumId);
// 取圖片 ==> 得到一個輸入流
Bitmap coverPhoto = null ;
try {
InputStream is = context.getContentResolver().openInputStream(albumUri);
if(null != is) {
coverPhoto = BitmapFactory.decodeStream(is);
}
} catch (Exception e) {
e.printStackTrace();
}
data.add(new Audio(cursor.getLong(0), cursor.getString(1) , cursor.getString(2) , cursor.getLong(3) , cursor.getString(4) , albumId , coverPhoto));
}
cursor.close();
❷ android 內存泄露 會導致什麼問題
1. 查詢資料庫而沒有關閉Cursor
在Android中,Cursor是很常用的一個對象,但在寫代碼是,經常會有人忘記調用close, 或者因為代碼邏輯問題狀況導致close未被調用。
通常,在Activity中,我們可以調用startManagingCursor或直接使用managedQuery讓Activity自動管理Cursor對象。
但需要注意的是,當Activity介紹後,Cursor將不再可用!
若操作Cursor的代碼和UI不同步(如後台線程),那沒需要先判斷Activity是否已經結束,或者在調用OnDestroy前,先等待後台線程結束。
除此之外,以下也是比較常見的Cursor不會被關閉的情況:
雖然表面看起來,Cursor.close()已經被調用,但若出現異常,將會跳過close(),從而導致內存泄露。
所以,我們的代碼應該以如下的方式編寫:
Cursor c = queryCursor();
try {
int a = c.getInt(1);
......
} catch (Exception e) {
} finally {
c.close(); //在finally中調用close(), 保證其一定會被調用
}
try {
Cursor c = queryCursor();
int a = c.getInt(1);
......
c.close();
} catch (Exception e) {
}
2. 調用registerReceiver後未調用unregisterReceiver().
在調用registerReceiver後,若未調用unregisterReceiver,其所佔的內存是相當大的。
而我們經常可以看到類似於如下的代碼:
這是個很嚴重的錯誤,因為它會導致BroadcastReceiver不會被unregister而導致內存泄露。
registerReceiver(new BroadcastReceiver() {
...
}, filter); ...
3. 未關閉InputStream/OutputStream
在使用文件或者訪問網路資源時,使用了InputStream/OutputStream也會導致內存泄露
4. Bitmap使用後未調用recycle()
根據SDK的描述,調用recycle並不是必須的。但在實際使用時,Bitmap佔用的內存是很大的,所以當我們不再使用時,盡量調用recycle()以釋放資源。
5. Context泄露
這是一個很隱晦的內存泄露的情況。
先讓我們看一下以下代碼:
在這段代碼中,我們使用了一個static的Drawable對象。
這通常發生在我們需要經常調用一個Drawable,而其載入又比較耗時,不希望每次載入Activity都去創建這個Drawable的情況。
此時,使用static無疑是最快的代碼編寫方式,但是其也非常的糟糕。
當一個Drawable被附加到View時,這個View會被設置為這個Drawable的callback (通過調用Drawable.setCallback()實現)。
這就意味著,這個Drawable擁有一個TextView的引用,而TextView又擁有一個Activity的引用。
這就會導致Activity在銷毀後,內存不會被釋放。
private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
❸ android開發,怎麼遍歷SD卡所有MP3文件並列舉出來,能不能給我最簡單的代碼呀
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
//遍歷媒體資料庫
if(cursor.moveToFirst()){
while (!cursor.isAfterLast()) {
//歌曲編號
int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
//歌曲id
int trackId=cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
//歌曲標題
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
//歌曲的專輯名:MediaStore.Audio.Media.ALBUM
String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
//歌曲的歌手名: MediaStore.Audio.Media.ARTIST
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
//歌曲文件的路徑 :MediaStore.Audio.Media.DATA
String url = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
//歌曲的總播放時長:MediaStore.Audio.Media.DURATION
int ration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
//歌曲文件的大小 :MediaStore.Audio.Media.SIZE
Long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
//歌曲文件顯示名字
String disName=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
cursor.moveToNext();
}
cursor.close();
}