在将目录从旧计算机复制到新计算机之前,我的项目正在运行。
这是我的logcat:
06-15 22:28:03.169 3205-3205/com.example.moric.pronostic W/System: ClassLoader referenced unknown path: /data/app/com.example.moric.pronostic-2/lib/x86
06-15 22:28:03.674 3205-3205/com.example.moric.pronostic W/System: ClassLoader referenced unknown path: /data/app/com.example.moric.pronostic-2/lib/x86
06-15 22:28:03.830 3205-3205/com.example.moric.pronostic W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
06-15 22:28:03.860 3205-3205/com.example.moric.pronostic E/SQLiteLog: (1) unknown column "betUser" in foreign key definition
06-15 22:28:03.872 3205-3205/com.example.moric.pronostic D/AndroidRuntime: Shutting down VM
--------- beginning of crash
06-15 22:28:03.872 3205-3205/com.example.moric.pronostic E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.moric.pronostic, PID: 3205
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.moric.pronostic/com.example.moric.pronostic.MainActivity}: android.database.sqlite.SQLiteException: unknown column "betUser" in foreign key definition (code 1): , while compiling: CREATE TABLE betsTable (betId INTEGER PRIMARY KEY AUTOINCREMENT, betScore TEXT, FOREIGN KEY(betUser) REFERENCES userTable(userId), FOREIGN KEY(betMatch) REFERENCES matchTable(id));
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.database.sqlite.SQLiteException: unknown column "betUser" in foreign key definition (code 1): , while compiling: CREATE TABLE betsTable (betId INTEGER PRIMARY KEY AUTOINCREMENT, betScore TEXT, FOREIGN KEY(betUser) REFERENCES userTable(userId), FOREIGN KEY(betMatch) REFERENCES matchTable(id));
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
at com.example.moric.pronostic.DataBaseHandler.onCreate(DataBaseHandler.java:17)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.example.moric.pronostic.MatchDataBase.openDb(MatchDataBase.java:33)
at com.example.moric.pronostic.MainActivity.onCreate(MainActivity.java:29)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
以下是我的 MainActivity ,它在没有openDb()
和closeDb()
功能的情况下运行,我已对其进行了测试。在我的代码中没有使用数据库是正常的,这是一个测试。
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Vector;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Création de la base de données
MatchDataBase matchDataBase = new MatchDataBase(this);
Vector<Match> matchList = new Vector<Match>();
matchList.addElement(new Match(1, "France", "Roumanie", "10/06/2016 - 15h00", new Score(2, 1), "Poule A"));
matchList.addElement(new Match(2, "France", "Irlande", "12/06/2016 - 11h00", new Score(1, 0), "Quarts"));
matchList.addElement(new Match(3, "France", "Allemagne", "15/06/2016 - 15h30", "Demi-finale"));
matchList.addElement(new Match(4, "France", "Angleterre", "18/06/2016 - 18h00", "Finale"));
matchDataBase.openDb();
matchDataBase.closeDb();
}
}
这是我的 DataBaseHandler (扩展SQLiteOpenHelper的类):
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseHandler extends SQLiteOpenHelper {
public DataBaseHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE_MATCH_CREATE);
db.execSQL(TABLE_USER_CREATE);
db.execSQL(TABLE_BETS_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(TABLE_MATCH_DROP);
db.execSQL(TABLE_USER_DROP);
db.execSQL(TABLE_BETS_DROP);
onCreate(db);
}
//Caractéristiques de la table relative aux Matches, indépendants des utilisateurs
public static final String TABLE_MATCH = "matchTable";
public static final String MATCH_KEY = "id";
public static final String DATE = "date";
public static final String INFO = "info";
public static final String SCORE = "score";
public static final String TEAMDOM = "teamDom";
public static final String TEAMEXT = "teamExt";
public static final String TABLE_MATCH_CREATE = "CREATE TABLE " + TABLE_MATCH + " ("
+ MATCH_KEY + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ DATE + " TEXT, "
+ INFO + " TEXT, "
+ SCORE + " TEXT, "
+ TEAMDOM + " TEXT, "
+ TEAMEXT + " TEXT);";
public static final String TABLE_MATCH_DROP = "DROP TABLE IF EXISTS " + TABLE_MATCH + ";";
//Caractéristiques de la table relative aux Utilisateurs
public static final String TABLE_USER= "userTable";
public static final String USER_KEY = "userId";
public static final String USERNAME = "userName";
public static final String TABLE_USER_CREATE = "CREATE TABLE " + TABLE_USER + " ("
+ USER_KEY + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ USERNAME + " TEXT); ";
public static final String TABLE_USER_DROP = "DROP TABLE IF EXISTS " + TABLE_USER + ";";
//Caractéristiques de la table relative aux Pronostics
public static final String TABLE_BETS= "betsTable";
public static final String BET_KEY = "betId";
public static final String BET_SCORE = "betScore";
public static final String BET_USER = "betUser";
public static final String BET_MATCH = "betMatch";
public static final String TABLE_BETS_CREATE = "CREATE TABLE " + TABLE_BETS + " ("
+ BET_KEY + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ BET_SCORE + " TEXT, "
+ BET_USER + "INTEGER, "
+ BET_MATCH + "INTEGER, "
+ "FOREIGN KEY(" + BET_USER + ") REFERENCES " + TABLE_USER + "(" + USER_KEY + "), "
+ "FOREIGN KEY(" + BET_MATCH + ") REFERENCES " + TABLE_MATCH + "(" + MATCH_KEY + ")); ";
public static final String TABLE_BETS_DROP = "DROP TABLE IF EXISTS " + TABLE_BETS + ";";
}
这是我的数据库类:
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Nullable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Vector;
public class MatchDataBase {
private final static int VERSION = 1;
private final static String NOM = "matches.db";
private static SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy' - 'HH'h'mm");
private SQLiteDatabase mDb;
private DataBaseHandler mHandler;
public SQLiteDatabase getDb() {
return mDb;
}
//Méthodes de création, d'ouverture et de fermeture de la base de données.
public MatchDataBase(Context pContext) {
this.mHandler = new DataBaseHandler(pContext, NOM, null, VERSION);
}
public void openDb() {
//Pour ouvrir l'accès à la base de données.
//getWritableDatabase ferme également la dernière base.
this.mDb = this.mHandler.getWritableDatabase();
}
public void closeDb() {
//Pour fermer l'accès à la base de données.
this.mDb.close();
}
//Caractéristiques de la table des matches.
private static final String TABLE_MATCH = "matchTable";
private static final String MATCH_KEY = "id";
private static final int NUM_COL_MATCH_KEY = 0;
private static final String TEAMDOM = "teamDom";
private static final int NUM_COL_TEAMDOM = 1;
private static final String TEAMEXT = "teamExt";
private static final int NUM_COL_TEAMEXT = 2;
private static final String DATE = "date";
private static final int NUM_COL_DATE = 3;
private static final String SCORE = "score";
private static final int NUM_COL_SCORE = 4;
private static final String INFO = "info";
private static final int NUM_COL_INFO = 5;
//Fonctions de la table des matches
//Cette fonction permet d'ajouter un match à la base de données.
public void addMatch(Match match) {
ContentValues value = new ContentValues();
value.put(MatchDataBase.MATCH_KEY, match.getId());
value.put(MatchDataBase.DATE, match.getDate());
value.put(MatchDataBase.INFO, match.getInfo());
value.put(MatchDataBase.SCORE, match.getScore().toString());
value.put(MatchDataBase.TEAMDOM, match.getTeamDom());
value.put(MatchDataBase.TEAMEXT, match.getTeamExt());
//L'on veut que le match déterminé remplace le précédent, donc on supprime celui qui existait déjà.
this.deleteMatch(match.getId());
mDb.insert(MatchDataBase.TABLE_MATCH, null, value);
}
//Cette fonction permet de supprimer un match de la base de données.
public void deleteMatch(long id) {
mDb.delete(TABLE_MATCH, MATCH_KEY + " = ?", new String[]{String.valueOf(id)});
}
//Cette fonction permet de modifier les informations d'un match, connaissant son ID.
public void updateMatch(Match match) {
ContentValues value = new ContentValues();
value.put(MatchDataBase.DATE, match.getDate());
value.put(MatchDataBase.INFO, match.getInfo());
value.put(MatchDataBase.SCORE, match.getScore().toString());
value.put(MatchDataBase.TEAMDOM, match.getTeamDom());
value.put(MatchDataBase.TEAMEXT, match.getTeamExt());
mDb.update(TABLE_MATCH, value, MATCH_KEY + " = ?", new String[]{String.valueOf(match.getId())});
}
@Nullable //Cette fonction permet de récupérer la première ligne d'un cursor sous la forme d'un objet java de la classe Match.
private Match cursorToMatch(Cursor c) {
if (c.getCount() == 0) {
return null;
}
//On se place au premier élément
c.moveToFirst();
Match returnedMatch = new Match();
returnedMatch.setId(c.getLong(NUM_COL_MATCH_KEY));
returnedMatch.setTeamDom(c.getString(NUM_COL_TEAMDOM));
returnedMatch.setTeamExt(c.getString(NUM_COL_TEAMEXT));
returnedMatch.setDate(c.getString(NUM_COL_DATE));
String writtenScore = c.getString(NUM_COL_SCORE);
returnedMatch.setScore(Score.convertStringToScore(writtenScore));
returnedMatch.setInfo(c.getString(NUM_COL_INFO));
c.close();
return returnedMatch;
}
//Cette fonction permet de récupérer un match à partir de son ID.
public Match getMatchWithId(long id) {
Cursor c = mDb.query(TABLE_MATCH, new String[]{MATCH_KEY, TEAMDOM, TEAMEXT, DATE, SCORE, INFO},
MATCH_KEY + "= ?", new String[]{String.valueOf(id)}, null, null, null);
return cursorToMatch(c);
}
//Cette fonction permet de récupérer tous les matches qui auront lieu après une date donnée, dans une table de type ArrayList déjà créée.
public void getMatchesAfterDate(String currentDateString, ArrayList<Match> listToComplete) {
Date currentDate = new Date();
Cursor c = mDb.query(TABLE_MATCH, new String[]{MATCH_KEY, TEAMDOM, TEAMEXT, DATE, SCORE, INFO},
null, null, null, null, null);
try {
currentDate = dateFormat.parse(currentDateString);
} catch (ParseException e) {
e.printStackTrace();
}
if (c.getCount() == 0) {
}
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
try {
Date dateMatch = dateFormat.parse(c.getString(NUM_COL_DATE));
if (dateMatch.after(currentDate)){
Match thisMatch = new Match();
thisMatch.setId(c.getLong(NUM_COL_MATCH_KEY));
thisMatch.setTeamDom(c.getString(NUM_COL_TEAMDOM));
thisMatch.setTeamExt(c.getString(NUM_COL_TEAMEXT));
thisMatch.setDate(c.getString(NUM_COL_DATE));
String writtenScore = c.getString(NUM_COL_SCORE);
thisMatch.setScore(Score.convertStringToScore(writtenScore));
thisMatch.setInfo(c.getString(NUM_COL_INFO));
listToComplete.add(thisMatch);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
c.close();
}
//Caractéristiques de la table des utilisateurs.
public static final String TABLE_USER= "userTable";
public static final String USER_KEY = "userId";
private static final int NUM_COL_USER_KEY = 0;
public static final String USERNAME = "userName";
private static final int NUM_COL_USERNAME = 1;
//Fonctions de la table des utilisateurs.
//Cette fonction permet d'ajouter un utilisateur à la base de données.
public void addUser(User user) {
ContentValues value = new ContentValues();
value.put(MatchDataBase.USER_KEY, user.getUserId());
value.put(MatchDataBase.USERNAME, user.getUserName());
this.deleteUser(user.getUserId());
mDb.insert(MatchDataBase.TABLE_USER, null, value);
}
//Cette fonction permet de supprimer un match de la base de données.
public void deleteUser(long id) {
mDb.delete(TABLE_USER, USER_KEY + " = ?", new String[]{String.valueOf(id)});
}
//Cette fonction permet de modifier les informations d'un utilisateur, connaissant son ID.
public void updateUser(User user) {
ContentValues value = new ContentValues();
value.put(MatchDataBase.USERNAME, user.getUserName());
mDb.update(TABLE_USER, value, USER_KEY + " = ?", new String[]{String.valueOf(user.getUserId())});
}
@Nullable //Cette fonction permet de récupérer la première ligne d'un cursor sous la forme d'un objet java de la classe User.
private User cursorToUser(Cursor c) {
if (c.getCount() == 0) {
return null;
}
//On se place au premier élément
c.moveToFirst();
User returnedUser = new User();
returnedUser.setUserId(c.getLong(NUM_COL_USER_KEY));
returnedUser.setUserName(c.getString(NUM_COL_USERNAME));
c.close();
return returnedUser;
}
//Cette fonction permet de récupérer un utilisateur à partir de son ID.
public User getUserWithId(long id) {
Cursor c = mDb.query(TABLE_USER, new String[]{USER_KEY, USERNAME},
USER_KEY + "= ?", new String[]{String.valueOf(id)}, null, null, null);
return cursorToUser(c);
}
//Caractéristiques de la table des pronostics.
public static final String TABLE_BETS= "betsTable";
public static final String BET_KEY = "betId";
private static final int NUM_COL_BET_KEY = 0;
public static final String BET_SCORE = "betScore";
private static final int NUM_COL_BET_SCORE = 1;
public static final String BET_USER = "betUser";
private static final int NUM_COL_BET_USER = 2;
public static final String BET_MATCH = "betMatch";
private static final int NUM_COL_BET_MATCH = 3;
//Fonctions de la table des pronostics.
//Cette fonction permet d'ajouter un utilisateur à la base de données.
public void addBet(Bet bet) {
ContentValues value = new ContentValues();
value.put(MatchDataBase.BET_KEY, bet.getBetId());
value.put(MatchDataBase.BET_SCORE, bet.getBetScore().toString());
value.put(MatchDataBase.BET_USER, bet.getBetUser());
value.put(MatchDataBase.BET_MATCH, bet.getBetMatch());
this.deleteUser(bet.getBetId());
mDb.insert(MatchDataBase.TABLE_USER, null, value);
}
//Cette fonction permet de supprimer un match de la base de données.
public void deleteBet(long id) {
mDb.delete(TABLE_BETS, BET_KEY + " = ?", new String[]{String.valueOf(id)});
}
//Cette fonction permet de modifier les informations d'un utilisateur, connaissant son ID.
public void updateBet(Bet bet) {
ContentValues value = new ContentValues();
value.put(MatchDataBase.BET_SCORE, bet.getBetScore().toString());
value.put(MatchDataBase.BET_USER, bet.getBetUser());
value.put(MatchDataBase.BET_MATCH, bet.getBetMatch());
mDb.update(TABLE_BETS, value, BET_KEY + " = ?", new String[]{String.valueOf(bet.getBetId())});
}
@Nullable //Cette fonction permet de récupérer la première ligne d'un cursor sous la forme d'un objet java de la classe User.
private Bet cursorToBet(Cursor c) {
if (c.getCount() == 0) {
return null;
}
//On se place au premier élément
c.moveToFirst();
Bet returnedBet = new Bet();
returnedBet.setBetId(c.getLong(NUM_COL_BET_KEY));
String writtenScore = c.getString(NUM_COL_BET_SCORE);
returnedBet.setBetScore(Score.convertStringToScore(writtenScore));
returnedBet.setBetUser(c.getLong(NUM_COL_BET_USER));
returnedBet.setBetMatch(c.getLong(NUM_COL_BET_MATCH));
c.close();
return returnedBet;
}
//Cette fonction permet de récupérer un utilisateur à partir de son ID.
public Bet geBetWithId(long id) {
Cursor c = mDb.query(TABLE_BETS, new String[]{BET_KEY, BET_SCORE, BET_USER, BET_MATCH},
BET_KEY + "= ?", new String[]{String.valueOf(id)}, null, null, null);
return cursorToBet(c);
}
}
你知道这个问题吗?这很奇怪,因为(我重复一遍)我在其他电脑上得到了相同的代码,没有问题...
谢谢,
莫里奇
答案 0 :(得分:0)
我不知道您做了哪些更改,但您的创建表查询如下所示:
您的查询
CREATE TABLE betsTable (betId INTEGER PRIMARY KEY AUTOINCREMENT, betScore TEXT, FOREIGN KEY(betUser) REFERENCES userTable(userId), FOREIGN KEY(betMatch) REFERENCES matchTable(id));
没有名称为#34; betUser&#34;的列,所以首先需要创建列,然后您可以为其指定外键,
检查以下新查询:
正确查询
CREATE TABLE betsTable (betId INTEGER PRIMARY KEY AUTOINCREMENT, betScore TEXT, betUser TEXT, betMatch TEXT, FOREIGN KEY(betUser) REFERENCES userTable(userId), FOREIGN KEY(betMatch) REFERENCES matchTable(id))