应用程序崩溃尝试在片段中添加到SQLite数据库

时间:2018-06-11 21:14:56

标签: android sqlite

我试图将数据库添加到我的应用程序中,以便用户输入的信息存储在其中。目前,我让用户输入播放器的名字和姓氏,我的应用程序运行正常。然后我尝试将名字和姓氏添加到数据库中,当我点击"添加播放器"时,所有内容都会崩溃。按钮提交播放器。

" 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)

2 个答案:

答案 0 :(得分:0)

初始化getActivity()时,无法保证Fragment中的Fragment不会为空。如果您在Fragment开始时需要一些内容但需要非空Context,那么您应该聆听onActivityCreated()(请参阅link)或{{1} (请参阅link),因为这可以让您知道onAttach()现在与FragmentActivity相关联。

答案 1 :(得分:0)

创建实例时,传递给PlayersDatabaseHelper的上下文为null。这是因为您尚未在片段中使用getActivity,但此时您还没有附加活动。

如果查看片段here的生命周期图,您可以看到该活动是在以后附加的,而不是在创建片段时附加的。

我建议将PlayerDatabaseHelper的创建移至onAttach