Android应用程序在一台设备上崩溃但在另一台(相同)设备上运行良好?

时间:2017-04-03 15:18:28

标签: android

寻找这个问题的答案。我正在编写一个简单的多人游戏,我一直试图在两台设备上测试它,看看它们是否通信。但是,它在第​​二台设备上崩溃,尽管它与第一台设备完全相同。

这是日志所说的内容:

FATAL EXCEPTION: main
Process: com.example.anna.pokerapp, PID: 29964
    java.lang.IllegalStateException: Could not execute method for android:onClick
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
    at android.view.View.performClick(View.java:5204)
    at android.view.View$PerformClick.run(View.java:21153)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
    at android.view.View.performClick(View.java:5204) 
    at android.view.View$PerformClick.run(View.java:21153) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
    Caused by: java.lang.IllegalStateException: GoogleApiClient must be connected.
    at com.google.android.gms.common.internal.zzac.zza(Unknown Source)
    at com.google.android.gms.games.Games.zzb(Unknown Source)
    at com.google.android.gms.games.Games.zzi(Unknown Source)
    at com.google.android.gms.games.internal.api.RealTimeMultiplayerImpl.getSelectOpponentsIntent(Unknown Source)
    at com.example.anna.pokerapp.QuickGame.onStartMatchClicked(QuickGame.java:50)
    at java.lang.reflect.Method.invoke(Native Method) 
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
    at android.view.View.performClick(View.java:5204) 
    at android.view.View$PerformClick.run(View.java:21153) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)  

它表示googleapiclient存在问题,但如果它在第一台设备上工作正常,那么我还能忽视其他什么吗?它与第一个设备或其他东西相关联吗?那是一件事吗?

这是有问题的活动。它在一台设备上运行但在另一台设备上崩溃:

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.view.WindowManager;

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.games.Games;
    import com.google.android.gms.games.GamesActivityResultCodes;
    import com.google.android.gms.games.GamesStatusCodes;
    import com.google.android.gms.games.multiplayer.Invitation;
    import com.google.android.gms.games.multiplayer.Multiplayer;
    import com.google.android.gms.games.multiplayer.OnInvitationReceivedListener;
    import com.google.android.gms.games.multiplayer.Participant;
    import com.google.android.gms.games.multiplayer.realtime.RealTimeMessage;
    import com.google.android.gms.games.multiplayer.realtime.RealTimeMessageReceivedListener;
    import com.google.android.gms.games.multiplayer.realtime.Room;
    import com.google.android.gms.games.multiplayer.realtime.RoomConfig;
    import com.google.android.gms.games.multiplayer.realtime.RoomStatusUpdateListener;
    import com.google.android.gms.games.multiplayer.realtime.RoomUpdateListener;

    import java.util.ArrayList;
    import java.util.List;

    public class QuickGame extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, RoomUpdateListener, RealTimeMessageReceivedListener, RoomStatusUpdateListener {

        // Variable declarations here
        private GoogleApiClient mGoogleApiClient;
        final static int RC_SELECT_PLAYERS = 10000;
        final static int RC_WAITING_ROOM = 10001;
        boolean mPlaying = false;

        // at least 1 players required for our game
        final static int MIN_PLAYERS = 2;
        private String mRoomId = "PokerApp102";
        private Room mRoom;
        boolean mWaitingRoomFinishedFromCode = false;
        private OnInvitationReceivedListener mListener;
        private String TAG = "Chips-in";
        private final ArrayList<Participant> mParticipants = new ArrayList<Participant>(2);

        public void onStartMatchClicked(View view) {
            Intent intent = Games.RealTimeMultiplayer.getSelectOpponentsIntent(mGoogleApiClient, 1, 2);
            startActivityForResult(intent, RC_SELECT_PLAYERS);
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_quick_game);
            //connect googleapi
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(Games.API).addScope(Games.SCOPE_GAMES)
                    .build();
            mGoogleApiClient.connect();

           // startQuickGame();
        }


        // returns whether there are enough players to start the game - in this case 2
        boolean shouldStartGame(Room room) {
            int connectedPlayers = 0;
            for (Participant p : room.getParticipants()) {
                if (p.isConnectedToRoom()) ++connectedPlayers;
            }
            return connectedPlayers >= MIN_PLAYERS;
        }

        // Returns whether the room is in a state where the game should be cancelled.
        boolean shouldCancelGame(Room room) {
            mRoomId = room.getRoomId();
            mRoom = room;
            return false;
        }

        private void startQuickGame() {
            // auto-matches specified range of players
            Bundle am = RoomConfig.createAutoMatchCriteria(1, 2, 0);
            // Room configuration
            RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder();
            roomConfigBuilder.setAutoMatchCriteria(am);
            RoomConfig roomConfig = roomConfigBuilder.build();
            // Create RTM room
            Games.RealTimeMultiplayer.create(mGoogleApiClient, roomConfig);
            // Screen stays on during handshake!
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            // go to game screen

        }

        @Override
        public void onActivityResult(int request, int response, Intent data) {
            if (request == RC_SELECT_PLAYERS) {
                if (response == Activity.RESULT_OK) {
                    // get the invitee list
                    Bundle extras = data.getExtras();
                    final ArrayList<String> invitees =
                            data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS);

                    // get auto-match criteria
                    Bundle autoMatchCriteria = null;
                    int minAutoMatchPlayers =
                            data.getIntExtra(Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0);
                    int maxAutoMatchPlayers =
                            data.getIntExtra(Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0);

                    if (minAutoMatchPlayers > 0) {
                        autoMatchCriteria = RoomConfig.createAutoMatchCriteria(
                                minAutoMatchPlayers, maxAutoMatchPlayers, 0);
                    } else {
                        autoMatchCriteria = null;
                    }

                    // create the room and specify a variant if appropriate
                    RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder();
                    roomConfigBuilder.addPlayersToInvite(invitees);
                    if (autoMatchCriteria != null) {
                        roomConfigBuilder.setAutoMatchCriteria(autoMatchCriteria);
                    }
                    RoomConfig roomConfig = roomConfigBuilder.build();
                    Games.RealTimeMultiplayer.create(mGoogleApiClient, roomConfig);

                    // prevent screen from sleeping during handshake
                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                }
                else if (response == Activity.RESULT_CANCELED) {
                    // back button pressed - leave room
                    Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId);
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                }
                else if (response == GamesActivityResultCodes.RESULT_LEFT_ROOM) {
                    // player wants to leave the room.
                    Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId);
                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                }
            }
        }

        private RoomConfig.Builder makeBasicRoomConfigBuilder() {
            return RoomConfig.builder(this).setMessageReceivedListener(this).setRoomStatusUpdateListener(this);
        }

        public void onConnected(Bundle connectionHint) {

            if(mGoogleApiClient.isConnected()){
                Log.d(TAG, "GoogleAPIClient connected");
            }
            else{
                Log.d(TAG, "GoogleAPIClient not connected");
            }

            if (connectionHint != null) {
                Invitation inv = connectionHint.getParcelable(Multiplayer.EXTRA_INVITATION);

                if (inv != null) {
                    // accept invitation
                    RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder();
                    roomConfigBuilder.setInvitationIdToAccept(inv.getInvitationId());
                    Games.RealTimeMultiplayer.join(mGoogleApiClient, roomConfigBuilder.build());

                    // prevent screen from sleeping during handshake
                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                    // go to game screen
                }
            }

        }

        @Override
        public void onConnectionSuspended(int i) {
            Log.d(TAG, "onConnectionSuspended() called. Trying to reconnect.");
            mGoogleApiClient.connect();
        }

        // RoomUpdateListener methods:
        // this three methods overridden
        @Override
        public void onRoomCreated(int statusCode, Room room) {
            if (statusCode != GamesStatusCodes.STATUS_OK) {
                // let screen go to sleep
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                // show error message, return to main screen.
                Log.d(TAG, "Room was not created successfully");
                return;
            }
            // get waiting room intent
            Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(mGoogleApiClient, room, Integer.MAX_VALUE);
            startActivityForResult(i, RC_WAITING_ROOM);
            Log.d(TAG, "Room created successfully");
        }

        @Override
        public void onJoinedRoom(int statusCode, Room room) {
            if (statusCode != GamesStatusCodes.STATUS_OK) {
                Log.d(TAG, "Joined room");
                // let screen go to sleep
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                // show error message, return to main screen.

                return;
            }
            // get waiting room intent
            Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(mGoogleApiClient, room, Integer.MAX_VALUE);
            startActivityForResult(i, RC_WAITING_ROOM);
        }

        @Override
        public void onRoomConnected(int statusCode, Room room) {
            if (statusCode != GamesStatusCodes.STATUS_OK) {
                // let screen go to sleep
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                // show error message, return to main screen.
            }
            Log.d(TAG, "Connected to room");
        }

        // Players Connected overridden methods
        @Override
        public void onPeersConnected(Room room, List<String> peers) {
            Log.d(TAG, "Peer connected");
            if (mPlaying) {
                // add new player to an ongoing game
            } else if (shouldStartGame(room)) {
                // start game!
            }
        }

        @Override
        public void onPeersDisconnected(Room room, List<String> peers) {
            if (mPlaying) {
                // do game-specific handling of this -- remove player's avatar
                // from the screen, etc. If not enough players are left for
                // the game to go on, end the game and leave the room.
            } else if (shouldCancelGame(room)) {
                // cancel the game
                Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId);
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            }
        }

        @Override
        public void onPeerLeft(Room room, List<String> peers) {
            // peer left -- see if game should be canceled
            if (!mPlaying && shouldCancelGame(room)) {
                Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId);
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            }
        }

        @Override
        public void onPeerDeclined(Room room, List<String> peers) {
            // peer declined invitation -- see if game should be canceled
            if (!mPlaying && shouldCancelGame(room)) {
                Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId);
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            }
        }

        @Override
        public void onLeftRoom(int statusCode, String roomId) {
            // we have left the room; return to main screen.
            Log.d(TAG, "onLeftRoom, code " + statusCode);
            switchToMainScreen();
        }

        private void switchToMainScreen() {

        }

        private void updateRoom(Room room) {
            if (room == null) {
                return;
            }

            mParticipants.clear();
            mParticipants.addAll(room.getParticipants());
        }

        // RealTimeMessage methods
        // this method's code source: https://github.com/markushi/lib-playutils/blob/master/src/main/java/at/markushi/multiplayer/MultiPlayerHelper.java
        @Override
        public void onRealTimeMessageReceived(RealTimeMessage rtm) {
            final byte[] buf = rtm.getMessageData();
            final String sender = rtm.getSenderParticipantId();
            Log.d(TAG, "Message received from: " + sender);

            Participant participant = null;
            for (Participant p : mParticipants) {
                if (p.getParticipantId().equals(sender)) {
                    participant = p;
                    break;
                }
            }
            if (participant == null) {
                Log.w(TAG, "Received message from unknown participant -> discarding");
            }
        }

        // RoomStatusUpdateListenerMethods
        @Override
        public void onRoomConnecting(Room room) {
            updateRoom(room);
        }

        @Override
        public void onRoomAutoMatching(Room room) {
            updateRoom(room);
        }

        @Override
        public void onPeerInvitedToRoom(Room room, List<String> list) {
            updateRoom(room);
        }

        @Override
        public void onPeerJoined(Room room, List<String> list) {
            updateRoom(room);
        }

        @Override
        public void onConnectedToRoom(Room room) {
          /*  Log.d(TAG, "onConnectedToRoom.");
            roomId = room.getRoomId();
            mParticipants.clear();
            mParticipants.addAll(room.getParticipants());
            userId = room.getParticipantId(Games.Players.getCurrentPlayerId(gameHelper.getApiClient()));*/
        }

        // overridden code
        @Override
        public void onDisconnectedFromRoom(Room room) {
            // leave the room
            Games.RealTimeMultiplayer.leave(mGoogleApiClient, null, mRoomId);

            // clear the flag that keeps the screen on
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

            // show error message and return to main screen
        }

        @Override
        public void onP2PConnected(String s) {
        }

        @Override
        public void onP2PDisconnected(String s) {
        }

        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        }
    }

有什么建议吗?如果要求,会发布更多。谢谢

3 个答案:

答案 0 :(得分:0)

确保Google Play服务是最新的,或两个版本都相同。

  1. 转到设置

  2. 打开应用

  3. 找到Google Play服务,然后进行更新。

答案 1 :(得分:0)

您的应用程序连接到Google Play服务时似乎存在问题,尤其是Google Play游戏。

检查您遇到错误的设备上是否安装了Google Play游戏。如果是,请尝试将Google Play游戏更新为最新版本。

答案 2 :(得分:0)

每当我在一台设备上运行而不是在其他设备上运行的Android应用程序出现错误时,我通常会执行其他人在上面建议的检查。

然后我还检查设备的操作系统版本是否相同。如果不是,我将检查设备上产生错误的版本,看看它是否与API兼容 - 在这种情况下是GMS API。如果是这种情况,您可能应该对代码进行一些调整,以便它可以在不同的操作系统版本上运行。

最后,根据错误日志,它表示&#34; GoogleApiClient必须连接&#34;。在执行任何操作之前,基于GoogleApiClient documentation,必须检查连接。管理连接是使用enableAutoManage。我在上面的代码中看到,这不是在构建器中设置的。您可以尝试像这样添加它:

mGoogleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Games.API).addScope(Games.SCOPE_GAMES)
                .build();

其中: enableAutoManage(FragmentActivity,OnConnectionFailedListener)

来自this site的代码。

如果您仍然遇到IllegalStateException错误,文档也会说

&#34;如果已使用默认的clientId自动管理其他GoogleApiClient。&#34;

所以可能也想检查一下。