Приложение неожиданно аварийно с исключением sqlite [дубликат]

Math.sum (javascript) .... вид замещения оператора

.1 + .0001 + -.1 --> 0.00010000000000000286
Math.sum(.1 , .0001, -.1) --> 0.0001

Object.defineProperties(Math, {
    sign: {
        value: function (x) {
            return x ? x < 0 ? -1 : 1 : 0;
            }
        },
    precision: {
        value: function (value, precision, type) {
            var v = parseFloat(value), 
                p = Math.max(precision, 0) || 0, 
                t = type || 'round';
            return (Math[t](v * Math.pow(10, p)) / Math.pow(10, p)).toFixed(p);
        }
    },
    scientific_to_num: {  // this is from https://gist.github.com/jiggzson
        value: function (num) {
            //if the number is in scientific notation remove it
            if (/e/i.test(num)) {
                var zero = '0',
                        parts = String(num).toLowerCase().split('e'), //split into coeff and exponent
                        e = parts.pop(), //store the exponential part
                        l = Math.abs(e), //get the number of zeros
                        sign = e / l,
                        coeff_array = parts[0].split('.');
                if (sign === -1) {
                    num = zero + '.' + new Array(l).join(zero) + coeff_array.join('');
                } else {
                    var dec = coeff_array[1];
                    if (dec)
                        l = l - dec.length;
                    num = coeff_array.join('') + new Array(l + 1).join(zero);
                }
            }
            return num;
         }
     }
    get_precision: {
        value: function (number) {
            var arr = Math.scientific_to_num((number + "")).split(".");
            return arr[1] ? arr[1].length : 0;
        }
    },
    diff:{
        value: function(A,B){
            var prec = this.max(this.get_precision(A),this.get_precision(B));
            return +this.precision(A-B,prec);
        }
    },
    sum: {
        value: function () {
            var prec = 0, sum = 0;
            for (var i = 0; i < arguments.length; i++) {
                prec = this.max(prec, this.get_precision(arguments[i]));
                sum += +arguments[i]; // force float to convert strings to number
            }
            return Math.precision(sum, prec);
        }
    }
});

Идея состоит в том, чтобы вместо Math вместо Math использовать ошибки плавания

Math.diff(0.2, 0.11) == 0.09 // true
0.2 - 0.11 == 0.09 // false

также отмечают, что Math.diff и Math.sum автоматически определяют точность использования

. Math.sum принимает любое количество аргументов

12
задан AWT 29 January 2016 в 20:22
поделиться

5 ответов

У меня есть аналогичная проблема, которая действительно раздражает то, что это происходит в любое время, трудно воспроизвести точные условия, которые делают это возможным. Я только закрываю DDBB в методе ondestroy класса MainActivity. То, что я сделал, это добавить try / catch при каждом использовании db и добавить следующий catch, в этом случае он находится в середине цикла while, в других функциях я вызываю функцию снова один раз:

catch (SQLException e) {
    e.printStackTrace();
    Log.d(TAG, "MainService: error in AccSaveToDB with "+mainDB.getPath()+" in iteration "+j+". Closing and re-opening DB");
    DBHelper.close();
    mainDB.close();
    j--;
}

И это в начале каждой функции, которая обращается к базе данных:

if (mainDB==null || !mainDB.isOpen()) {
    DBHelper = DefSQLiteHelper.getInstance(getApplicationContext(), "Data.db", null, 1);
    mainDB = DBHelper.getWritableDatabase();
}

До сих пор у меня до сих пор есть эта ошибка, я еще не мог понять причину, но по крайней мере, мое приложение не разбивается, и оно возобновляет то, что он должен делать. Я не вижу, удаляется ли файл, но эти решения работают для меня

0
ответ дан Ale 29 August 2018 в 02:37
поделиться

Таким образом, первопричина этого, на первый взгляд, появляется в сторонней библиотеке. Если я не ошибаюсь, Tagit от Mobeix удаляет базу данных при запуске приложения. Я добавил подробное ведение журнала SQLite, включая следующие политики:

    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
    .detectLeakedSqlLiteObjects()
    .detectLeakedClosableObjects()
    .penaltyLog()
    .penaltyDeath()
    .build());

В журнале я заметил, что после того, как я создал и открываю мою базу данных, я отсоединяюсь. Более подробное ведение журнала указывает, что это происходит, когда библиотека Mobeix инициализируется. Оскорбительная строка:

01-29 13:47:49.118: W/SQLiteLog(12120): (28) file unlinked while open: /data/user/0/com.company.app/databases/MyDatabase.db

Так что мой файл базы данных отсоединен. Weird. Следующий вызов getWritableDatabase () воссоздает его снова, и тогда это нормально, пока приложение не будет убито и перезапущено, после чего оно будет удалено и восстановлено.

Я обновлю это, если когда-либо выясню точно , что вызывает unlink.

1
ответ дан AWT 29 August 2018 в 02:37
поделиться

Я придерживаюсь более или менее точно такой же проблемы, и я обнаружил открытый дефект по этому вопросу, который имеет смысл ...

https://code.google.com / p / android / issues / detail? id = 174566

Мое обходное решение - пусть и не самое лучшее решение - состоит в том, чтобы никогда не менять ревизию базы данных и не отслеживать ее самостоятельно, поэтому никогда не вызывайте onUpgrade() , и вручную обновлять приложение при обновлении.

Альтернативно, если у вас есть небольшая БД, которая доступна только для чтения, вы можете инициировать копирование db в активах на каждом onCreate() в классе DBHelper , но это может привести к нежелательным проблемам, если файловая система заполнена, поэтому делайте это только при поиске лучшего решения.

@Override
public void onCreate(SQLiteDatabase db) {
    // Workaround for Issue 174566
    myContext.deleteDatabase(DB_NAME);
    try {
        copyDataBase();
    }
    catch(IOException e) {
        System.out.println("IOException " + e.getLocalizedMessage());
    }
}

Мое приложение теперь обновляется, как и должно быть, с моим обходным решением и, судя, потому что этот дефект первоначально был поднят, он вообще никогда не может быть исправлен ...

Извините, что это не полное решение проблемы, но это, по крайней мере, путь вперед.

1
ответ дан General Failure 29 August 2018 в 02:37
поделиться

У меня была аналогичная проблема. Тем не менее, я целенаправленно удалял текущую базу данных как часть восстановления.

Я думаю, что SQLite помещает базу данных как прочитанную только для обеспечения защиты от file unlinked while open:.

После восстановления любые обновления сбой attempt to write a readonly database (code 1032).

Мое решение состояло в том, чтобы восстановить DBHelper. Я сделал это, добавив метод reopen, который я вызываю.

, например.

    public static void reopen(Context context) {
        instance = new DBHelper(context);
    }

Затем я вызываю / вызываю это с помощью

                if(copytaken && origdeleted && restoredone) {
                    DBHelper.reopen(context);
                    DBHelper.getHelper(context).expand(null,true);
                }

. Вызов метода expand - это мой эквивалент / getaround для onUpgrade / versions. Он добавляет таблицы и столбцы в соответствии с псевдосхемой, сравниваемой с фактической базой данных.

Полный DBHelper: -

/**
 * DBHelper
 */
@SuppressWarnings("WeakerAccess")
class DBHelper extends SQLiteOpenHelper {

    private static final String LOGTAG = "SW-DBHelper";
    private static final String DBNAME = DBConstants.DATABASE_NAME;
    private static final String dbcreated =
            "001I Database " + DBNAME + " created.";
    private static final String dbunusable =
            "002E Database " + DBNAME +
            " has been set as unusable (according to schema).";
    private   static final String dbexpanded =
            "003I Database " + DBNAME + " expanded.";
    private static final String dbexpandskipped =
            "004I Database " + DBNAME + " expand skipped - nothing to alter.";
    private static final String dbbuildskipped =
            "005I Database" + DBNAME + " build skipped - no tables to add";
    public static final String THISCLASS = DBHelper.class.getSimpleName();

    /**
     * Consrtuctor
     *
     * @param context activity context
     * @param name    database name
     * @param factory cursorfactory
     * @param version database version
     */
    DBHelper(Context context, @SuppressWarnings("SameParameterValue") String name, @SuppressWarnings("SameParameterValue") SQLiteDatabase.CursorFactory factory, @SuppressWarnings("SameParameterValue") int version) {
        super(context, name, factory, version);
    }

    /**
     * Instantiates a new Db helper.
     *
     * @param context the context
     */
    DBHelper(Context context) {
        super(context, DBConstants.DATABASE_NAME, null, 1);
    }

    private static DBHelper instance;

    /**
     * Gets helper.
     *
     * @param context the context
     * @return the helper
     */
    static synchronized DBHelper getHelper(Context context) {
        if(instance == null) {
            instance = new DBHelper(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        expand(db, false);
    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {

    }

    /**
     * expand create database tables
     *
     * @param db             SQLIte Database, if null then instance is used
     * @param buildandexpand to attempt both create and expand
     */
    void expand(SQLiteDatabase db, boolean buildandexpand) {

        String mode = "Create Mode.";
        if (buildandexpand) {
            mode = "Expand Mode.";
        }
        String msg = mode;
        String methodname = new Object(){}.getClass().getEnclosingMethod().getName();
        LogMsg.LogMsg(LogMsg.LOGTYPE_INFORMATIONAL,LOGTAG,msg,THISCLASS,methodname);
        // if no database has been passed then get the database
        if(db == null) {
            db = instance.getWritableDatabase();
        }
        // Build Tables to reflect schema (SHOPWISE) only if schema is usable
        if(DBConstants.SHOPWISE.isDBDatabaseUsable()) {
            // Check to see if any tables need to be added
            ArrayList<String> buildsql = DBConstants.SHOPWISE.generateDBBuildSQL(db);
            if (!buildsql.isEmpty()) {
                DBConstants.SHOPWISE.actionDBBuildSQL(db);
                msg = dbcreated + buildsql.size() + " tables added.";
                LogMsg.LogMsg(LogMsg.LOGTYPE_INFORMATIONAL,LOGTAG,msg,THISCLASS,methodname);
            } else {
                msg = dbbuildskipped;
                LogMsg.LogMsg(LogMsg.LOGTYPE_INFORMATIONAL,LOGTAG,msg,THISCLASS,methodname);
            }
            if(buildandexpand) {
                ArrayList<String> altersql = DBConstants.SHOPWISE.generateDBAlterSQL(db);
                if(!altersql.isEmpty()) {
                    msg = dbexpanded + altersql.size() + " columns added.";
                    LogMsg.LogMsg(LogMsg.LOGTYPE_INFORMATIONAL,LOGTAG,msg,THISCLASS,methodname);
                    DBConstants.SHOPWISE.actionDBAlterSQL(db);
                }  else {
                    msg = dbexpandskipped;
                    LogMsg.LogMsg(LogMsg.LOGTYPE_INFORMATIONAL,LOGTAG,msg,THISCLASS,methodname);
                }
            }
        } else {
            msg = dbunusable + "\n" +
                    DBConstants.SHOPWISE.getAllDBDatabaseProblemMsgs();
            LogMsg.LogMsg(LogMsg.LOGTYPE_ERROR,LOGTAG,msg,THISCLASS,methodname);
        }
    }
    public static void reopen(Context context) {
        instance = new DBHelper(context);
    }
}
0
ответ дан MikeT 29 August 2018 в 02:37
поделиться

У меня была та же проблема. Я нашел самый простой способ использовать enableWriteAheadLogging () в объекте базы данных.

databaseObject.enableWriteAheadLogging()
0
ответ дан Sam Joos 29 August 2018 в 02:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: