尋找這個問題的答案。我正在編寫一個簡單的多人遊戲,我一直試圖在兩個設備上測試它,看看它們是否通信。但是,它在第二個設備上崩潰,儘管它與第一個設備完全相同。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) {
}
}
有什麼建議嗎?如果需要,將發佈更多內容謝謝
.enableAutoManage (this,this)奏效了!非常感謝你!! <3 –