我有一个实时应用程序,我遇到了一些我无法弄清楚的崩溃。当第一次安装应用程序时,它会从我的服务器上下载数据库并安装在设备上。
我无法在我的设备上复制这个,所以我留下来自Android控制台的堆栈跟踪。我安装了映射文件,因此它被去混淆了,但我无法确切地知道问题的确切位置。它给了我一堆方法,但我不知道哪个是问题发生的地方。任何帮助将不胜感激。
android.database.sqlite.SQLiteConstraintException: PRIMARY KEY must be unique (code 19)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:971)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1588)
at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1484)
at com.clashtoolkit.clashtoolkit.database.ArmyProvider.bulkInsert(ArmyProvider.java)
at android.content.ContentProvider$Transport.bulkInsert(ContentProvider.java:233)
at android.content.ContentResolver.bulkInsert(ContentResolver.java:1251)
at com.clashtoolkit.clashtoolkit.database.DataCreator.updateFullDbFromServer(DataCreator.java)
updateTableFromServer(DataCreator.java)
getValuesFromJsonObj(DataCreator.java)
addNewUser(DataCreator.java)
getGcmIdFromDb(DataCreator.java)
at com.clashtoolkit.clashtoolkit.database.DataCreator.updateFullDbFromServer(DataCreator.java)
updateTableFromServer(DataCreator.java)
getValuesFromJsonObj(DataCreator.java)
addNewUser(DataCreator.java)
getGcmIdFromDb(DataCreator.java)
at com.clashtoolkit.clashtoolkit.ui.MainBuilderActivity$1.onResponse(MainBuilderActivity.java)
at com.clashtoolkit.clashtoolkit.ui.MainBuilderActivity$1.onResponse(MainBuilderActivity.java)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java)
parseNetworkResponse(JsonRequest.java)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5584)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(NativeStart.java)
DataCreator.java
public class DataCreator {
// private static final String TAG = DataCreator.class.getSimpleName();
public static void updateFullDbFromServer(JSONObject jsonObj, Context context) {
Iterator<String> keys = jsonObj.keys();
while (keys.hasNext()) {
String tableName = keys.next();
try {
updateTableFromServer(jsonObj.getJSONArray(tableName), context, tableName);
} catch (JSONException e) {
e.printStackTrace();
}
}
setBaseTables(context);
}
private static void updateTableFromServer(JSONArray jsonArray, Context context, String tableName) {
ContentValues[] valuesArray = new ContentValues[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
try {
valuesArray[i] = getValuesFromJsonObj(jsonArray.getJSONObject(i));
} catch (JSONException e) {
e.printStackTrace();
}
}
Uri uri = ArmyContract.BASE_CONTENT_URI.buildUpon().appendPath(tableName).build();
context.getContentResolver().bulkInsert(uri, valuesArray);
}
private static ContentValues getValuesFromJsonObj(JSONObject jsonObj) {
ContentValues values = new ContentValues();
try {
Iterator<String> keys = jsonObj.keys();
while (keys.hasNext()) {
String key = keys.next();
if (jsonObj.get(key) instanceof String) {
values.put(key, jsonObj.getString(key));
} else {
values.put(key, jsonObj.getInt(key));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return values;
}
private static void setBaseTables(Context context) {
ContentValues[] valuesArray = new ContentValues[6];
valuesArray[0] = new ContentValues();
valuesArray[0].put(ArmyContract.DisplayArmy.BARRACKS, 1);
valuesArray[0].put(ArmyContract.DisplayArmy.OVERALL_TIME, "00:00:00");
valuesArray[0].put(ArmyContract.DisplayArmy.TYPE, "elixer");
valuesArray[1] = new ContentValues();
valuesArray[1].put(ArmyContract.DisplayArmy.BARRACKS, 2);
valuesArray[1].put(ArmyContract.DisplayArmy.OVERALL_TIME, "00:00:00");
valuesArray[1].put(ArmyContract.DisplayArmy.TYPE, "elixer");
valuesArray[2] = new ContentValues();
valuesArray[2].put(ArmyContract.DisplayArmy.BARRACKS, 3);
valuesArray[2].put(ArmyContract.DisplayArmy.OVERALL_TIME, "00:00:00");
valuesArray[2].put(ArmyContract.DisplayArmy.TYPE, "elixer");
valuesArray[3] = new ContentValues();
valuesArray[3].put(ArmyContract.DisplayArmy.BARRACKS, 4);
valuesArray[3].put(ArmyContract.DisplayArmy.OVERALL_TIME, "00:00:00");
valuesArray[3].put(ArmyContract.DisplayArmy.TYPE, "elixer");
valuesArray[4] = new ContentValues();
valuesArray[4].put(ArmyContract.DisplayArmy.BARRACKS, 1);
valuesArray[4].put(ArmyContract.DisplayArmy.OVERALL_TIME, "00:00:00");
valuesArray[4].put(ArmyContract.DisplayArmy.TYPE, "dark");
valuesArray[5] = new ContentValues();
valuesArray[5].put(ArmyContract.DisplayArmy.BARRACKS, 2);
valuesArray[5].put(ArmyContract.DisplayArmy.OVERALL_TIME, "00:00:00");
valuesArray[5].put(ArmyContract.DisplayArmy.TYPE, "dark");
//base row for the current army values table
ContentValues currentArmyValues = new ContentValues();
currentArmyValues.put(ArmyContract.CustomArmyValues.ARMY_NAME, "current");
//base row for current army totals table
ContentValues currentArmyTotals = new ContentValues();
currentArmyTotals.put(ArmyContract.CurrentArmyTotals._ID, 1);
context.getContentResolver().bulkInsert(ArmyContract.DisplayArmy.CONTENT_URI, valuesArray);
context.getContentResolver().insert(ArmyContract.CustomArmyValues.CONTENT_URI, currentArmyValues);
context.getContentResolver().insert(ArmyContract.CurrentArmyTotals.CONTENT_URI, currentArmyTotals);
}
public static void addNewUser(int userId, String token, Context context) {
ContentValues values = new ContentValues();
values.put("main_id", userId);
values.put("gcm_id", token);
values.put("created_on", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
context.getContentResolver().insert(Users.CONTENT_URI, values);
}
public static String getGcmIdFromDb(Context context) {
String gcmId = "";
String[] columns = {"gcm_id"};
String whereClause = "_id=?";
String[] args = {"1"};
Cursor cursor = context.getContentResolver().query(Users.CONTENT_URI, columns, whereClause, args, null);
if (cursor != null && cursor.moveToFirst()) {
gcmId = cursor.getString(0);
cursor.close();
return gcmId;
} else {
return gcmId;
}
}
}
DBHelper.java
final String SQL_CREATE_USERS_TABLE = "CREATE TABLE " + Users.TABLE_NAME + " (" +
Users._ID + " INTEGER PRIMARY KEY," +
Users.MAIN_ID + " INTEGER, " +
Users.GCM_ID + " INTEGER, " +
Users.WEB_KEY + " TEXT, " +
Users.NICKNAME + " TEXT," +
Users.EMAIL + " TEXT," +
Users.CREATED_ON + " TEXT NOT NULL, " +
Users.CLAN_ID + " INTEGER, " +
Users.CLAN_POSITION + " INTEGER " +
");";
final String SQL_CREATE_CUSTOM_ARMY_VALUES = " CREATE TABLE " + CustomArmyValues.CUSTOM_ARMY_VALUES + " (" +
CustomArmyValues._ID + " INTEGER PRIMARY KEY, " +
CustomArmyValues.ARMY_NAME + " TEXT NOT NULL, " +
CustomArmyValues.USER_NAME + " TEXT, " +
CustomArmyValues.BARBARIAN + " INTEGER, " +
CustomArmyValues.ARCHER + " INTEGER, " +
CustomArmyValues.GIANT + " INTEGER, " +
CustomArmyValues.GOBLIN + " INTEGER, " +
CustomArmyValues.WALL_BREAKER + " INTEGER, " +
CustomArmyValues.BALLOON + " INTEGER, " +
CustomArmyValues.WIZARD + " INTEGER, " +
CustomArmyValues.HEALER + " INTEGER, " +
CustomArmyValues.DRAGON + " INTEGER, " +
CustomArmyValues.PEKKA + " INTEGER, " +
CustomArmyValues.MINION + " INTEGER, " +
CustomArmyValues.HOG_RIDER + " INTEGER, " +
CustomArmyValues.VALKYRIE + " INTEGER, " +
CustomArmyValues.GOLEM + " INTEGER, " +
CustomArmyValues.WITCH + " INTEGER, " +
CustomArmyValues.LAVA_HOUND + " INTEGER, " +
CustomArmyValues.BOWLER + " INTEGER, " +
CustomArmyValues.BABY_DRAGON + " INTEGER, " +
CustomArmyValues.MINER + " INTEGER, " +
CustomArmyValues.LIGHTNING + " INTEGER, " +
CustomArmyValues.HEAL + " INTEGER, " +
CustomArmyValues.RAGE + " INTEGER, " +
CustomArmyValues.JUMP + " INTEGER, " +
CustomArmyValues.FREEZE + " INTEGER, " +
CustomArmyValues.CLONE + " INTEGER, " +
CustomArmyValues.POISON + " INTEGER, " +
CustomArmyValues.EARTHQUAKE + " INTEGER, " +
CustomArmyValues.HASTE + " INTEGER, " +
CustomArmyValues.SKELETON + " INTEGER, " +
CustomArmyValues.TOWN_HALL_REQ + " INTEGER, " +
CustomArmyValues.ARMY_TYPE + " TEXT, " +
CustomArmyValues.UPDATED + " TEXT " +
");";
final String SQL_CREATE_CURRENT_ARMY_TOTALS = " CREATE TABLE " + CurrentArmyTotals.CURRENT_ARMY_TOTALS + " (" +
CurrentArmyTotals._ID + " INTEGER PRIMARY KEY, " +
CurrentArmyTotals.ELIXER_TROOP_COST + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.ELIXER_SPELL_COST + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.DE_TROOP_COST + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.DE_SPELL_COST + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.ELIXER_TOTAL_TIME + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.DE_TOTAL_TIME + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.SPELL_TOTAL_TIME + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.HERO_TIME + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.ELIXER_TROOP_COUNT + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.DARK_TROOP_COUNT + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.SPELL_COUNT + " INTEGER DEFAULT 0, " +
CurrentArmyTotals.CAMP_CAPACITY + " INTEGER DEFAULT 240, " +
CurrentArmyTotals.FACTORY_CAPACITY + " INTEGER DEFAULT 11 " +
");";
final String SQL_CREATE_HERO_LEVEL = " CREATE TABLE " + ArmyContract.HeroLevel.HERO_LEVEL + " (" +
HeroLevel._ID + " INTEGER PRIMARY KEY, " +
HeroLevel.NAME + " TEXT NOT NULL, " +
HeroLevel.LEVEL + " INTEGER NOT NULL, " +
HeroLevel.REGEN_TIME + " INTEGER NOT NULL, " +
HeroLevel.UPDATED + " TEXT NOT NULL " +
");";
final String SQL_CREATE_DISPLAY_ARMY = " CREATE TABLE " + DisplayArmy.DISPLAY_ARMY + " (" +
DisplayArmy._ID + " INTEGER PRIMARY KEY, " +
DisplayArmy.BARRACKS + " INTEGER NOT NULL, " +
DisplayArmy.TYPE + " TEXT NOT NULL, " +
DisplayArmy.BARBARIAN + " INTEGER DEFAULT 0, " +
DisplayArmy.ARCHER + " INTEGER DEFAULT 0, " +
DisplayArmy.GIANT + " INTEGER DEFAULT 0, " +
DisplayArmy.GOBLIN + " INTEGER DEFAULT 0, " +
DisplayArmy.WALL_BREAKER + " INTEGER DEFAULT 0, " +
DisplayArmy.BALLOON + " INTEGER DEFAULT 0, " +
DisplayArmy.WIZARD + " INTEGER DEFAULT 0, " +
DisplayArmy.HEALER + " INTEGER DEFAULT 0, " +
DisplayArmy.DRAGON + " INTEGER DEFAULT 0, " +
DisplayArmy.PEKKA + " INTEGER DEFAULT 0, " +
DisplayArmy.BABY_DRAGON + " INTEGER DEFAULT 0, " +
DisplayArmy.MINER + " INTEGER DEFAULT 0, " +
DisplayArmy.MINION + " INTEGER DEFAULT 0, " +
DisplayArmy.HOG_RIDER + " INTEGER DEFAULT 0, " +
DisplayArmy.VALKYRIE + " INTEGER DEFAULT 0, " +
DisplayArmy.GOLEM + " INTEGER DEFAULT 0, " +
DisplayArmy.WITCH + " INTEGER DEFAULT 0, " +
DisplayArmy.LAVA_HOUND + " INTEGER DEFAULT 0, " +
DisplayArmy.BOWLER + " INTEGER DEFAULT 0, " +
DisplayArmy.OVERALL_TIME + " TEXT " +
" );";
final String SQL_CREATE_BUILDABLE = " CREATE TABLE " + Buildable.BUILDABLE + " (" +
Buildable._ID + " INTEGER PRIMARY KEY, " +
Buildable.NAME + " TEXT NOT NULL, " +
Buildable.BUILD_TIME + " INTEGER NOT NULL, " +
Buildable.BUILDER_SPACE + " INTEGER NOT NULL, " +
Buildable.BUILDER_REQ + " INTEGER NOT NULL, " +
Buildable.CURRENT_LEVEL + " INTEGER DEFAULT 1, " +
Buildable.LEVEL_COUNT + " INTEGER NOT NULL, " +
Buildable.ELIXER_TYPE + " TEXT NOT NULL, " +
Buildable.BUILDABLE_TYPE + " TEXT NOT NULL, " +
Buildable.UPDATED + " TEXT NOT NULL " +
" );";
final String SQL_CREATE_BUILDABLE_LEVEL = " CREATE TABLE " + BuildableLevel.BUILDABLE_LEVEL + " (" +
BuildableLevel._ID + " INTEGER PRIMARY KEY, " +
BuildableLevel.LEVEL + " INTEGER NOT NULL, " +
BuildableLevel.BUILDABLE_ID + " INTEGER NOT NULL, " +
BuildableLevel.BUILD_COST + " INTEGER NOT NULL, " +
BuildableLevel.UPDATED + " TEXT NOT NULL " +
" );";
final String SQL_CREATE_BUILDER = " CREATE TABLE " + Builder.BUILDER + " (" +
Builder._ID + " INTEGER PRIMARY KEY, " +
Builder.CURRENT_LEVEL + " INTEGER NOT NULL DEFAULT 0, " +
Builder.CURRENT_BOOST + " INTEGER NOT NULL DEFAULT 0, " +
Builder.BUILDER_TYPE + " TEXT NOT NULL, " +
Builder.ELIXER_TYPE + " TEXT NOT NULL, " +
Builder.LEVEL_COUNT + " INTEGER NOT NULL, " +
Builder.UPDATED + " TEXT NOT NULL " +
" );";
final String SQL_CREATE_BUILDER_LEVEL = " CREATE TABLE " + ArmyContract.BuilderLevel.BUILDER_LEVEL + " (" +
BuilderLevel._ID + " INTEGER PRIMARY KEY, " +
BuilderLevel.LEVEL + " INTEGER NOT NULL DEFAULT 0," +
BuilderLevel.CAPACITY + " INTEGER NOT NULL, " +
BuilderLevel.BUILDER_TYPE + " TEXT NOT NULL, " +
BuilderLevel.ELIXER_TYPE + " TEXT NOT NULL, " +
BuilderLevel.UPDATED + " TEXT NOT NULL " +
" );";
final String SQL_CREATE_CONTAINER = " CREATE TABLE " + Container.CONTAINER + " (" +
Container._ID + " INTEGER PRIMARY KEY, " +
Container.CURRENT_LEVEL + " INTEGER NOT NULL DEFAULT 0, " +
Container.LEVEL_COUNT + " INTEGER NOT NULL, " +
Container.ARMY_OBJ_TYPE + " TEXT NOT NULL, " +
Container.UPDATED + " TEXT NOT NULL " +
" );";
final String SQL_CREATE_CONTAINER_LEVEL = " CREATE TABLE " + ContainerLevel.CONTAINER_LEVEL + " (" +
ContainerLevel._ID + " INTEGER PRIMARY KEY, " +
ContainerLevel.LEVEL + " INTEGER NOT NULL, " +
ContainerLevel.CAPACITY + " INTEGER NOT NULL, " +
ContainerLevel.ARMY_OBJ_TYPE + " TEXT NOT NULL, " +
ContainerLevel.UPDATED + " TEXT NOT NULL " +
" );";
final String SQL_CREATE_HEROES = " CREATE TABLE " + ArmyContract.Heroes.HEROES + " (" +
ArmyContract.Heroes._ID + " INTEGER PRIMARY KEY, " +
ArmyContract.Heroes.CURRENT_LEVEL + " INTEGER NOT NULL DEFAULT 1, " +
ArmyContract.Heroes.CURRENT_BOOST + " INTEGER NOT NULL, " +
ArmyContract.Heroes.NAME + " TEXT NOT NULL, " +
ArmyContract.Heroes.LEVEL_COUNT + " INTEGER NOT NULL, " +
ArmyContract.Heroes.UPDATED + " TEXT NOT NULL " +
" );";
final String SQL_CREATE_LIKED = " CREATE TABLE " + ArmyContract.LikedArmies.LIKED_ARMIES + " (" +
ArmyContract.LikedArmies._ID + " INTEGER PRIMARY KEY, " +
ArmyContract.LikedArmies.ARMY_ID + " INTEGER " +
" );";
final String SQL_CREATE_TABLE_VERSION = " CREATE TABLE " + ArmyContract.TableVersion.TABLE_VERSION + " (" +
ArmyContract.TableVersion._ID + " INTEGER PRIMARY KEY, " +
ArmyContract.TableVersion.TABLE_NAME + " TEXT NOT NULL, " +
ArmyContract.TableVersion.VERSION + " INTEGER NOT NULL, " +
ArmyContract.TableVersion.UPDATED + " TEXT NOT NULL " +
" );";