2017-04-20 137 views
-6

这是我DatabaseHelper类SQLiteOpenHelper.getReadableDatabase()方法崩溃

public class DatabaseHelper extends SQLiteOpenHelper 

    public static final int DATABASE_VERSION = 1; 
    public static final String DATABASE_NAME = "MyAccountsDB.db"; 

    public static final String TABLE_Accounts = "Accounts"; 

    public static final String COLUMN_AccountID= "AccountID"; 
    public static final String COLUMN_WebSite= "WebSite"; 
    public static final String COLUMN_Email= "Email"; 
    public static final String COLUMN_UserName = "UserName"; 
    public static final String COLUMN_Password= "Password"; 


    private static final String TEXT_TYPE = " TEXT"; 
    private static final String INT_TYPE = " INTEGER"; 
    private static final String COMMA_SEP = ","; 

    private static final String SQL_CREATE_TABLE_Accounts = 
      "CREATE TABLE " + TABLE_Accounts + 
        " (" + 
        COLUMN_AccountID + INT_TYPE +" PRIMARY KEY AUTOINCREMENT NOT NULL"+ COMMA_SEP + 
        COLUMN_WebSite + TEXT_TYPE + COMMA_SEP + 
        COLUMN_Email + TEXT_TYPE + COMMA_SEP + 
        COLUMN_UserName + TEXT_TYPE + COMMA_SEP + 
        COLUMN_Password+ TEXT_TYPE + ")"; 
    public DatabaseHelper(Context context) 
    { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 


    @Override 
    public void onCreate(SQLiteDatabase db) 
    { 
     db.execSQL(SQL_CREATE_TABLE_Accounts); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int i, int i1) 
    { 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_Accounts); 
     onCreate(db); 
    } 
    public void CreateAccount(Account acc) 
    { 
     SQLiteDatabase db = getWritableDatabase(); 

     String insertAccount = "Insert into Accounts (WebSite,Email,UserName,Password) values" + 
     "('" + acc.getWebSite() + "','" + acc.geteMail() + "','" + acc.getUserName() + "','" + acc.getPassWord() + "')"; 
     db.execSQL(insertAccount); 
    } 

    public ArrayList<Account> getAllAccounts() 
    { 
     String query = "SELECT AccountID , WebSite FROM Accounts"; 
     ArrayList<Account> Accounts = new ArrayList<Account>(); 
     SQLiteDatabase database = getReadableDatabase();//when its called here no problem and load all the accounts the way i want 
     Cursor c = database.rawQuery(query, null); 
     if (c != null) 
     { 
      while (c.moveToNext()) 
      { 
       Account acc = new Account(); 
       acc.setAccountID(c.getInt(0)); 
       acc.setWebSite(c.getString(1)); 
       Accounts.add(acc); 
      } 
     } 
     return Accounts; 
    } 
    public Account getAccountByID(int id) 
    { 
     Account acc = new Account(); 
     String query = "SELECT WebSite , eMail , UserName , Password from Accounts where AccountID = " + id; 
     SQLiteDatabase database = getReadableDatabase();//but when i call it here following exception thrown 
     Cursor c = database.rawQuery(query, null); 
     if (c != null) 
     { 
      while (c.moveToFirst()) 
      { 
       acc.setAccountID(c.getInt(0)); 
       acc.setWebSite(c.getString(1)); 
       acc.seteMail(c.getString(2)); 
       acc.setUserName(c.getString(3)); 
       acc.setPassWord(c.getString(4)); 
      } 
     } 
     return acc; 
    } 

NullPointerException : 
Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference 

我有同样的方法和函数的语法另一个应用程序,它的工作没有任何问题

+2

的可能重复的构造函数[什么是空指针异常,怎么解决呢?(http://stackoverflow.com/quest离子/ 218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) –

+0

你是在字符串中放置列而不是使用'COLUMN_AccountID',例如?你真的需要将密码存储在Java'Account'对象中吗? –

+0

谢谢你......但getReadableDatabase()的相同调用语法在getAllAccounts方法中工作良好 –

回答

0

谢谢大家...我已经找到了答案....我是从一个片段调用 getAccountById方法,所以,我必须重新通过 语境再次给它

UpdateAccountFragment a = new UpdateAccountFragment(accountID,getActivity()); 

UpdateAccountFragment样子

public UpdateAccountFragment (int accountID , Context context) 
{ 
    this.context = context; 
    this.accountID = accountID; 
} 
+0

您不需要将上下文传递给任何片段。你可以简单地在第二个片段中使用'getActivity()' –

+0

**是的。你的权利它的工作** –

-1

问题是在您的查询中:

String query = "SELECT WebSite , eMail , UserName , Password from Accounts where AccountID = " + id; 

您已使用eMail而不是Email。您的Accounts表中名为eMail的表中没有column。还将from更改为FROMwhere子条款更改为WHERE

更改Query如下:

String query = "SELECT WebSite , Email , UserName , Password FROM Accounts WHERE AccountID = " + id; 

ActivityFragment像下面创建的DatabaseHelperinstance

从活动:

public class MainActivity extends AppCompatActivity { 

    DatabaseHelper db; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     db = new DatabaseHelper(this); // Context is this 

     ............... 
     .................... 
    } 

} 

从片段:

public class UpdateAccountFragment extends Fragment { 

    DatabaseHelper db; 

    @Override 
    public void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     db = new DatabaseHelper(getActivity()); // Context is getActivity() 

     ............... 
     .................... 
    } 
} 

希望这将有助于〜

+1

谢谢你表明你在哪里调用该方法..我刚刚尝试过电子邮件,但仍然是同样的问题... –

+0

你为什么建议SQL注入? –

+1

再次感谢你......仍然没有工作......我的问题不在SQL查询中 –

0

我相信你需要以不同的方式创建数据库帮手。

例如,

public class MainActivity extends Activity { 

    private DatabaseHelper db; // Don't initialize here 

    @Override 
    protected void onCreate(Bundle b) { 
     ... 
     db = new DatabaseHelper(this); // Do it here 
    } 
} 

,并应解决当前的错误,如果你使用整个活动同db变量,但你仍然有在SQL查询等事项,不你的表定义相匹配。

您也不想使用while (c.moveToFirst()),除非您希望该循环永不结束。

public Account getAccountByID(int id) 
{ 
    Account acc = new Account(); 
    SQLiteDatabase database = getReadableDatabase(); 

    Cursor c = database.query(TABLE_Accounts, 
      { COLUMN_WebSite , COLUMN_Email , COLUMN_UserName , COLUMN_Password }, 
      COLUMN_AccountID + "=?", 
      { String.valueOf(id) }, 
      null, null, null, null); 
     );  

    try { 
     if (c != null && c.moveToFirst()) 
     { 
      acc.setAccountID(id); 
      acc.setWebSite(c.getString(0)); 
      acc.seteMail(c.getString(1)); 
      acc.setUserName(c.getString(2)); 
      acc.setPassWord(c.getString(3)); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     if (c != null) c.close(); 
    } 
    return acc; 
} 
+0

非常感谢你的代码......但我已经解决了它:)....它是从另一个片段调用一个片段时,你必须通过活动的上下文它通过''getActivity()' –

+0

似乎是一个合理的解决方案。 –