2015-02-26 1 views
1

слушатель в течение длительного времени, первый звонок, поэтому извинения, если мое форматирование ужасно.Android: Кастинг сериализуется из комплекта сбоев в телефоне, но не эмулятор

TL/DR Версия:

Помещенный сериализации класс [] в пачке/намерение в моей службе. Перейдите на главную деятельность через BroadcastReceiver. Когда вы вытаскиваете объект [] из комплекта и пытаетесь вернуть его в свой собственный класс, на моем телефоне (MOTO Razr HD) происходит свалка, но не в моем эмуляторе Android Studio.

Я только что зашел в Android в течение последних нескольких месяцев и в значительной степени полагался на их учебники/google, поэтому есть хороший шанс, что это может быть разрыв.

Итак, моя цель состоит в том, чтобы иметь сервис, выполняемый во время моих различных действий, и чтобы упомянутая служба отвечала за взаимодействие с сервером (создание шахматной игры, по существу, для работы в андроиде). Эмулятор работал по назначению во время моего тестирования, но когда я запускаю свой телефон, он сбрасывает.

У меня были другие сериализуемые объекты, передаваемые между действиями в пакетах, и это ранее работало нормально. Однако с введением этой услуги, похоже, упускает из виду фактический тип объекта (он показан на скриншотах ниже) и не позволяет мне отбрасывать объект Object [] на мой GameContainer [].

Мой следующий шаг - попробовать другой телефон .... использование SharedPreferences вообще не работало на моем телефоне (логика для этого происходит задолго до того, как происходит свалка), и только начал работать, когда я начал отлаживая мой телефон, несмотря на нулевые изменения в моем исходном коде за это время. Мой телефон может быть просто ранен.

Вот вид отладки моего пучка (ы) в разное время:

http://imgur.com/a/hu5Tc

изображение # 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 [] через пучок и широковещательный приемник и просто позволить это параметр возврата.

Любая помощь будет замечательной! Достаточно близко к пределу персонажа, у меня есть намного больше кода, чтобы показать, может ли это быть полезным!

+0

Немного смущает, что я не могу найти статьи об этом ранее, но, по-видимому, java очень тяжело бросает Object [] в CustomClass []. Многие статьи, которые я вижу, показывают, что если он исходит от объекта [], его нужно повторять и касту отдельно. Я должен сделать это и посмотреть, не имеет значения. Когда я думаю об этом, кастинг, который я использовал ранее для этого массива, был прямо из InputStream с моего сервера, поэтому, возможно, он никогда не попадает в состояние посредника «объект», поэтому он не работает сейчас, а не раньше. Все еще не уверен на SIm против телефона. –

ответ

0

Java, по-видимому, не любит кастинг из объекта [] в CustomClass []. Тем не менее, делая bundle.getSerializable() и помещая его в Object [], а затем литье каждого объекта индивидуально фиксирует проблему. Должно быть какое-то несоответствие между моим телефоном и моим эмулятором!