Android Studio 没有显示未关闭光标的警告,我是否仍应关闭它?

Android Studio doesn't show warning for not closing cursor, should I still close it?

我在 class DatabaseHelper extends SQLiteAssetHelper 中有一个 private Cursor c;,它全局处理我的应用程序的所有数据库操作。此游标在整个 class 中使用,在多个方法中用于从 private static SQLiteDatabase mydb; 获取数据。我既没有关闭任何地方的游标,也没有关闭数据库,但我没有看到任何警告。我有一个案例,我被警告从方法内部关闭本地游标(我解决了)。我必须关闭这个游标吗? (假设我不必关闭静态数据库)

这里是全部class,以防万一:

    class DatabaseHelper extends SQLiteAssetHelper {

    static final String AUTHORITY = "com.example.attendance.provider";
    static final String ACCOUNT_TYPE = "example.com";
    static final String ACCOUNT = "Lazim";
    static final String WIFI_ERROR = "Please enter your office premises";
    static final boolean DEBUG = true;
    private static final String DATE_FORMAT = "d-M-yyyy";
    private static final String TIME_FORMAT = "hh:mm:ss a";
    private static final String DB_NAME = "attendance.db";
    private static final int DB_VERSION = 1;
    private static SQLiteDatabase mydb;
    private Cursor c;
    private Context context;

    DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.context = context;
        mydb = getWritableDatabase();
    }

    boolean insertTable(int u_id, String name, String username, String password) {
        boolean b;
        try {
            c = mydb.rawQuery("select * from login where u_id=" + u_id + ";", null);
            if (!c.moveToFirst()) {
                mydb.execSQL("insert into login (u_id,name,username,password) values(" + u_id + ",'" + name + "','" + username + "','" + password + "');");
                b = true;
            } else {
                mydb.execSQL("update login set name='" + name + "',username='" + username + "',password='" + password + "' where u_id=" + u_id + ";");
                mydb.execSQL("delete from records where u_id=" + u_id + ";");
                b = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            b = false;
        }
        return b;
    }

    boolean insertTable(int id, String name, String date, String checkin, int flag) {
        boolean b = false;
        try {
            c = mydb.rawQuery("select * from records where u_id=" + id + " and date='" + date + "' and checkin='" + checkin + "';", null);
            if (!c.moveToFirst()) {
                mydb.execSQL("insert into records (u_id,name,date,checkin,checkout,flag) values(" + id + ",'" + name + "','" + date + "','" + checkin + "',''," + flag + ");");
                b = true;
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return b;
    }

    Boolean deleteRecords(String username) {
        Boolean b = null;
        try {
            c = mydb.rawQuery("select u_id from login where username='" + username + "';", null);
            if (c.moveToFirst()) {
                int u_id = c.getInt(0);
                Cursor cursor = mydb.rawQuery("select * from records where u_id=" + u_id + ";", null);
                if (cursor.moveToFirst())
                    mydb.execSQL("delete from records where u_id=" + u_id + ";", null);
                cursor.close();
                mydb.execSQL("delete from login where username='" + username + "';");
                b = true;
            } else
                b = false;
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return b;
    }

    boolean insertOnLogin(int u_id, String name, String username, String password) {
        boolean b = false;
        try {
            c = mydb.rawQuery("select * from login where u_id=" + u_id + ";", null);
            if (!c.moveToFirst())
                mydb.execSQL("insert into login (u_id,name,username,password) values(" + u_id + ",'" + name + "','" + username + "','" + password + "');");
            else
                mydb.execSQL("update login set name='" + name + "',username='" + username + "',password='" + password + "' where u_id=" + u_id + ";");
            b = true;
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return b;
    }

    boolean updateTable(int id, String name, String checkout, String date, int flag) {
        boolean b = false;
        int s_id, f;
        try {
            c = mydb.rawQuery("select s_id,flag from records where u_id=" + id + " and date='" + date + "' and checkin='" + getCheckin() + "';", null);
            if (c.moveToFirst()) {
                s_id = c.getInt(0);
                f = c.getInt(1);
                if (f == 0)
                    flag = 0;
                mydb.execSQL("update records set flag=" + flag + ",checkout='" + checkout + "' where s_id=" + s_id + ";");
                b = true;
            } else {
                mydb.execSQL("insert into records (u_id,name,date,checkin,checkout,flag) values(" + id + ",'" + name + "','" + date + "','','" + checkout + "'," + flag + ");");
                b = true;
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return b;
    }

    void updateFlags(Cursor c) {
        if (c.moveToFirst()) {
            do {
                try {
                    mydb.execSQL("update records set flag=1 where u_id=" + c.getInt(0) + " and date='" + c.getString(2) + "' and checkin='" + c.getString(3) + "' and checkout='" + c.getString(4) + "';");
                    if (DEBUG) Log.i("#####", "###FLAGS UPDATED");
                } catch (SQLiteException e) {
                    e.printStackTrace();
                }
            } while (c.moveToNext());
        }
    }

    long getMinDate(int u_id) {
        long minDate = -1;
        long tempDate;
        try {
            c = mydb.rawQuery("select distinct(date) from records where u_id=" + u_id + ";", null);
            if (c.moveToFirst()) {
                minDate = getLongDateTime(c.getString(0), DATE_FORMAT);
                while (c.moveToNext()) {
                    tempDate = getLongDateTime(c.getString(0), DATE_FORMAT);
                    if (tempDate < minDate)
                        minDate = tempDate;
                }
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return minDate;
    }

    private String getMaxDate(int u_id, String check) {
        long longDate;
        long tempDate;
        String maxDate = null;
        try {
            if ("checkout".equals(check))
                c = mydb.rawQuery("select distinct(date) from records where u_id=" + u_id + " and checkout!='';", null);
            else
                c = mydb.rawQuery("select distinct(date) from records where u_id=" + u_id + ";", null);
            if (c.moveToFirst()) {
                maxDate = c.getString(0);
                longDate = getLongDateTime(maxDate, DATE_FORMAT);
                while (c.moveToNext()) {
                    tempDate = getLongDateTime(c.getString(0), DATE_FORMAT);
                    if (tempDate > longDate) {
                        longDate = tempDate;
                        maxDate = c.getString(0);
                    }
                }
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return maxDate;
    }

    private long getLongDateTime(String datetime, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format, Locale.US);
        Date newDate;
        long longDate = -1;
        try {
            newDate = simpleDateFormat.parse(datetime);
            longDate = newDate.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return longDate;
    }

    POJO urlConnector(String con) {
        POJO pojo = new POJO();
        int u_id;
        String response;
        try {
            URL url = new URL(con);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(10000);
            httpURLConnection.setReadTimeout(10000);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader((InputStream) httpURLConnection.getContent()));
            response = bufferedReader.readLine();
            httpURLConnection.disconnect();
            JSONObject object = new JSONObject(response);
            response = object.getString("response");
            pojo.setResponse(response);
            if ("success".equals(response)) {
                u_id = object.getInt("u_id");
                pojo.setU_id(u_id);
            }
        } catch (SocketTimeoutException e) {
            e.printStackTrace();
            pojo.setResponse("Connection timed out");
        } catch (IOException e) {
            e.printStackTrace();
            pojo.setResponse("Network unavailable");
        } catch (JSONException e) {
            e.printStackTrace();
            pojo.setResponse("Data unavailable");
        }
        return pojo;
    }

    POJO jsonReceiver(String con) {
        POJO pojo = new POJO();
        String name = "", response;
        int u_id = -1;
        try {
            URL url = new URL(con);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(10000);
            httpURLConnection.setReadTimeout(10000);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader((InputStream) httpURLConnection.getContent()));
            String result = bufferedReader.readLine();
            httpURLConnection.disconnect();
            JSONObject object = new JSONObject(result);
            response = object.getString("response");
            pojo.setResponse(response);
            if ("success".equals(response)) {
                u_id = object.getInt("u_id");
                name = object.getString("name");
                pojo.setU_id(u_id);
                pojo.setNamePojo(name);
            }
            if (object.has("jsonarray")) {
                JSONArray jsonArray = object.getJSONArray("jsonarray");
                if (DEBUG) Log.i("#####", "JSONARRAY: " + jsonArray.toString());
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (DEBUG) Log.i("###########", "#####" + jsonObject);
                    String date = jsonObject.getString("date");
                    String checkin = jsonObject.getString("checkin");
                    String checkout = jsonObject.getString("checkout");
                    try {
                        c = mydb.rawQuery("select * from records where u_id=" + u_id + " and date='" + date + "' and checkin='" + checkin + "';", null);
                        if (!c.moveToFirst())
                            mydb.execSQL("insert into records (u_id,name,date,checkin,checkout) values (" + u_id + ",'" + name + "','" + date + "','" + checkin + "','" + checkout + "');");
                    } catch (SQLiteException e) {
                        e.printStackTrace();
                    }
                }
            } else if (DEBUG) Log.i("#####", "###NO JSON ARRAY");
        } catch (SocketTimeoutException e) {
            e.printStackTrace();
            pojo.setResponse("Connection timed out");
        } catch (IOException e) {
            e.printStackTrace();
            pojo.setResponse("Network unavailable");
        } catch (JSONException e) {
            e.printStackTrace();
            pojo.setResponse("Data unavailable");
        }
        return pojo;
    }

    String uploadData(String con) {
        String result;
        try {
            URL url = new URL(con);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(10000);
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            result = reader.readLine();
            connection.disconnect();
        } catch (SocketTimeoutException e) {
            e.printStackTrace();
            result = "Connection timed out";
        } catch (IOException e) {
            e.printStackTrace();
            result = "Network unavailable";
        }
        return result;
    }

    void setCheckin(String checkin) {
        SharedPreferences preferences = context.getSharedPreferences("checkin", MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("last_checkin", checkin);
        editor.apply();
    }

    String getCheckin() {
        SharedPreferences preferences = context.getSharedPreferences("checkin", MODE_PRIVATE);
        return preferences.getString("last_checkin", null);
    }


    Cursor getFileQueue() {
        try {
            c = mydb.rawQuery("select u_id,name,date,checkin,checkout from records where flag=0 order by s_id", null);
            return c;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private Cursor getSessionLogAM(String date, int u_id) {
        Cursor mergeCursorAM = null;
        try {
            c = mydb.rawQuery("select checkin,checkout from records where u_id=" + u_id + " and date='" + date + "' and checkin like '12%AM' order by checkin;", null);
            mergeCursorAM = mydb.rawQuery("select checkin,checkout from records where u_id=" + u_id + " and date='" + date + "' and checkin like '%AM' and checkin not like '12%' order by checkin;", null);
            if (c.moveToFirst()) {
                if (mergeCursorAM.moveToFirst())
                    mergeCursorAM = new MergeCursor(new Cursor[]{c, mergeCursorAM});
                else
                    mergeCursorAM = c;
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return mergeCursorAM;
    }

    private Cursor getSessionLogPM(String date, int u_id) {
        Cursor mergeCursorPM = null;
        try {
            c = mydb.rawQuery("select checkin,checkout from records where u_id=" + u_id + " and date='" + date + "' and checkin like '12%PM' order by checkin;", null);
            mergeCursorPM = mydb.rawQuery("select checkin,checkout from records where u_id=" + u_id + " and date='" + date + "' and checkin like '%PM' and checkin not like '12%' order by checkin;", null);
            if (c.moveToFirst()) {
                if (mergeCursorPM.moveToFirst())
                    mergeCursorPM = new MergeCursor(new Cursor[]{c, mergeCursorPM});
                else
                    mergeCursorPM = c;
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return mergeCursorPM;
    }

    Cursor getMergedLog(String date, int u_id) {
        Cursor AM = getSessionLogAM(date, u_id), PM = getSessionLogPM(date, u_id);
        if (AM.moveToFirst()) {
            if (PM.moveToFirst())
                return new MergeCursor(new Cursor[]{AM, PM});
            else return AM;
        } else if (PM.moveToFirst())
            return PM;
        else return null;
    }

    String enString(String s) {
        try {
            return URLEncoder.encode(s, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    String getName(String username) {
        String name = "";
        try {
            c = mydb.rawQuery("select name from login where username='" + username + "';", null);
            if (c.moveToFirst()) {
                do {
                    name = c.getString(0);
                } while (c.moveToNext());
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return name;
    }

    int getID(String username) {
        int id = -1;
        try {
            c = mydb.rawQuery("select u_id from login where username='" + username + "';", null);
            if (c.moveToFirst()) {
                do {
                    id = c.getInt(0);
                } while (c.moveToNext());
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return id;
    }

    String getLastLogin(int id) {
        String maxTime;
        String maxDate;
        maxDate = getMaxDate(id, null);
        if (maxDate != null) {
            maxTime = getMaxTime(id, maxDate, "checkin");
            if (maxTime != null)
                return (maxTime + "  " + maxDate);
        }
        return "N/A";
    }


    String getLastLogout(int id) {
        String maxTime;
        String maxDate;
        maxDate = getMaxDate(id, "checkout");
        if (maxDate != null) {
            maxTime = getMaxTime(id, maxDate, "checkout");
            if (maxTime != null)
                return (maxTime + "  " + maxDate);
        }
        return "N/A";
    }

    private String getMaxTime(int u_id, String date, String check) {
        long time, tempTime;
        String maxTime = null;
        try {
            c = mydb.rawQuery("select distinct(" + check + ") from records where u_id=" + u_id + " and date='" + date + "';", null);
            if (c.moveToFirst()) {
                maxTime = c.getString(0);
                time = getLongDateTime(maxTime, TIME_FORMAT);
                while (c.moveToNext()) {
                    tempTime = getLongDateTime(c.getString(0), TIME_FORMAT);
                    if (tempTime > time) {
                        time = tempTime;
                        maxTime = c.getString(0);
                    }
                }
            }
        } catch (SQLiteException e) {
            e.printStackTrace();
        }
        return maxTime;
    }


    boolean checkWifi() {
        boolean b = false;
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (wifiManager.startScan()) {
            List<ScanResult> scanResults = wifiManager.getScanResults();
            if (scanResults != null)
                for (int i = 0; i < scanResults.size(); i++) {
                    ScanResult result = scanResults.get(i);
                    if ("6c:72:20:fa:0b:6c".equals(result.BSSID) || "d8:fe:e3:17:93:0c".equals(result.BSSID))
                        if (result.level >= -67) {
                            b = true;
                            break;
                        }
                }
        }
        return b;
    }

    void setLoggedIn(String username) {
        SharedPreferences sharedPreferences = context.getSharedPreferences("logged_in", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean("login", true);
        editor.putBoolean("login_received", true);
        editor.putBoolean("logout_received", false);
        editor.putString("username", username);
        editor.apply();
    }

    void setLoggedOut() {
        SharedPreferences sharedPreferences = context.getSharedPreferences("logged_in", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean("login", false);
        editor.putBoolean("logout_received", true);
        editor.putBoolean("login_received", false);
        editor.apply();
    }

    void setCheckBox(boolean b, String username, String password) {
        SharedPreferences preferences = context.getSharedPreferences("checkbox", MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putBoolean("remember", b);
        if (b) {
            editor.putString("username", username);
            editor.putString("password", password);
        } else {
            if (preferences.getString("username", null) != null)
                editor.remove("username");
            if (preferences.getString("password", null) != null)
                editor.remove("password");
        }
        editor.apply();
    }

}

您没有收到警告的原因是 c 被声明为 class 成员。

AndroidStudio 假定如果您在方法范围之外声明 Cursor,那么它也会与其他方法共享。使用此声明范围,您有效地声明了 "I know what I'm doing and will close the Cursor once I'm done with it".

通常Cursor管理有以下三种方法:

  1. 在方法范围内声明 Cursor 并在 finally 块中关闭它
  2. 在具有生命周期的 class 范围内声明 Cursor,并作为特定生命周期事件的结果关闭它(例如,当 Activity 停止时关闭游标)
  3. 在实现Closable接口的class范围内声明Cursor,当包含class的close()方法时关闭它正在呼叫

通过快速查看您的代码,似乎没有必要 Cursor 在使用它的方法 return 之后保持打开状态,因此您应该考虑重构代码接近#1.