0

在严格模式下运行时,当手机的方向发生变化时,我的应用程序将因错误而崩溃

在附加的堆栈跟踪中获取了资源,但从未释放。有关避免资源泄漏的信息,请参阅 java.io.Closeable。java.lang.Throwable:未调用显式终止方法“关闭”

奇怪的是,如果我在调试模式下运行应用程序并在所有 cursor.close() 处放置断点只是为了确保它实际上被命中,所有断点都会被命中并且应用程序永远不会崩溃。

这是我的片段,它调用另一个包含所有 SqlBrite 查询和游标的类(为简洁起见,代码已缩短)。

public class MenuSummary extends Fragment{

private DbHelper dbHelper;
private Observable<?> income1, income2;
private Observable imin;
private Subscription s;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    dbHelper = new DbHelper(getContext());
}

@Override
public void onPause(){
    super.onPause();
    s.unsubscribe();
}

@Override
public void onResume(){
    super.onResume();
    displaySummary(selectedYear,selectedMonth);
}

@Override
public void onStop() {
    super.onStop();
}

@Override
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);
}

private void displaySummary(final int selectedYear, final int selectedMonth){

    income1 = dbHelper.getIncome(selectedYear,selectedMonth,1);
    income2 = dbHelper.getIncome(selectedYear,selectedMonth,2);

    List<Observable<?>> myObservables = Arrays.asList(income1,income2);
    imin = Observable.combineLatest(myObservables, new FuncN<List<BigDecimal>>() {
        @Override
        public List<BigDecimal> call(Object... args) {
            List<BigDecimal> listIncome = new ArrayList<~>();
            listIncome.add((BigDecimal) args[0]);
            listIncome.add((BigDecimal) args[1]);
            return listIncome ;
        }
    }
).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
s = imin.subscribe(new Action1<List<BigDecimal>>() {
@Override
public void call(List<BigDecimal> expensesAndBalance) {
    //do plenty of view.settext here
}});
}

下面是包含函数 getIncome 的 DbHelper 类的样子:

谁能指出我哪里出错了?

   public class DbHelper {

        private MySQLiteHelper mySQLiteHelper;
        SqlBrite sqlBrite = new SqlBrite.Builder().build();
        BriteDatabase briteDb;
        Subscription subscription;

        private static DbHelper instance;
        public DbHelper(Context context) {
            mySQLiteHelper = new MySQLiteHelper(context);
            sqlBrite = new SqlBrite.Builder().build();
            briteDb = sqlBrite.wrapDatabaseHelper(mySQLiteHelper,Schedulers.io());
        }

        public Observable<BigDecimal> getIncome(final int endYear, final int endMonth, final int moneyJar){
        final String[] args = new String[]{moneyJar + "", endYear + "", endMonth + "", endYear + "", };
        Observable<BigDecimal> myObservable;
        myObservable = briteDb.createQuery(MySQLiteHelper.TABLE_INCOME, "SELECT total FROM " + MySQLiteHelper.TABLE_INCOME +
                " WHERE moneyJar = ? AND ((year = ? AND month <= ?) OR (year < ?)) and isDeleted = 0", args)
                .map(new Func1<SqlBrite.Query, BigDecimal>() {
                    @Override
                    public BigDecimal call(SqlBrite.Query query) {
                        Cursor cursor = query.run();
                        BigDecimal income, incomeTotal = new BigDecimal(0);
                        if (cursor != null) {
                            try {
                                if (cursor.getCount() > 0 && cursor.moveToFirst()) {
                                    do {
                                        income = new BigDecimal(cursor.getString(cursor.getColumnIndex("total")));
                                        incomeTotal = incomeTotal.add(income);
                                    } while (cursor.moveToNext());
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                cursor.close();
                            }
                        }
                        return incomeTotal;
                    }
                });
        return myObservable;
    }
}
4

1 回答 1

1

您没有关闭您的BriteDatabase实例。

您应该在关闭片段时执行此操作:

briteDb.close();

文档

关闭底层 SQLiteOpenHelper 并移除缓存的可读可写数据库。这不会阻止现有的 observables 保留现有的引用以及尝试为新订阅创建新的引用。

于 2017-03-27T10:31:41.787 回答