слушатель в течение длительного времени, первый звонок, поэтому извинения, если мое форматирование ужасно.Android: Кастинг сериализуется из комплекта сбоев в телефоне, но не эмулятор
TL/DR Версия:
Помещенный сериализации класс [] в пачке/намерение в моей службе. Перейдите на главную деятельность через BroadcastReceiver. Когда вы вытаскиваете объект [] из комплекта и пытаетесь вернуть его в свой собственный класс, на моем телефоне (MOTO Razr HD) происходит свалка, но не в моем эмуляторе Android Studio.
Я только что зашел в Android в течение последних нескольких месяцев и в значительной степени полагался на их учебники/google, поэтому есть хороший шанс, что это может быть разрыв.
Итак, моя цель состоит в том, чтобы иметь сервис, выполняемый во время моих различных действий, и чтобы упомянутая служба отвечала за взаимодействие с сервером (создание шахматной игры, по существу, для работы в андроиде). Эмулятор работал по назначению во время моего тестирования, но когда я запускаю свой телефон, он сбрасывает.
У меня были другие сериализуемые объекты, передаваемые между действиями в пакетах, и это ранее работало нормально. Однако с введением этой услуги, похоже, упускает из виду фактический тип объекта (он показан на скриншотах ниже) и не позволяет мне отбрасывать объект Object [] на мой GameContainer [].
Мой следующий шаг - попробовать другой телефон .... использование SharedPreferences вообще не работало на моем телефоне (логика для этого происходит задолго до того, как происходит свалка), и только начал работать, когда я начал отлаживая мой телефон, несмотря на нулевые изменения в моем исходном коде за это время. Мой телефон может быть просто ранен.
Вот вид отладки моего пучка (ы) в разное время:
изображение # 1 Вот вид отладки моего пучка после того, как я поставил мой GameContainer [] в нем с помощью bundle.putSerializable (String, Obj []) на моем телефоне
image # 2 Вот отладочный вид моего пакета после того, как широковещательный приемник получает его в моей основной деятельности и перед тем, как он попытается выполнить бросок (который вызывает свалку) мой телефон
imgae # 3 И вот здесь то же самое, что и выше, только на моем эмуляторе на моем компьютере.
Я не уверен, что подмножества mMap, бросающие ClassNotFoundException, являются полезными ... Я вижу это как в своем телефоне, так и в эмуляторе, что заставляет меня предположить, что это просто потому, что я помещаю пользовательский класс внутри пакета.
Некоторый код для вас, ребята
моя служба - в частности, порционных под моим Runnalbe если государственные = RequestedGames.
package chess2.Services;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Binder;
import android.util.Log;
import java.util.Date;
import ServerStuff.ChessClass;
import chess2.source.GameBoard;
import chess2.source.GameContainer;
public class ChessService extends Service {
protected ChessClass theGame;
protected String myState = "INITIAL";
protected String returnState = "INITIAL";
protected String returnMessage = "";
protected GameBoard myGB = null;
protected GameContainer[] myGC = null;
protected int myGameIndex = -1;
private static final String RM = "RETURNMESSSAGE";
private static final String RS = "RETURNSTATE";
private static final String RO = "RETURNOBJECT";
private static final String RA = "RETURNOBJECTARRAY";
public static final String SERVER_RESPONSE = "com.botna.chess2.server_response";
private final Handler handler = new Handler();
Intent intent;
private Runnable sendUpdatesToActivity = new Runnable() {
public void run() {
intent.putExtra(RS, returnState);
intent.putExtra(RM, returnMessage);
if (returnState.equals("REQUESTEDGAMES")) {
Bundle b = new Bundle();
b.putSerializable(RA,myGC);
intent.putExtras(b);
}
if (returnState.equals("GAMELOADED"))
{
Bundle b = new Bundle();
b.putSerializable(RO,myGB);
intent.putExtras(b);
}
sendBroadcast(intent);
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
//make sure our connection is still setup.
try {
if (theGame == null) {
theGame = new ChessClass();
}
}
catch(Exception e)
{
//TODO
}
//Gather information out fo the intent and decipher what
//we need to send to the server based on MODE, STATE, PAYLOAD etc
//SEnd it to the server, get our response
//PUt the response in our intent.
//post our updates, which will trigger stuff in the activity.
String state = intent.getStringExtra("STATE");
String result = null;
String[] payload;
switch(state) {
case "INITIAL":
//this specifies the app just resumed activity or did something else that
//caused the onDestory method to get executed.
//we want to try and log in our connection if we have a stored username and pword,
//otherwise, well send a response that the app needs to gather that.
//find out if username and password is stored already.
returnState = "NOSAVEDLOGIN";
break;
case "LOGINATTEMPT":
payload = intent.getStringArrayExtra("PAYLOAD");
if(myState.equals("INITIAL")) {
try {
result = theGame.login(payload[0], payload[1]);
//login was a success.
returnState = "AUTHENTICATED";
returnMessage = result;
myState = "LOGGEDIN";
} catch (Exception e) {
//Wrong username/pwrod/ or generic error.
returnState = "ERROR";
returnMessage = e.getMessage();
}
}
else
returnState = "ALREADYLOGGED";
break;
case "REGISTERATTEMPT":
payload = intent.getStringArrayExtra("PAYLOAD");
try {
result = theGame.register(payload[0], payload[1]);
//login was a success.
returnState = "JUSTTOAST";
returnMessage = result;
} catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
case "CREATEGAME":
payload = intent.getStringArrayExtra("PAYLOAD");
try{
result = theGame.createNewGame(payload[0],payload[1]);
returnState = "JUSTTOAST";
returnMessage = result;
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
case "REQUESTGAMES":
payload = intent.getStringArrayExtra("PAYLOAD");
try{
theGame.refreshGames();
GameContainer[] myGames = theGame.getCurrentGames();
myState = returnState = "REQUESTEDGAMES";
returnMessage = "";
myGC = myGames;
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
case "CHOOSEBLACK":
char variant = intent.getCharExtra("PAYLOAD", 'z');
if(variant != 'z')
{
try {
theGame.updateClassChoice(variant);
//success, start a game jsut the same
returnState = "GAMELOADED";
returnMessage = theGame.getName();
myGB = theGame.getGame();
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
}
case "LOADGAME":
int index = intent.getIntExtra("INDEX", -1);
myGameIndex = index;
try{
result = theGame.loadGame(index);
if(result.equals("SUCCESS")) {
returnState = "GAMELOADED";
returnMessage = theGame.getName();
myGB = theGame.getGame();
}
else
{
//black needs update
returnState = "BLACKUPDATE";
returnMessage = "";
}
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
case "ATTEMPTMOVE":
int[] moves = intent.getIntArrayExtra("PAYLOAD");
try{
result = theGame.sendMove(moves);
returnState = "MOVEMADE";
returnMessage = result;
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
case "REFRESHGAME":
try{
result = theGame.loadGame(myGameIndex);
if(result.equals("SUCCESS")) {
returnState = "GAMELOADED";
returnMessage = theGame.getName();
myGB = theGame.getGame();
}
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
case "ENACTSKIRMISH":
int wager = intent.getIntExtra("PAYLOAD",-1);
try{
result = theGame.sendSkirmish(wager);
returnState = "SKIRMISHSENT";
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
case "FINISHSKIRMISH":
int finish = intent.getIntExtra("PAYLOAD",-1);
try{
result = theGame.finishSkirmish(finish);
returnState = "SKIRMISHSENT";
}
catch (Exception e) {
//invalid username, username already exists, something else.
returnState = "ERROR";
returnMessage = e.getMessage();
}
break;
}
//state suggests what we are being sent from the activity.
//do the needful based on its payload and other stuff,
//send to server, and send back the servers response so our
//activity can do wahtever is necessary from taht point forward.
handler.removeCallbacks(sendUpdatesToActivity);
handler.post(sendUpdatesToActivity);
return Service.START_STICKY;
}
@Override
public void onCreate()
{
super.onCreate();
intent = new Intent(SERVER_RESPONSE);
}
@Override
public void onDestroy()
{
theGame.disconnect();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Вот мой широковещательный приемник в моей основной деятельности, так как им бежать из космоса. В частности, ищите случай «ЗАПРОСИТЬ», чтобы увидеть линию пакета, которую я отметил с помощью ->, чтобы указать на это.
package com.botna.chess2;
import java.util.ArrayList;
import chess2.Services.ChessService;
import chess2.source.GameContainer;
import chess2.Activities.*;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;
import ServerStuff.ChessClass;
public class MainActivity extends ActionBarActivity {
public static final String PREFERENCES = "com.botna.chess2";
public static final String INITIAL = "INITIAL";
public static final String LOGGED = "LOGGED";
private static final String RM = "RETURNMESSSAGE";
private static final String RS = "RETURNSTATE";
private static final String RO = "RETURNOBJECT";
private static final String RA = "RETURNOBJECTARRAY";
protected ChessClass theGame;
protected Toast toast = null;
protected String[] variants={"Classic", "Reapers", "Nemesis","Empowered",
"Animals","Two-Kings"};
protected String[] myGamesString;
protected GameContainer[] myGames;
protected String myName;
protected String state = null;
protected boolean transitioning = false;
protected MainActivity pointer = this;
private Intent myService;
private BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateActivity(intent);
}
};
private void updateActivity(Intent intent)
{
String returnState = intent.getStringExtra(RS);
String returnMessage = intent.getStringExtra(RM);
Bundle b = null;
switch(returnState)
{
case "NOSAVEDLOGIN":
setContentView(R.layout.activity_main);
break;
case "AUTHENTICATED":
setContentView(R.layout.activity_main_menu);
state = LOGGED;
SharedPreferences prefs = getSharedPreferences(PREFERENCES, MODE_PRIVATE);
String restoredUName = prefs.getString("USERNAME", null);
String restoredPWord = prefs.getString("PASSWORD", null);
if(restoredUName == null || restoredPWord == null);
{
//need to save our username and password in the preferences now.
//no previous shared preferences, lets update it.
SharedPreferences.Editor editor = getSharedPreferences(PREFERENCES, MODE_PRIVATE).edit();
editor.putString("USERNAME", myService.getStringArrayExtra("PAYLOAD")[0]);
editor.putString("PASSWORD",myService.getStringArrayExtra("PAYLOAD")[1]);
editor.commit();
}
break;
case "REQUESTEDGAMES":
b = intent.getExtras();
//DUMPS RIGHT HERE AT THE ->
->myGames = (GameContainer[])b.getSerializable(RA);
//myGames = (GameContainer[])intent.getSerializableExtra(RA);
int counter = 1;
if(myGames.length == 0 || myGames[0] == null)
{
toast = Toast.makeText(getApplicationContext(),"You dont have any games =(",Toast.LENGTH_LONG);
toast.show();
}
else
{
ArrayList<String> list = new ArrayList<String>();
String temp;
for(int i = 0; i< myGames.length; i++)
{
if(myGames[i] != null)
{
temp = myGames[i].getWhiteTeam() + " vs " + myGames[i].getBlackTeam() ;
if(myGames[i].getWinner() != null)
{
//game is over.
temp = temp + " - Game Over";
}
else if(myGames[i].getBlackVar() < 'A')
{
temp = temp + " - Awaiting Pick";
}
else if(myGames[i].getTurn().equals(myName))
temp = temp + " - Your Turn";
else
temp = temp + " - Their Turn";
list.add(temp);
counter++;
}
}
myGamesString = null;
myGamesString = list.toArray(new String[list.size()]);
GameChoiceDialog gameDialog = new GameChoiceDialog();
state = "GAMESELECTED";
FragmentManager fm = getSupportFragmentManager();
gameDialog.show(fm, "Dialog Fragment");
}
break;
case "BLACKUPDATE":
ClassChoiceDialog classChoiceDialog = new ClassChoiceDialog();
FragmentManager fm = getSupportFragmentManager();
classChoiceDialog.show(fm, "Dialog Fragment");
break;
case "GAMELOADED":
state = "PLAYINGGAME";
b = intent.getExtras();
Intent playGameIntent = new Intent(this, PlayGameActivity.class);
playGameIntent.putExtras(b);
startActivityForResult(playGameIntent, 0);
break;
case "JUSTTOAST":
case "ERROR":
if(toast != null)
toast.cancel();
toast = Toast.makeText(getApplicationContext(),returnMessage,Toast.LENGTH_LONG);
toast.show();
break;
}
}
и Вот часть моей игры контейнер показывая это Сериализуемый
package chess2.source;
import java.io.Serializable;
import java.util.UUID;
public class GameContainer implements Serializable{
В зависимости от интереса это генерирует, мой следующий шаг будет отойти от радиовещательных приемников и просто привязать к Сервис, в соответствии с моим пониманием с точным 1 учебным пособием, который я прочитал о привязке к службам, он позволяет выполнять методы непосредственно в классе обслуживания, что должно обойти необходимость транспортировки моего GameContainer [] через пучок и широковещательный приемник и просто позволить это параметр возврата.
Любая помощь будет замечательной! Достаточно близко к пределу персонажа, у меня есть намного больше кода, чтобы показать, может ли это быть полезным!
Немного смущает, что я не могу найти статьи об этом ранее, но, по-видимому, java очень тяжело бросает Object [] в CustomClass []. Многие статьи, которые я вижу, показывают, что если он исходит от объекта [], его нужно повторять и касту отдельно. Я должен сделать это и посмотреть, не имеет значения. Когда я думаю об этом, кастинг, который я использовал ранее для этого массива, был прямо из InputStream с моего сервера, поэтому, возможно, он никогда не попадает в состояние посредника «объект», поэтому он не работает сейчас, а не раньше. Все еще не уверен на SIm против телефона. –