【问题标题】:Android - sending instance of class X from activity A to activity BAndroid - 将 X 类的实例从活动 A 发送到活动 B
【发布时间】:2015-11-22 22:05:11
【问题描述】:

我正在尝试从我的 Mainactivity 将我的 Connection 类发送到我的 Mapsactivity,以便我可以使用我的 Mapsactivity 中的 Connection 类中的方法。

由于某种原因,我在启动 Mapsactivity 时遇到此错误,

java.lang.RuntimeException: Parcelable 在写入可序列化对象时遇到 IOException

我不太确定问题出在哪里,我的 Connection 类已经实现了 Serializable,我还让我的 Mainactivity 实现了 Serializable 以查看它是否会修复但没有成功。

我的应用程序应该让人们连接到服务器,他们将位置发送到服务器,并从连接的其他人那里接收位置,并将坐标放在他们的地图上。我已经删除了与此问题无关的代码,因此要阅读的内容更少。我相信我已经获得了所有必要的代码,如果还不够,我可以发布整个课程。 提前致谢

MainActivity 类

public class MainActivity extends FragmentActivity{
private Connection connection;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initialize();
    setListeners();
}

public void initialize() {
    connection = new Connection("xxx.xxx.xxx.x",xxxx);
    btnShowMap = (Button)findViewById(R.id.btnShowMap);
    Log.w(null, "Initialized");
}

public void startMap() {
    Intent intent = new Intent(this, MapsActivity.class);
    intent.putExtra("class", connection);
    startActivity(intent);
}

public void setListeners() {
    btnShowMap.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            btnShowMap.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    startMap();
                }
            });
        }
    });
}

连接类

    public class Connection implements Serializable{
private InetAddress address;
private int port;
private String ip, groupName, myName, total, membersInfo, id, fName;
private Socket socket;
private InputStream is;
private DataInputStream dis;
private OutputStream os;
private DataOutputStream dos;
private boolean connected = false;
private double latitude, longitude, fLong ,fLat;
private String name;
private double Longi, Lati;

public Connection(String ip, int port){
    this.ip = ip;
    this.port = port;
}

public void listenToServer() {
    Thread thread = new Thread(new ListenToServer());
    thread.start();
}

private class ListenToServer implements Runnable {
    public void run() {
        Log.w(null,"Listening to server");
        try {
            String locations = new String(dis.readUTF());
            if(locations == null) {
                Log.e(null,"EMPTY");
            }
            if(locations != null) {
                JSONObject friends = new JSONObject(locations);
                JSONArray jsonArray = friends.getJSONArray("location");
                JSONObject transaction;
                for (int i = 0; i < jsonArray.length(); i++) {
                    transaction = jsonArray.getJSONObject(i);
                    fName = transaction.getString("member");
                    fLong = transaction.getDouble("longitude");
                    fLat = transaction.getDouble("latitude");
                }
            }
            if (locations == null) {
                dis.close();
            }
        }
        catch (JSONException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

MapsActivity 类

public class MapsActivity extends FragmentActivity {

private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private LocationManager locationManager;
private LocationListener locationListener;
private double latitude, longitude, flat, flong;
private String friendName;
private boolean addMarker = false;
private Connection connection;
private Button btnAddMyMarker, btnAddFriendMarker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    initialize();
    setListener();
}

public void initialize() {
    btnAddMyMarker = (Button)findViewById(R.id.btnAddMyMarker);
    btnAddMyMarker.setEnabled(false);
    btnAddFriendMarker = (Button)findViewById(R.id.btnAddFriendMarker);
    connection = (Connection) getIntent().getSerializableExtra("class");
    mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
            .getMap();
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationListener = new LocList();

}

public void setListener() {
    btnAddMyMarker.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            addMyMarker();
        }
    });

    btnAddFriendMarker.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            connection.listenToServer();
        }
    });
}


public void addMyMarker() {
    mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("My position"));
}

private class LocList implements LocationListener {
    @Override
    public void onLocationChanged(Location location) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        if(addMarker == false && longitude != 0 && latitude != 0) {
            btnAddMyMarker.setEnabled(true);
        }
        connection.sendLocation(latitude, longitude);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

【问题讨论】:

    标签: java android android-intent android-activity runtimeexception


    【解决方案1】:

    您将无法在活动之间传递Connection,因为其中的大部分内容无法序列化或转换为Parcel。值得注意的是,以下都不支持任一操作:

    private InputStream is;
    private DataInputStream dis;
    private OutputStream os;
    private DataOutputStream dos;
    

    要么:

    • 这应该是一项服务,特别是如果工作应该独立于任何 UI 来完成,或者

    • 这需要是单例,或者

    • 不要有单独的活动,而是一个活动有多个片段,或者

    • 将所有与连接相关的工作隔离到一个活动中

    【讨论】:

      【解决方案2】:

      正如 CommonsWare 所说,您需要重新考虑您的设计,连接通常独立于您拥有的活动,因为大多数活动可能必须使用它,因为您注意到自己。

      您可以做的是创建Application 的子类,以将Connection 维护为所有活动都可访问的全局实例:例如单例。

          public class MyApp extends Application{
      
                public void onCreate(){
                  super.onCreate();           
                }
      
                private static Connection con=null;
      
                private Connection(){
      
                   //initialize a connection here
      
                }
      
                public static Connection getConnection(){
      
                    if(con==null){
      
                   con=new Connection();
                   return con;
                    }else{
      
                     return con;
                    }        
      
                }
           }
      

      这样您就可以通过调用 MyApp.getConnection() 从任何 Activity 访问 Connection con。只是不要忘记将 MyApp 添加到您的清单中

      This link should be helpful

      【讨论】:

        猜你喜欢
        • 2021-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-30
        • 1970-01-01
        • 2020-06-14
        • 1970-01-01
        • 2018-07-10
        相关资源
        最近更新 更多