我正在编写一个android应用程序,该应用程序使用SQLite数据库来存储有关书籍的信息(id、标题、作者和评级)。最终,目标是通过CRUD实现将该信息输出给用户。现在,我有一个类来建立Books的各种属性,一个SQLHelper类,一个用于最终列表视图的ListAdapter,当然还有一个MainActivity类来运行应用程序并实现所有内容。
我正在将前3列(id、title和author)的条目硬编码到DB中。之后,我将使用Firefox扩展SQLiteManager来更新"评级"列。然而,现在,我无法克服我一直在犯的错误;当我尝试运行该应用程序时,它会崩溃,而且我在SQLite Manager中所做的更改似乎没有反映在Logcat文件中(我使用导出DB文件,使用管理器编辑,然后导入回项目中)。
稍后我可以也将致力于应用程序、UI和其他美学因素的展示,现在我只想弄清楚为什么我的数据库更改没有得到反映。
Logcat的完整输出在这里,但我相信相关信息是:
11-16 19:32:07.777 2433-2433/? E/AndroidRuntime: FATAL EXCEPTION: main
11-16 19:32:07.777 2433-2433/? E/AndroidRuntime: Process: com.bookreviews.hernandez.bookreviews, PID: 2433
11-16 19:32:07.777 2433-2433/? E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference
从这一点我了解到错误在我的MainActivity.java中,但我还没有确定原因。
主要活动.java
package com.bookreviews.hernandez.bookreviews;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("Name", "C H");
SqlHelper db = new SqlHelper(this);
/** CRUD Operations **/
// add Books
/*
db.addBook(new Book("Professional Android 4 Application Development",
"Reto Meier"));
db.addBook(new Book("Beginning Android 4 Application Development", "Wei-Meng Lee"));
db.addBook(new Book("Programming Android", "Wallace Jackson"));
db.addBook(new Book("Hello, Android", "Wallace Jackson"));
*/
// get all books
List<Book> list = db.getAllBooks();
// update one book
int j = db.updateBook(list.get(0), "Hello, Android", "Ben Wallace");
// delete one book
// db.deleteBook(list.get(0));
// get all books
db.getAllBooks();
ListView listContent = (ListView) findViewById(R.id.list);
List<Book> books = new ArrayList<Book>();
books=db.getAllBooks();
//get data from the table by the ListAdapter
ListAdapter customAdapter = new ListAdapter(this, R.layout.itemlistrow, books );
listContent.setAdapter(customAdapter);
// get # of records
db.getIds(list.get(0));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Book.java
package com.bookreviews.hernandez.bookreviews;
public class Book {
private int id;
private String title;
private String author;
private String rating;
public void setRating(String rating) {
this.rating = rating;
}
public String getRating() {
return rating;
}
public Book(){}
public Book(String title, String author) {
super();
this.title = title;
this.author = author;
}
//getters & setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book [id=" + id + ", title=" + title + ", author=" + author
+ ", rating=" + rating + "]";
}
}
SqlHelper.java
package com.bookreviews.hernandez.bookreviews;
import java.util.LinkedList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class SqlHelper extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 6;
// Database Name
private static final String DATABASE_NAME = "BookDB";
// Books table name
private static final String TABLE_BOOKS = "books";
// Books Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_TITLE = "title";
private static final String KEY_AUTHOR = "author";
public SqlHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// SQL statement to create book table
String CREATE_BOOK_TABLE = "CREATE TABLE books ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"title TEXT, "+
"author TEXT, "+
"rating TEXT)";
// create books table
db.execSQL(CREATE_BOOK_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older books table if existed
db.execSQL("DROP TABLE IF EXISTS books");
// create fresh books table
this.onCreate(db);
}
/*CRUD operations (create "add", read "get", update, delete) */
public void addBook(Book book){
Log.d("addBook", book.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_TITLE, book.getTitle()); // get title
values.put(KEY_AUTHOR, book.getAuthor()); // get author
// 3. insert
db.insert(TABLE_BOOKS, // table
null, //nullColumnHack
values); // key/value -> keys = column names/values
// 4. Close dbase
db.close();
}
// Get All Books
public List<Book> getAllBooks() {
List<Book> books = new LinkedList<Book>();
// 1. build the query
String query = "SELECT * FROM " + TABLE_BOOKS;
// 2. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
// 3. go over each row, build book and add it to list
Book book = null;
if (cursor.moveToFirst()) {
do {
book = new Book();
book.setId(Integer.parseInt(cursor.getString(0)));
book.setTitle(cursor.getString(1));
book.setAuthor(cursor.getString(2));
// Add book to books
books.add(book);
} while (cursor.moveToNext());
}
Log.d("getAllBooks()", books.toString());
return books; // return books
}
// Updating single book
public int updateBook(Book book, String newTitle, String newAuthor) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put("title", newTitle); // get title
values.put("author", newAuthor); // get author
// 3. updating row
int i = db.update(TABLE_BOOKS, //table
values, // column/value
KEY_ID+" = ?", // selections
new String[] { String.valueOf(159) }); //selection args
// 4. close dbase
db.close();
Log.d("UpdateBook", book.toString());
return i;
}
// Deleting single book
public void deleteBook(Book book) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. delete
db.delete(TABLE_BOOKS,
KEY_ID+" = ?",
new String[] { String.valueOf(book.getId()) });
// 3. close
db.close();
Log.d("deleteBook", book.toString());
}
public int getIds(Book book)
{
String selectQuery = "SELECT id FROM books";
SQLiteDatabase database = this.getReadableDatabase();
Cursor c = database.rawQuery(selectQuery, null);
c.moveToFirst();
int total = c.getCount();
Log.d("getIds", "Count=" + total);
return total;
}
}
ListAdapter.java
package com.bookreviews.hernandez.bookreviews;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.RatingBar;
import android.widget.TextView;
public class ListAdapter extends ArrayAdapter<Book> {
private List<Book> items;
public ListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
public ListAdapter(Context context, int resource, List<Book> items) {
super(context, resource, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.itemlistrow, null);
}
Book p = getItem(position);
if (p != null) {
TextView tt = (TextView) v.findViewById(R.id._id);
TextView tt1 = (TextView) v.findViewById(R.id.title);
TextView tt3 = (TextView) v.findViewById(R.id.author);
RatingBar rb = (RatingBar) v.findViewById(R.id.rating);
if (tt != null) {
tt.setText("" + p.getId());
}
if (tt1 != null) {
tt1.setText(p.getTitle());
}
if (tt3 != null) {
tt3.setText(p.getAuthor());
}
if (rb != null) {
float rating = Float.parseFloat(p.getRating());
rb.setRating(rating);
}
}
return v;
}
}
itemlistrow.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:textColor="#000"
android:id="@+id/_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="id" android:textStyle="bold"
android:gravity="left"
android:layout_weight="1"
android:typeface="monospace"
android:height="40sp" />
<TextView android:textColor="#000"
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="title"
android:layout_weight="1"
android:height="20sp" />
<TextView android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="1"
android:textColor="#000"
android:gravity="right"
android:id="@+id/author"
android:text="author"
android:height="20sp" />
<RatingBar
android:id="@+id/rating"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="6dip"
android:stepSize="0.25"
android:numStars="5"
/>
</LinearLayout>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical" >
<ListView
android:id="@+id/list"
android:layout_width="250dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_height="fill_parent"
android:layout_gravity="center" >
</ListView>
</LinearLayout>
显示数据库条目的Logcat。尽管我已经通过SQLite管理器更新了评级,但评级仍然显示为"null"。
19:32:07.426 2433-2433/? D/getAllBooks(): [Book [id=1, title=Professional Android 4 Application Development, author=Reto Meier, rating=null], Book [id=2, title=Beginning Android 4 Application Development, author=Wei-Meng Lee, rating=null], Book [id=3, title=Programming Android, author=Wallace Jackson, rating=null], Book [id=4, title=Hello, Android, author=Wallace Jackson, rating=null]]
问题:
我的SQLite Manager更改没有反映在Logcat中,应用程序崩溃
我已经尝试过的:
卸载和重新安装应用程序,升级数据库版本,删除数据库并通过启动
我正在使用的内容:
Android Studio 的最新版本
Firefox的SQLite Manager
对于如何解决这些错误并反映数据库更改的任何建议或建议,我们将不胜感激。
看起来您没有在SQLiteHelper
类的getAllBooks()
方法中设置评级。