确保我的游标被关闭 [英] Ensuring my cursor is closed

查看:185
本文介绍了确保我的游标被关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一些使用SimpleCursorAdapter为一个ListView几个不同的活动。我最关心的,现在是内存泄漏和诸如此类的东西。我需要确保,当它被认为是游标关闭。

我注意到,我的应用程序崩溃,当我去重新运行code我做了由于NullPointerException异常变化后。

有人可以看看我的code为我的活动之一,并告诉我,如果有与光标没有被正确关闭的问题?或者你看到的任何其他问题可能导致内存泄漏,或ANR?

RoutinesActivity.java

 包com.gauvion.gfit;进口android.annotation.Sup pressLint;
进口android.app.ListActivity;
进口android.content.Intent;
进口android.database.Cursor;
进口android.os.Bundle;
进口android.view.Menu;
进口android.view.MenuInflater;
进口android.view.MenuItem;
进口android.view.View;
进口android.widget.ListView;
进口android.widget.SimpleCursorAdapter;
进口android.widget.Toast;公共类RoutinesActivity扩展ListActivity {    私人RoutinesDataSource数据源;
    私人SimpleCursorAdapter DataAdapter的;
    私人布尔isEditing = FALSE;
    私人吐司toast_deleted;
    私有String [] =列新的String [] {} MySQLiteHelper.COLUMN_NAME;
    私人诠释[]来;    @燮pressLint(ShowToast)
    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_routines);
        getActionBar()setDisplayHomeAsUpEnabled(真)。        toast_deleted = Toast.makeText(这一点,,Toast.LENGTH_SHORT);
        数据源=新RoutinesDataSource(本);
        datasource.open();        光标光标= datasource.fetchAllRoutines();
        以新= INT [] {} R.id.listitem_routine_name;
        的DataAdapter =新SimpleCursorAdapter(在此,R.layout.listitem_routine,光标,列,向,0);
        setListAdapter(DataAdapter的);
    }    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){
        MenuInflater吹气= getMenuInflater();
        inflater.inflate(R.menu.activity_routines,菜单);
        返回true;
    }    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
        光标光标= datasource.fetchAllRoutines();
        开关(item.getItemId()){
        案例android.R.id.home:
            this.finish();
            返回true;        案例R.id.button_routines_add:
            意图startRoutineAdd =新意图(这一点,RoutineAddActivity.class);
            this.startActivity(startRoutineAdd);
            返回true;        案例R.id.button_routines_edit:
            以新= INT [] {} R.id.listitem_routine_edit_name;
            的DataAdapter =新SimpleCursorAdapter(在此,R.layout.listitem_routine_edit,光标,列,向,0);
            setListAdapter(DataAdapter的);            isEditing =真;
            invalidateOptionsMenu();
            返回true;        案例R.id.button_routines_edit_done:
            以新= INT [] {} R.id.listitem_routine_name;
            的DataAdapter =新SimpleCursorAdapter(在此,R.layout.listitem_routine,光标,列,向,0);
            setListAdapter(DataAdapter的);            isEditing = FALSE;
            invalidateOptionsMenu();
            返回true;        默认:
            返回super.onOptionsItemSelected(项目);
        }
    }    @覆盖
    prepareOptionsMenu(菜单菜单)上公共布尔{
        super.on prepareOptionsMenu(菜单);        menu.findItem(R.id.button_routines_edit).setVisible(isEditing!);
        menu.findItem(R.id.button_routines_edit_done).setVisible(isEditing);        返回true;
    }    @覆盖
    保护无效onListItemClick(ListView中升,视图V,INT位置,长thisID)
    {
        光标的光标=((SimpleCursorAdapter)l.getAdapter())getCursor();
        cursor.moveToPosition(位置);
        长ID = cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.COLUMN_ID));
        字符串名称= cursor.getString(cursor.getColumnIndex(MySQLiteHelper.COLUMN_NAME));        如果(!isEditing){
            意图startDaysActivity =新意图(这一点,Da​​ysActivity.class);
            startDaysActivity.putExtra(routineDataID,ID);
            startDaysActivity.putExtra(routineDataName,名);
            this.startActivity(startDaysActivity);
        }
    }    公共无效的onClick(查看视图){
        ListView的L = getListView();
        INT位置= l.getPositionForView(视图);        光标的光标=((SimpleCursorAdapter)l.getAdapter())getCursor();
        cursor.moveToPosition(位置);
        长ID = cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.COLUMN_ID));
        字符串名称= cursor.getString(cursor.getColumnIndex(MySQLiteHelper.COLUMN_NAME));        开关(view.getId()){
        案例R.id.button_routine_edit:
            意图startRoutineEdit =新意图(这一点,RoutineEditActivity.class);
            startRoutineEdit.putExtra(routineDataID,ID);
            startRoutineEdit.putExtra(routineDataName,名);
            this.startActivity(startRoutineEdit);
            打破;        案例R.id.button_routine_delete:
            toast_deleted.setText(的getString(R.string.toast_routine_deleted));
            toast_deleted.show();
            datasource.deleteRoutine(ID);
            onResume();
            打破;
        }
    }    @覆盖
    保护无效onResume(){
        super.onResume();
        datasource.open();
        光标光标= datasource.fetchAllRoutines();
        dataAdapter.changeCursor(光标);
    }    @覆盖
    保护无效的onPause(){
        super.onPause();
        datasource.close();
    }}


解决方案

我最终只是让在光标一个全球性的,并呼吁 cursor.close() 的onDestroy() @覆盖。

So I have a few different Activities that use a SimpleCursorAdapter for a ListView. My main concern right now would be memory leaks and whatnot. I need to make sure that the cursor is closed when it is supposed to be.

I noticed that my app crashes when I go to re-run the code after I've made changes due to a nullpointerexception.

Can someone take a look at my code for one of my activities and tell me if there are issues with the cursor not being closed properly? Or any other issues you see that may cause memory leaks or ANR?

RoutinesActivity.java:

package com.gauvion.gfit;

import android.annotation.SuppressLint;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class RoutinesActivity extends ListActivity {

    private RoutinesDataSource datasource;
    private SimpleCursorAdapter dataAdapter;
    private boolean isEditing = false;
    private Toast toast_deleted;
    private String[] columns = new String[] { MySQLiteHelper.COLUMN_NAME };
    private int[] to;

    @SuppressLint("ShowToast")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_routines);
        getActionBar().setDisplayHomeAsUpEnabled(true);

        toast_deleted = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        datasource = new RoutinesDataSource(this);
        datasource.open();

        Cursor cursor = datasource.fetchAllRoutines();
        to = new int[] { R.id.listitem_routine_name };
        dataAdapter = new SimpleCursorAdapter(this, R.layout.listitem_routine, cursor, columns, to, 0);
        setListAdapter(dataAdapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.activity_routines, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {     
        Cursor cursor = datasource.fetchAllRoutines();
        switch (item.getItemId()) {
        case android.R.id.home:
            this.finish();
            return true;

        case R.id.button_routines_add:
            Intent startRoutineAdd = new Intent(this, RoutineAddActivity.class);
            this.startActivity(startRoutineAdd);
            return true;

        case R.id.button_routines_edit:
            to = new int[] { R.id.listitem_routine_edit_name };
            dataAdapter = new SimpleCursorAdapter(this, R.layout.listitem_routine_edit, cursor, columns, to, 0);
            setListAdapter(dataAdapter);

            isEditing = true;
            invalidateOptionsMenu();
            return true;

        case R.id.button_routines_edit_done:
            to = new int[] { R.id.listitem_routine_name };
            dataAdapter = new SimpleCursorAdapter(this, R.layout.listitem_routine, cursor, columns, to, 0);
            setListAdapter(dataAdapter);

            isEditing = false;
            invalidateOptionsMenu();
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);

        menu.findItem(R.id.button_routines_edit).setVisible(!isEditing);
        menu.findItem(R.id.button_routines_edit_done).setVisible(isEditing);

        return true;
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long thisID)
    {       
        Cursor cursor = ((SimpleCursorAdapter)l.getAdapter()).getCursor();
        cursor.moveToPosition(position);
        long id = cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.COLUMN_ID));
        String name = cursor.getString(cursor.getColumnIndex(MySQLiteHelper.COLUMN_NAME));

        if (!isEditing) {
            Intent startDaysActivity = new Intent(this, DaysActivity.class);
            startDaysActivity.putExtra("routineDataID", id);
            startDaysActivity.putExtra("routineDataName", name);
            this.startActivity(startDaysActivity);
        }
    }

    public void onClick(View view) {        
        ListView l = getListView();
        int position = l.getPositionForView(view);

        Cursor cursor = ((SimpleCursorAdapter)l.getAdapter()).getCursor();
        cursor.moveToPosition(position);
        long id = cursor.getLong(cursor.getColumnIndex(MySQLiteHelper.COLUMN_ID));
        String name = cursor.getString(cursor.getColumnIndex(MySQLiteHelper.COLUMN_NAME));

        switch (view.getId()) { 
        case R.id.button_routine_edit:
            Intent startRoutineEdit = new Intent(this, RoutineEditActivity.class);
            startRoutineEdit.putExtra("routineDataID", id);
            startRoutineEdit.putExtra("routineDataName", name);
            this.startActivity(startRoutineEdit);
            break;

        case R.id.button_routine_delete:
            toast_deleted.setText(getString(R.string.toast_routine_deleted));
            toast_deleted.show();
            datasource.deleteRoutine(id);
            onResume();
            break;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        datasource.open();
        Cursor cursor = datasource.fetchAllRoutines();
        dataAdapter.changeCursor(cursor);
    }

    @Override
    protected void onPause() {
        super.onPause();
        datasource.close();
    }

} 

解决方案

I ended up just making the cursor a global and calling cursor.close() in an onDestroy() @Override.

这篇关于确保我的游标被关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆