0

I have a main activity called Chessboard. Within Chessboard, in the onCreate, I set a fragment activity GameInfoFragment. After this, a call is made to query an SQLite database, immediately after which a method in class SQLiteDataInterpreter is called. From here, a call is made to a method in the GameInfoFragment class, where imageViews in the fragment I set in Chessboard's onCreate should be populated.

When I attempt to start the Chessboard activity, I receive the following error:

Caused by: java.lang.IllegalStateException: Fragment GameInfoFragment{2ef389d9 id=0x7f09008d InfoTest} not attached to Activity

The code in Chessboard's onCreate is the following:

FragmentManager manager = this.getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();

        if (chessboard.moveCounter % 2 == 0) {
            transaction.add(com.zlaporta.chessgame.R.id.game_play_screen, gameInfo, "InfoTest");

        } else {
            transaction.add(com.zlaporta.chessgame.R.id.game_play_black_screen, gameInfo, "InfoTestBlack");
        }
        transaction.commit();

        Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar);
        toolbar.setTitle("Current Game");
        setSupportActionBar(toolbar);


        DBAdapter boardstateDB = new DBAdapter(chessboard.this);
        boardstateDB.open();


        Cursor cur = boardstateDB.getAllRows();

        if (cur != null && cur.moveToFirst()) {
            cur.moveToLast();
            String pieceData = cur.getString(cur.getColumnIndex("piecepositions"));
            whiteKingMoved = cur.getInt(cur.getColumnIndex("whitekingmoved"));
            blackKingMoved = cur.getInt(cur.getColumnIndex("blackkingmoved"));
            leftWRMoved = cur.getInt(cur.getColumnIndex("whiterook1moved"));
            rightWRMoved = cur.getInt(cur.getColumnIndex("whiterook2moved"));
            leftBRMoved = cur.getInt(cur.getColumnIndex("blackrook1moved"));
            rightBRMoved = cur.getInt(cur.getColumnIndex("blackrook2moved"));
            moveCounter = cur.getInt(cur.getColumnIndex("movecount"));
            String madeMoves = cur.getString(cur.getColumnIndex("mademoves"));
            storedTakenPieces = cur.getString(cur.getColumnIndex("takenpieces"));
            SQLiteDataInterpreter boardRefresher = new SQLiteDataInterpreter();
            boardRefresher.refreshBoard(pieceData, madeMoves, chessboard.this, storedTakenPieces);
        } else {
            boardstateDB.updateGameState("r00 k01 b02 q03 a04 b05 k06 r07 p10 p11 p12 p13 p14 p15 p16 p17 P60 P61 P62 P63 P64 P65 P66 P67 R70 K71 B72 Q73 A74 B75 K76 R77",
                    0, 0, 0, 0, 0, 0, 0, " ", " ");
            Cursor curs = boardstateDB.getAllRows();
            curs.moveToLast();

            String pieceData = curs.getString(curs.getColumnIndex("piecepositions"));
            whiteKingMoved = curs.getInt(curs.getColumnIndex("whitekingmoved"));
            blackKingMoved = curs.getInt(curs.getColumnIndex("blackkingmoved"));
            leftWRMoved = curs.getInt(curs.getColumnIndex("whiterook1moved"));
            rightWRMoved = curs.getInt(curs.getColumnIndex("whiterook2moved"));
            leftBRMoved = curs.getInt(curs.getColumnIndex("blackrook1moved"));
            rightBRMoved = curs.getInt(curs.getColumnIndex("blackrook2moved"));
            moveCounter = curs.getInt(curs.getColumnIndex("movecount"));
            String madeMoves = curs.getString(curs.getColumnIndex("mademoves"));
            storedTakenPieces = curs.getString(curs.getColumnIndex("takenpieces"));
            SQLiteDataInterpreter boardRefresher = new SQLiteDataInterpreter();
            boardRefresher.refreshBoard(pieceData, madeMoves, chessboard.this, storedTakenPieces);

And the relevant code in my GameInfoFragment class which is causing problems:

public void setTakenPiece(String[] takenpiecerecord) {
        takenPiece = takenpiecerecord;

        int c;
        for (c = 0; c < takenPiece.length; c++) {
            String takenPieceHolder = "t" + c;
            String pieceCheck = takenPiece[c];
            //System.out.println(square);

                int takenPieceHolderID = this.getResources().getIdentifier(takenPieceHolder, "id", getActivity().getPackageName());
                ImageView takenPieceHolderSquare = (ImageView) v.findViewById(takenPieceHolderID);

The main line of code that is causing issues is where I try to set the value of takenPieceHolderID in the code directly above.

How can I ensure that my fragment is added so that its imageViews will be populated upon the start of my Chessboard Activity?

credo56
  • 423
  • 1
  • 8
  • 19

2 Answers2

0

You should check if Activity exists and if isAdded() is True

public void setTakenPiece(String[] takenpiecerecord) {
        activity = getActivity();
        if (isAdded() && activity) {
            takenPiece = takenpiecerecord;

            int c;
            for (c = 0; c < takenPiece.length; c++) {
                String takenPieceHolder = "t" + c;
                String pieceCheck = takenPiece[c];
                //System.out.println(square);

                int takenPieceHolderID = this.getResources().getIdentifier(takenPieceHolder, "id", getActivity().getPackageName());
                ImageView takenPieceHolderSquare = (ImageView) v.findViewById(takenPieceHolderID); 
    }}
rafaelc
  • 57,686
  • 15
  • 58
  • 82
  • `isAdded` checks whether the result of `getActivity` is null, so there's no need to check that separately. – stkent Apr 26 '15 at 00:50
  • But this just prevents the image views from being populated. It doesn't get to the heart of the issue, which is ensuring the fragment is added prior to the method being called – credo56 Apr 26 '15 at 02:02
0

I use the fragment manager to find the fragment by tag. If it returns null I have problems with fragment creation. This depends on whether my fragment has a valid container, calls an adapter and the adapter is unhappy, or if it calls a view improperly, so double check all. Make sure your container is added to your ViewGroup, if you are using one, and that the container is detached from any parent.

I create my fragments programatically and set tag names that can be searched.

Using debug, be sure that the fragment constructor is called, then make sure onCreateView is called. If so, single step through onCreateView and look for a line that bombs. Make sure the fragment returns a view.

Also be sure what type of fragment you are using, android or android.support.v4.app.Fragment.

At times I have had to use FragmentManager whatever_your_name_is.executePendingTransactions to ensure that the fragment has been added prior to being accessed. Be sure to use the fragment manager that launched the fragment.

That's my brain dump, good luck.