我试图将数据库添加到我的应用程序中,以便用户输入的信息存储在其中。目前,我让用户输入播放器的名字和姓氏,我的应用程序运行正常。然后我尝试将名字和姓氏添加到数据库中,当我点击"添加播放器"时,所有内容都会崩溃。按钮提交播放器。
" addPlayer"中注释掉的行这个片段的方法似乎是罪魁祸首。当我取消评论时,应用程序崩溃了;当它被评论时,事情似乎工作得很好:
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* A simple {@link Fragment} subclass.
*/
public class AddPlayerFragment extends Fragment {
TextView addFirstName, addLastName;
Button doneButton, nextButton;
String playerNames = "";
PlayersDatabaseHelper db = new PlayersDatabaseHelper(getActivity());
public AddPlayerFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_add_player, container, false);
//Define buttons on the view.
doneButton = view.findViewById(R.id.doneAddingPlayers);
nextButton = view.findViewById(R.id.addPlayer);
//Get player names.
if(getArguments() != null){
playerNames = getArguments().getString("playersSoFar");
}
/*
Set onClickListener method for "Add Another" button.
Call addPlayer method to get user-entered player name, add name to players array list.
Re-open this view to enter another player.
*/
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String newPlayerName = addPlayer(view);
if(newPlayerName != "") {
if (playerNames != null) {
playerNames = playerNames + ", " + newPlayerName;
} else {
playerNames = newPlayerName;
}
Intent intent = new Intent(view.getContext(), AddPlayerActivity.class);
intent.putExtra("playersSoFar", playerNames);
startActivity(intent);
}
}
});
//Set onClick Listener method for "Done" button. Opens grid for new game with player names.
doneButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String newPlayerName = addPlayer(view);
playerNames = playerNames + "," + newPlayerName;
Intent intent = new Intent(view.getContext(), ScoringGridActivity.class);
intent.putExtra("players", playerNames);
startActivity(intent);
}
});
return view;
}
public String addPlayer(View view) {
String playerFirstName, playerLastName, playerName;
addFirstName = view.findViewById(R.id.newUserFirstName);
addLastName = view.findViewById(R.id.newUserLastName);
playerFirstName = addFirstName.getText().toString();
playerLastName = addLastName.getText().toString();
playerName = playerFirstName + " " + playerLastName;
if(playerFirstName.isEmpty()) {
//Toast letting user know first name is required.
Toast.makeText(getActivity(), R.string.required_name_toast, Toast.LENGTH_LONG).show();
return "";
}
else{
//db.addPlayer(new PlayerInfo(playerFirstName, playerLastName));
}
return playerName;
}
}
这是我的SQLiteDBHelper类的代码:
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.schrumpfk.candlepinscorecard.PlayerInfo;
class PlayersDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "player information";
private static final int DB_VERSION = 1;
PlayersDatabaseHelper (Context context){
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE PLAYER_INFO ("
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "FIRST_NAME TEXT, "
+ "LAST_NAME TEXT) ;");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS PLAYER_INFO");
db.execSQL("CREATE TABLE IF NOT EXISTS PLAYER_INFO ("
+ "FIRST_NAME TEXT, "
+ "LAST_NAME TEXT) ;");
this.onCreate(db);
}
public void addPlayer(PlayerInfo playerInfo){
SQLiteDatabase db = this.getReadableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("FIRST_NAME", playerInfo.getFirstName());
contentValues.put("LAST_NAME", playerInfo.getLastName());
db.insert("PLAYER_INFO", null, contentValues);
db.close();
}
}
崩溃日志:
06-11 17:28:06.621 2636-2676/com.schrumpfk.candlepinscorecard D/EGL_emulation: eglMakeCurrent: 0xa1bec5c0: ver 3 0 (tinfo 0xa1be9730)
06-11 17:28:06.800 2636-2676/com.schrumpfk.candlepinscorecard D/EGL_emulation: eglMakeCurrent: 0xa1bec5c0: ver 3 0 (tinfo 0xa1be9730)
06-11 17:28:06.911 2636-2676/com.schrumpfk.candlepinscorecard D/EGL_emulation: eglMakeCurrent: 0xa1bec5c0: ver 3 0 (tinfo 0xa1be9730)
06-11 17:28:06.928 2636-2676/com.schrumpfk.candlepinscorecard D/EGL_emulation: eglMakeCurrent: 0xa1bec5c0: ver 3 0 (tinfo 0xa1be9730)
06-11 17:28:06.963 2636-2676/com.schrumpfk.candlepinscorecard D/EGL_emulation: eglMakeCurrent: 0xa1bec5c0: ver 3 0 (tinfo 0xa1be9730)
06-11 17:28:06.968 2636-2676/com.schrumpfk.candlepinscorecard D/OpenGLRenderer: endAllActiveAnimators on 0x946ab000 (RippleDrawable) with handle 0x9452ca50
06-11 17:28:07.350 2636-2676/com.schrumpfk.candlepinscorecard D/EGL_emulation: eglMakeCurrent: 0xa1bec5c0: ver 3 0 (tinfo 0xa1be9730)
06-11 17:28:08.662 2636-2640/com.schrumpfk.candlepinscorecard I/art: Do partial code cache collection, code=18KB, data=26KB
After code cache collection, code=16KB, data=26KB
Increasing code cache capacity to 128KB
06-11 17:28:09.035 2636-2636/com.schrumpfk.candlepinscorecard W/IInputConnectionWrapper: finishComposingText on inactive InputConnection
06-11 17:28:09.414 2636-2640/com.schrumpfk.candlepinscorecard I/art: Do partial code cache collection, code=56KB, data=56KB
After code cache collection, code=56KB, data=56KB
Increasing code cache capacity to 256KB
06-11 17:28:11.612 2636-2636/com.schrumpfk.candlepinscorecard D/AndroidRuntime: Shutting down VM
--------- beginning of crash
06-11 17:28:11.613 2636-2636/com.schrumpfk.candlepinscorecard E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.schrumpfk.candlepinscorecard, PID: 2636
java.lang.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
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
at com.schrumpfk.candlepinscorecard.PlayersDatabaseHelper.addPlayer(PlayersDatabaseHelper.java:38)
at com.schrumpfk.candlepinscorecard.AddPlayerFragment.addPlayer(AddPlayerFragment.java:110)
at com.schrumpfk.candlepinscorecard.AddPlayerFragment$1.onClick(AddPlayerFragment.java:60)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
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:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
答案 0 :(得分:0)
初始化getActivity()
时,无法保证Fragment
中的Fragment
不会为空。如果您在Fragment
开始时需要一些内容但需要非空Context
,那么您应该聆听onActivityCreated()
(请参阅link)或{{1} (请参阅link),因为这可以让您知道onAttach()
现在与Fragment
或Activity
相关联。
答案 1 :(得分:0)
创建实例时,传递给PlayersDatabaseHelper
的上下文为null。这是因为您尚未在片段中使用getActivity
,但此时您还没有附加活动。
如果查看片段here的生命周期图,您可以看到该活动是在以后附加的,而不是在创建片段时附加的。
我建议将PlayerDatabaseHelper
的创建移至onAttach
。