2

我試圖修改HelloGridView示例,以便我可以顯示存儲在SD上的圖像的圖像縮略圖而不是res/drawable中的圖像。這個想法是首先在ImageView.initialize()函數中創建一個帶有圖像的列表,並且使用它幾乎和示例中一樣。Android「嘗試訪問已關閉的遊標」

我遇到了我的光標問題,首先我試圖將它作爲Imageview.initialize()函數中的私有函數(它只是註釋掉了,所以你可以看到我的位置),因爲對我來說它似乎是這樣只是在那裏使用,但後來我得到了錯誤「嘗試訪問一個光標後,它已被關閉。」在線上的onCreate()函數

gridview.setAdapter(imageAdapter);

所以這條線很明顯地使用它。接下來的嘗試是將遊標設置爲「全局」,然後在該行之後關閉它,但是我得到相同的錯誤,但是現在當我離開onCreate()時。 這就是現在的代碼,我不知道該怎麼做。此外,如果您發現其他任何看起來很奇怪的事情,請讓我知道,因爲我在android和java上非常新穎。

package se.mmarks.hellogridview; 

import java.util.ArrayList; 

import android.app.Activity; 
import android.content.Context; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.provider.MediaStore; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.BaseAdapter; 
import android.widget.GridView; 
import android.widget.ImageView; 
import android.widget.Toast; 

public class MainActivity extends Activity { 

    private Cursor imagecursor; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     GridView gridview = (GridView) findViewById(R.id.gridview); 
     ImageAdapter imageAdapter = new ImageAdapter(this, imagecursor); 
     imagecursor = imageAdapter.initialize(); 
     gridview.setAdapter(imageAdapter); 
     /* setAdapter needs the cursor, 
     * this is why it is closed here and not in ImageAdapter.initialize() 
     */ 
     imagecursor.close(); 

     gridview.setOnItemClickListener(new OnItemClickListener() { 
      public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
      Toast.makeText(MainActivity.this, "" + position, Toast.LENGTH_SHORT).show(); 
      } 
     }); 
    } 
} 



class ImageAdapter extends BaseAdapter { 
    private ArrayList<ImageView> images = new ArrayList<ImageView>(); 
    Cursor imagecursor = null; 


    private Context mContext; 

    public ImageAdapter(Context c, Cursor cursor) { 
     mContext = c; 
     imagecursor = cursor; 
    } 

    public Cursor initialize() { 
     final String[] columns = { MediaStore.Images.Thumbnails._ID }; 
     imagecursor = null; 
     try { 
      imagecursor = mContext.getContentResolver().query(
         MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, null); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 

     if(imagecursor != null){ 
      int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Thumbnails._ID); 
      int count = imagecursor.getCount(); 
      for (int i = 0; i < count; i++) { 
       imagecursor.moveToPosition(i); 
       int id = imagecursor.getInt(image_column_index); 
       ImageView imageItem = new ImageView(mContext); 
       imageItem.setId(id); 
       imageItem.setImageBitmap(
        MediaStore.Images.Thumbnails.getThumbnail(mContext.getContentResolver(), id, 
        MediaStore.Images.Thumbnails.MICRO_KIND, null)); 
       images.add(imageItem); 
      } 
      //imagecursor.close(); 
     } 
     return imagecursor; 
    } 

    @Override 
    public int getCount() { 
     return imagecursor.getCount(); 
    } 

    @Override 
    public Object getItem(int position) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { // if it's not recycled, initialize some attributes 
      imageView = images.get(position); 
      imageView.setLayoutParams(new GridView.LayoutParams(85, 85)); 
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
      imageView.setPadding(8, 8, 8, 8); 
     } else { 
      imageView = (ImageView) convertView; 
     } 
     return imageView; 
    } 
} 

回答

6

Android「的試圖訪問一個遊標後已關閉」

雖然你的工作/訪問到Cursor數據,它需要被打開!

通常建議關閉任何數據源遊標在活動的生命週期方法要麼onStop()onDestroy()方法。

基本例如:

public void onDestroy() { 
    super.onDestroy(); 
    if (cursor != null) { 
     c.close(); 
    } 
    if (db != null) { 
     db.close(); 
    } 
} 
+0

感謝sajmon_d!我加入的onStop()函數和移動imagecursor.close()那裏,現在的作品!:) – user2078171 2013-02-17 13:10:19

+0

歡迎您:) – Sajmon 2013-02-17 13:12:37

0

因爲我沒有足夠的信譽評論...

我必須補充的事實,即使正確的答案說,你可以關閉你的光標的onDestroy( ),這不是你應該做的。

onDestroy方法不保證Cursor.close()將被調用,因爲android本身並不能保證onDestroy最終會被調用。

從技術文檔:

的onDestroy()=您在活動前收到的最後通話是 銷燬。這可能是因爲活動正在完成 (某人稱爲finish()或者因爲系統暫時爲 銷燬此活動的實例以節省空間。您可以使用isFinishing()方法區分這兩個方案。

相關問題