我从一个教程中创建了一个简单的SQLite应用程序,现在我正在尝试将它与我制作的游戏拼接在一起。我希望使用SQLite更新和保存高分,但我遇到了一些问题。现在玩游戏但是当我输了并且调用了cancel()方法时,我得到了一个"尝试调用虚拟方法' void'在null对象引用"错误。我不太了解SQL是如何工作的,所以任何反馈都是值得赞赏的。
主要活动
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
//sqlite
//EditText input;
//first high score
TextView productText;
MyDBHandler dbHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//sqlite
//input = (EditText)findViewById(R.id.editText_ID);
productText = (TextView)findViewById(R.id.textView1);
//GameScreen gameScreen = new GameScreen();
dbHandler = new MyDBHandler(this, null, null, 1);
updateDatabase();
}
public void sendMessage(View view)
{
Intent intent = new Intent(MainActivity.this, GameScreen.class);
startActivity(intent);
}
//sqlite
//add a product to the database
public void addButtonClicked(){
GameScreen gameScreen = new GameScreen();
Products product = new Products(gameScreen.countPassString);
dbHandler.addProduct(product);
updateDatabase();
}
//sqlite
public void updateDatabase(){
String dbString = dbHandler.databaseToString();
productText.setText(dbString);
}
}
GameScreen类
import android.app.Activity;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class GameScreen extends Activity {
private TextView time;
private ImageButton start;
private ImageButton gameButton;
private ImageButton button2;
private CountDownTimer countDownTimer;
public static int count = 0;
public static int countPass = 0;
public String countPassString = "";
final Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
cancel();
}
};
private View.OnClickListener btnClickListener = new View.OnClickListener(){
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.start_ID :
start();
break;
case R.id.gameButton_ID :
gameButton();
break;
case R.id.button2_ID :
button2();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_screen);
start = (ImageButton) findViewById(R.id.start_ID);
start.setOnClickListener(btnClickListener);
time = (TextView) findViewById(R.id.time);
gameButton = (ImageButton) findViewById(R.id.gameButton_ID);
gameButton.setOnClickListener(btnClickListener);
button2 = (ImageButton) findViewById(R.id.button2_ID);
button2.setOnClickListener(btnClickListener);
button2.setVisibility(View.GONE);
}
public void start(){
count = 0;
start.setVisibility(View.GONE);
time.setText("100");
//this doesnt work and makes app crash when you hit start button
countDownTimer = new CountDownTimer(100 * 1000, 1000) {
@Override
public void onTick(long millsUntilFinished){
time.setText("" + millsUntilFinished / 1000);
//turns textview string to int
int foo = Integer.parseInt(time.getText().toString());
if(foo == 93) {
time.setVisibility(View.GONE);
button2.setVisibility(View.VISIBLE);
}
else if(foo == 97) {
gameButton.animate().translationX(200).setDuration(5000).start(); // move away
}
else if(foo == 90){
gameButton.animate().translationY(200).setDuration(5000).start(); // move away
}
if(foo % 2 == 0){
handler.postDelayed(r, 1000);
}
}
public void onFinish() {
start.setVisibility(View.VISIBLE);
time.setVisibility(View.VISIBLE);
time.setText("Done !");
//need to check if score will reset if you win the game
Toast.makeText(getApplicationContext(), "You scored " + count, Toast.LENGTH_LONG).show();
gameButton.clearAnimation();
gameButton.animate().translationX(0).setDuration(500).start(); //move back
gameButton.animate().translationY(0).setDuration(500).start(); //move back
button2.setVisibility(View.GONE);
}
};
countDownTimer.start();
}
private void cancel(){
if(countDownTimer != null){
countDownTimer.cancel();
countDownTimer = null;
start.setVisibility(View.VISIBLE);
time.setVisibility(View.VISIBLE);
gameButton.clearAnimation();
gameButton.animate().translationX(0).setDuration(500).start(); //move back
gameButton.animate().translationY(0).setDuration(500).start(); //move back
button2.setVisibility(View.GONE);
//holds score at end of game
countPass = count;
//reset score for new game
count = 0;
Toast.makeText(getApplicationContext(), "You scored " + countPass, Toast.LENGTH_LONG).show();
countPassString = Integer.toString(countPass);
MainActivity mainActivity = new MainActivity();
mainActivity.addButtonClicked();
}
}
private void gameButton(){
int foo = Integer.parseInt(time.getText().toString());
if(foo % 2 == 0 ) {
final Toast toast = Toast.makeText(getApplicationContext(), "+1", Toast.LENGTH_SHORT);
toast.show();
// makes +1 toast half a second
Handler gameButtonToastHandler = new Handler();
gameButtonToastHandler.postDelayed(new Runnable() {
@Override
public void run() {
toast.cancel();
}
}, 500);
handler.removeCallbacks(r);
++count;
}
else{
cancel();
}
}
private void button2(){
cancel();
}
}
MyDBHandler类
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDBHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "products.db";
public static final String TABLE_PRODUCTS = "products";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_PRODUCTNAME = "productname";
public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_PRODUCTS + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_PRODUCTNAME + " TEXT " +
");";
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRODUCTS);
onCreate(db);
}
//add a new row to the database
public void addProduct(Products product){
ContentValues values = new ContentValues();
values.put(COLUMN_PRODUCTNAME, product.get_productname());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_PRODUCTS, null, values);
db.close();
}
/*//delete a product from the database
public void deleteProduct(String productName){
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_PRODUCTS + " WHERE " + COLUMN_PRODUCTNAME + "=\"" + productName + "\";" );
}
*/
//print out the database as a string
public String databaseToString(){
String dbString = "";
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_PRODUCTS + " WHERE 1";
//Cursor point to location in your results
/*
Cursor c = db.rawQuery(query, null);
//Move to the first row in your results
c.moveToFirst();
while(!c.isAfterLast()){
if(c.getString(c.getColumnIndex("productname")) != null){
dbString += c.getString(c.getColumnIndex("productname"));
dbString += "\n";
}
c.moveToNext();
}
*/
db.close();
return dbString;
}
}
产品类
public class Products {
private int _id;
private String _productname;
public Products(){
}
public Products(String productname){
this._productname = productname;
}
public void set_id(int _id) {
this._id = _id;
}
public void set_productname(String _productname) {
this._productname = _productname;
}
public int get_id() {
return _id;
}
public String get_productname() {
return _productname;
}
}
MainActivity的XML也是我试图让SQL更改textViews的地方。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:background="@drawable/clock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.emilythacker.myapplication.MainActivity">
<TextView
android:text="HIGH SCORES"
android:textSize="35dp"
android:textColor="#4cfd00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="45dp"
android:id="@+id/textView" />
<TextView
android:text="1:"
android:textSize="35dp"
android:textColor="#4cfd00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="17dp"
android:id="@+id/textView1"
android:layout_below="@+id/textView"
android:layout_alignStart="@+id/textView" />
<TextView
android:text="2:"
android:textSize="35dp"
android:textColor="#4cfd00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/textView1"
android:id="@+id/textView2"
android:layout_below="@+id/textView1" />
<TextView
android:text="3:"
android:textSize="35dp"
android:textColor="#4cfd00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView3"
android:layout_below="@+id/textView2"
android:layout_alignStart="@+id/textView2" />
<TextView
android:text="4:"
android:textSize="35dp"
android:textColor="#4cfd00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView4"
android:layout_below="@+id/textView3"
android:layout_alignStart="@+id/textView3" />
<TextView
android:text="5:"
android:textSize="35dp"
android:textColor="#4cfd00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView5"
android:layout_below="@+id/textView4"
android:layout_alignStart="@+id/textView4" />
<Button
android:text="PLAY"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView5"
android:layout_centerHorizontal="true"
android:layout_marginTop="53dp"
android:id="@+id/playbutton_ID"
android:onClick="sendMessage"/>
</RelativeLayout>
这是控制台消息
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.emilythacker.myapplication, PID: 31291
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.emilythacker.myapplication.MyDBHandler.addProduct(com.example.emilythacker.myapplication.Products)' on a null object reference
at com.example.emilythacker.myapplication.MainActivity.addButtonClicked(MainActivity.java:46)
at com.example.emilythacker.myapplication.GameScreen.cancel(GameScreen.java:150)
at com.example.emilythacker.myapplication.GameScreen.access$000(GameScreen.java:19)
at com.example.emilythacker.myapplication.GameScreen$1.run(GameScreen.java:33)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6688)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Disconnected from the target VM, address: 'localhost:8603', transport: 'socket'
答案 0 :(得分:0)
你应该添加
在Contentvalues之前SQLiteDatabase db = this.getWritableDatabase();