After adding its own interface, Java will throw notserializableexception

People, I'm sticking to the new android app I'm developing For the application (card game), I need to save some data I use serialization to do this

The problem now is that when I try to implement an interface to track the direction of the payer, the application returns noserializableexception from the class game (main activity) When I delete the interface, everything works

The turn class contains the following codes:

public class Turn<T> implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 1L;

public interface OnTurnEndedListener<T>{
    void onTurnEnded(T currentPlayer);
}

private ArrayList<T> players;
private int turnIndex;
private int rounds;
private ArrayList<OnTurnEndedListener<T>> turnEndListenerList;

public Turn() {
    throw new UnsupportedOperationException("cannot init without players");
}

public Turn(ArrayList<T> players,int startingPlayerIndex) {
    this.players = players;
    this.turnIndex = startingPlayerIndex;
    this.rounds = 0;
    turnEndListenerList = new ArrayList<OnTurnEndedListener<T>>();
}

public int getRounds() {
    return rounds;
}

public T next() {
    turnIndex = (turnIndex + 1) % players.size();
    if (turnIndex == 0) {
        rounds++;
    }
    T retVal = players.get(turnIndex);
    for (OnTurnEndedListener<T> l : turnEndListenerList) {
        l.onTurnEnded(retVal);
    }
    return retVal;
}

public T peek() {
    return players.get(turnIndex);
}

public void addOnTurnEndedListener(OnTurnEndedListener<T> l) {
    this.turnEndListenerList.add(l);

}
}

When I add the following code to the main activity (game), I receive an exception every time I close the activity

gameData.getTurn().addOnTurnEndedListener(new Turn.OnTurnEndedListener<Hand>() {
            @Override
            public void onTurnEnded(Hand hand) {
                turnEndedHandler(hand);
            }
        });

You can find the complete code of the game and GameData classes, as well as the following error log

import java.util.ArrayList;
import java.util.Collections;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class Game extends Activity implements OnTouchListener{

    private Deck deck;
    private GameData gameData;
    Hand playerHand,oppHand;
    private ImageView ivDeckClosed,ivDeckOpen,ivPlayerCard1,ivPlayerCard2,ivPlayerCard3,ivPlayerCard4,ivPlayerCard5,ivPlayerCard6,ivPlayerCard7,ivPlayerCard8,ivPlayerCard9,ivPlayerCard10,ivPlayerCard11,ivPlayerCard12,ivPlayerCard13,ivPlayerCard14;
    private ImageView[] playerCards;
    private TextView tvOpp1;
    private ArrayList<Hand> playersInOrder;
    private LinearLayout llPlayGround,llPlayGroundRow1,llPlayGroundRow2,llCardDeck;
    private ArrayList<PlayedSet> playedSets;
    public static final String SAVE_FILENAME = "jokerensave.ser";
    private SaveHandler savehandler;
    private Hand currentHand;
    private int defaultStartingPlayer = 0;

    public static enum STATES {
        start,resume,end
    };

    public static final int START_CODE = 0;
    public static final int RESUME_CODE = 1;
    public static final String GAME_STATE = "STATE";
    public static final String GAME_DATA = "GameData";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("PUKI","onCreate");

        // Get save game
        savehandler = SaveHandler.getInstance(this);
        gameData = savehandler.readLastState();

        setContentView(R.layout.gamescreen);

        // Load which state was given by the mainscreen
        switch ((STATES) getIntent().getExtras().get(GAME_STATE)) {
        case start:
            gameData.setFirstRun(true);
            Log.i("ONCREATE","Received state: start");
            break;
        case resume:
            gameData.setFirstRun(false);
            Log.i("ONCREATE","Received state: resume");
            break;
        default:
            gameData.setFirstRun(true);
            Log.i("ONCREATE","Received state: none");
            break;
        }

        // Transferring game data to MainScreen
        Bundle b = new Bundle();
        b.putInt("int",5);
        b.putSerializable(GAME_DATA,gameData);
        Intent i = new Intent();
        i.putExtras(b);
        setResult(0,i);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("PUKI","onStart");
        Log.i("FIRSTRUN","Firstrun = "+gameData.getFirstRun());

        init(gameData.getFirstRun());


        gameData.getTurn().addOnTurnEndedListener(new Turn.OnTurnEndedListener<Hand>() {
            @Override
            public void onTurnEnded(Hand hand) {
                turnEndedHandler(hand);
            }
        });
    }

    private void init(boolean first) {
        initGraphics(first);
        Log.i("INIT","Game init graphics");
        if (first) {
            Log.i("INIT","Game init core");
            initGameCore();
        }
    }

    private void initGameCore() {
        deck = new Deck();
        playedSets = new ArrayList<PlayedSet>();

        // Create array with players and their hand
        playersInOrder = new ArrayList<Hand>();
        playerHand = new PlayerHand(playerCards,"Player name");
        playersInOrder.add(playerHand);
        oppHand = new OppHand(new GameStrategy(),null,"Opponent");
        playersInOrder.add(oppHand);

        // Push all data to gamedata class
        gameData.init(playerHand,oppHand,playersInOrder,deck,playedSets,new Turn<Hand>(playersInOrder,defaultStartingPlayer));
        gameData.setGameInProgress(true);

        // Deal cards to players
        dealCards();
    }


    //TODO
    protected void turnEndedHandler(final Hand hand) {
        if(hand.isAwaitinginput()){
            // This means the turn is for a human player,so do nothing.
            Log.i("TURN","The turn is for the human player: "+hand.getPlayerName());
        }
        else{
            // This means the turn is for a AI. Decide!
            Log.i("TURN","The turn is for the AI player: "+hand.getPlayerName());
            gameData.getTurn().next();

            // Update players hand size for human player
            this.updateOppscore();
        }
    }

(I removed a lot of code from the above example because no code is required to solve this problem)

import java.io.Serializable;
import java.util.ArrayList;

public class GameData implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -3796450525724090900L;

    private Hand playerHand,oppHand;
    private ArrayList<Hand> playersInOrder;
    private Deck deck;
    private boolean gameInProgress,grabbedCard,playerMustThrow,firstRun;
    private ArrayList<PlayedSet> playedSets; 
    private Turn<Hand> turn;

    private static GameData instance = new GameData();

    public GameData(){
        // Do nothing
    }

    public static GameData getInstance(){
        return instance;
    }

    public void init(Hand playerHand,Hand oppHand,ArrayList<Hand> playersInOrder,Deck deck,ArrayList<PlayedSet> playedSets,Turn<Hand> turn) {
        this.playerHand = playerHand;
        this.playersInOrder = playersInOrder;
        this.oppHand = oppHand;
        this.deck = deck;
        this.grabbedCard = false;
        this.playerMustThrow = false;
        this.playedSets = playedSets;
        this.firstRun = false;
        this.turn = turn;
    }

    public Hand getPlayerHand(){
        return playerHand;
    }
    public Hand getOppHand(){
        return oppHand;
    }
    public Deck getDeck(){
        return deck;
    }
    public ArrayList<Hand> getPlayersInOrder(){
        return playersInOrder;
    }
    public void setGrabbedCard(boolean set){
        this.grabbedCard = set;
    }
    public boolean getGrabbedCard(){
        return grabbedCard;
    }

    public void setGameInProgress(boolean progress) {
        this.gameInProgress = progress;
    }

    public boolean isGameInProgress(){
        return gameInProgress;
    }

    public void createNewPlaySet(PlayedSet newSet){
        playedSets.add(newSet);
    }

    public ArrayList<PlayedSet> getAllPlayedSets(){
        return playedSets;
    }

    public void setPlayerCanThrow(boolean set){
        this.playerMustThrow = set;
    }

    public boolean canPlayerThrow(){
        return playerMustThrow;
    }

    public boolean getFirstRun(){
        return firstRun;
    }

    public void setFirstRun(boolean set){
        this.firstRun = set;
    }

    public Turn<Hand> getTurn(){
        return turn;
    }

}

journal:

01-20 21:05:16.678: W/dalvikvm(27035): threadid=1: thread exiting with uncaught exception (group=0x40c5c1f8)
01-20 21:05:16.693: E/AndroidRuntime(27035): FATAL EXCEPTION: main
01-20 21:05:16.693: E/AndroidRuntime(27035): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = nl.dirkgroenen.jokeren.GameData)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Parcel.writeSerializable(Parcel.java:1181)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Parcel.writeValue(Parcel.java:1135)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Parcel.writeMapInternal(Parcel.java:493)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Bundle.writeToParcel(Bundle.java:1612)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Parcel.writeBundle(Parcel.java:507)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.content.Intent.writeToParcel(Intent.java:6224)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.app.ActivityManagerProxy.finishActivity(ActivityManagerNative.java:1831)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.app.Activity.finish(Activity.java:3709)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.app.Activity.onBackPressed(Activity.java:2124)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.app.Activity.onKeyUp(Activity.java:2099)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.view.KeyEvent.dispatch(KeyEvent.java:2633)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.app.Activity.dispatchKeyEvent(Activity.java:2334)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1958)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3565)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.view.ViewRootImpl.handleFinishedEvent(ViewRootImpl.java:3538)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2646)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Looper.loop(Looper.java:137)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.app.ActivityThread.main(ActivityThread.java:4511)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.lang.reflect.Method.invokeNative(Native Method)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.lang.reflect.Method.invoke(Method.java:511)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at dalvik.system.NativeStart.main(Native Method)
01-20 21:05:16.693: E/AndroidRuntime(27035): Caused by: java.io.NotSerializableException: nl.dirkgroenen.jokeren.Game$6
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.util.ArrayList.writeObject(ArrayList.java:644)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.lang.reflect.Method.invokeNative(Native Method)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.lang.reflect.Method.invoke(Method.java:511)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1053)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
01-20 21:05:16.693: E/AndroidRuntime(27035):    at android.os.Parcel.writeSerializable(Parcel.java:1176)
01-20 21:05:16.693: E/AndroidRuntime(27035):    ... 23 more

Solution

can't. It will raise a notserializableexception, which refers to the game $6 class, which is an anonymous instance of onturnendedlistener. You can start to create it on the line

gameData.getTurn().addOnTurnEndedListener(...)

It does not extend serializable So either you have to solve the problem or make a decision

private ArrayList<OnTurnEndedListener<T>> turnEndListenerList;

Become a transient variable, whatever you want

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>