Parcelable 在将对象的实例发送到其他活动时遇到 IOException

Posted

技术标签:

【中文标题】Parcelable 在将对象的实例发送到其他活动时遇到 IOException【英文标题】:Parcelable encountered IOException when sending instance of an object to other activity 【发布时间】:2016-02-21 15:45:10 【问题描述】:

在 activit-main 的 onCreate 中,我创建了一个名为 XMPPConectio 的类 在 XMMPPConnection 的构造函数中,我接受了 activity-main 的实例,因此我执行了一个 Asychtask。在progressUpdate 中,我调用了activity-main 的triger 函数。我想通过intent.putExtra将XMPPconnectio的实例发送到其他活动的触发函数,但我得到了错误

Parcelable 在写入可序列化对象时遇到 IOException

做所有这些的目的是与其他活动建立联系(当它连接时)。

请给我一些示例代码,谢谢

实现 Serializable 的 XMPPConectio 类:

public class XMPPConnectio implements Serializable 


    XMPPTCPConnection connection;
    String connectionMessages="";
    connectionXMPP connectionXMPPAsynch;
    MainActivity mainActivity;


    public XMPPTCPConnection getXMPPConnectio ()
    
        return connection;
    

   public XMPPConnectio(MainActivity mainActivity)
    
    this.mainActivity=mainActivity;
    try
    
        connectionXMPPAsynch =new connectionXMPP();
        connectionXMPPAsynch.execute();
    
    catch (Exception e)
    
    
    

    class connectionXMPP extends AsyncTask<String,Void,String>
    

        @Override
        protected String doInBackground(String... params) 


            connection = new XMPPTCPConnection(XMPPTCPConnectionConfiguration.builder()
            .setServiceName("192.168.1.6")
            .setUsernameAndPassword("ehsan", "123")
            .setPort(9090)
            .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
            .setDebuggerEnabled(true)
            .setCompressionEnabled(false).build());
            connection.setUseStreamManagement(true);
            connection.addConnectionListener(new ConnectionListener()
            

                @Override
                public void connected(XMPPConnection connection) 
                    Log.d("connected", "yes connected successfully : ");
                    publishProgress();
                

                @Override
                public void authenticated(XMPPConnection connection, boolean resumed) 
                    Log.d("connected","yes authenticated successfully : ");
                

                @Override
                public void connectionClosed() 
                    Log.d("connected","yes connectionClosed successfully : ");
                

                @Override
                public void connectionClosedOnError(Exception e) 

                    Log.d("connected","yes connectionClosedOnError  : ");
                

                @Override
                public void reconnectionSuccessful() 
                    Log.d("connected","yes reconnection successfully : ");
                

                @Override
                public void reconnectingIn(int seconds) 
                    Log.d("connected","yes reconnectingIn  : ");
                

                @Override
                public void reconnectionFailed(Exception e) 
                    Log.d("connected","yes reconnectionFailed  : ");
                
            );

           connect();
            return null;
        

        @Override
        protected void onProgressUpdate(Void... values) 
            super.onProgressUpdate(values);
            mainActivity.triger();
        

        @Override
        protected void onPostExecute(String s) 
            super.onPostExecute(s);
            Log.d("","onPostExecute");
        
         private void connect()
        
        try 

                connection.connect();

             catch (SmackException e) 
                e.printStackTrace();
             catch (IOException e) 
                e.printStackTrace();
             catch (XMPPException e) 
                e.printStackTrace();
            
        
    

创建 XMPPConectio 实例并导致 Asychtask 执行的 Activity

package passargad.ehsan;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.Socket;

public class MainActivity extends ActionBarActivity implements Serializable 


    private Socket socket;
    private String serverIpAddress = "192.168.1.6";
    XMPPConnectio xmppConnectio;
    XMPPTCPConnection connection;
    private static final int REDIRECTED_SERVERPORT = 6789;


    FastFood fastFood;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent=new Intent(this,SocketService.class);
        startService(intent);

        fastFood =new FastFood(this);

        xmppConnectio=new XMPPConnectio(this);


    

// this is the function which is called (when connection is done ) by //onProgressUpdate of Asychtask 

   public void triger()
    


        try 
            Intent intent=  new Intent(this,chat.class);
            intent.putExtra("XMPP",xmppConnectio);
             startActivity(intent);
         catch (Exception e) 
            e.printStackTrace();
        


    



这是我希望在其中包含 XMPPConnectio 但执行从未达到此目的的活动

package passargad.ehsan;

import android.app.Application;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;

import java.io.IOException;


public class chat extends ActionBarActivity 
    XMPPConnectio xmppConnectio;
    XMPPTCPConnection connection;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);


        xmppConnectio=(XMPPConnectio)getIntent().getSerializableExtra("XMPP");
        Log.d("","done");
 

我试图通过提供所有代码来使问题变得清晰。正如我所说,目标是在连接连接时在所有活动中建立连接。 谢谢。

【问题讨论】:

【参考方案1】:

如果我想在每个活动中都可以访问连接对象,其中一种解决方案是使用捆绑包并有意发送捆绑包。但实际问题是 API 级别 10(android 2.3)中没有捆绑选项。另一个问题是,由于 XMPPTCPConnection 没有实现可序列化,因此无法选择使用序列化和 putExtra。所以我使用了第三个选项,它定义了静态对象。

所以我把 XMPPConectio 类改成了这个

 import android.app.Application;
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.os.IBinder;
    import android.util.Log;

    import org.jivesoftware.smack.ConnectionConfiguration;
    import org.jivesoftware.smack.ConnectionListener;
    import org.jivesoftware.smack.SmackException;
    import org.jivesoftware.smack.XMPPConnection;
    import org.jivesoftware.smack.XMPPException;
    import org.jivesoftware.smack.chat.Chat;
    import org.jivesoftware.smack.chat.ChatManager;
    import org.jivesoftware.smack.chat.ChatManagerListener;
    import org.jivesoftware.smack.chat.ChatMessageListener;
    import org.jivesoftware.smack.packet.Message;
    import org.jivesoftware.smack.tcp.XMPPTCPConnection;
    import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;

    import java.io.IOException;
    import java.io.Serializable;


    public class XMPPConnectio  


        XMPPTCPConnection connection;
        String connectionMessages="";
        connectionXMPP connectionXMPPAsynch;
        MainActivity mainActivity;


        public XMPPTCPConnection getXMPPConnectio ()
        
            return connection;
        

       public XMPPConnectio(MainActivity mainActivity)
        
        this.mainActivity=mainActivity;
        try
        
            connectionXMPPAsynch =new connectionXMPP();
            connectionXMPPAsynch.execute();
        
        catch (Exception e)
        
        
        

        class connectionXMPP extends AsyncTask<String,Void,String>
        

            @Override
            protected String doInBackground(String... params) 


                connection = new XMPPTCPConnection(XMPPTCPConnectionConfiguration.builder()
                .setServiceName("192.168.1.6")
                .setUsernameAndPassword("ehsan", "123")
                .setPort(9090)
                .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
                .setDebuggerEnabled(true)
                .setCompressionEnabled(false).build());
                connection.setUseStreamManagement(true);
                connection.addConnectionListener(new ConnectionListener()
                

                    @Override
                    public void connected(XMPPConnection connection) 

                        Log.d("connected","yes connected successfully : ");
                        publishProgress();
                    

                    @Override
                    public void authenticated(XMPPConnection connection, boolean resumed) 
                        Log.d("connected","yes authenticated successfully : ");

                    

                    @Override
                    public void connectionClosed() 
                        Log.d("connected","yes connectionClosed successfully : ");
                    

                    @Override
                    public void connectionClosedOnError(Exception e) 

                        Log.d("connected","yes connectionClosedOnError  : ");
                    

                    @Override
                    public void reconnectionSuccessful() 
                        Log.d("connected","yes reconnection successfully : ");
                    

                    @Override
                    public void reconnectingIn(int seconds) 
                        Log.d("connected","yes reconnectingIn  : ");
                    

                    @Override
                    public void reconnectionFailed(Exception e) 
                        Log.d("connected","yes reconnectionFailed  : ");
                    
                );

               connect();
                return null;
            

            @Override
            protected void onProgressUpdate(Void... values) 
                super.onProgressUpdate(values);
                mainActivity.triger();
            

            @Override
            protected void onPostExecute(String s) 
                super.onPostExecute(s);
                Log.d("","onPostExecute");
            
             private void connect()
            
            try 

                    connection.connect();
                   // connection.login();

                 catch (SmackException e) 
                    e.printStackTrace();
                 catch (IOException e) 
                    e.printStackTrace();
                 catch (XMPPException e) 
                    e.printStackTrace();
                
            
        
    

创建 XMPPConectio 实例并导致 Asychtask 执行的 Activity

package passargad.ehsan;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.Socket;

public class MainActivity extends ActionBarActivity 

private Socket socket;
private String serverIpAddress = "192.168.1.6";
XMPPConnectio xmppConnectio;
public static XMPPTCPConnection connection;
private static final int REDIRECTED_SERVERPORT = 6789;


FastFood fastFood;
@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Intent intent=new Intent(this,SocketService.class);
    startService(intent);
    fastFood =new FastFood(this);

    //this is
    xmppConnectio=new XMPPConnectio(this);





public void triger()


    connection=xmppConnectio.getXMPPConnectio();
    Intent intent=  new Intent(this,chat.class);
    startActivity(intent);


这是我们可以访问那里的连接的活动

package passargad.ehsan;

import android.app.Application;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;

import java.io.IOException;


public class chat extends ActionBarActivity 
XMPPTCPConnection connection;
@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);

    //this is
        connection=MainActivity.connection;
        connection.addConnectionListener(new ConnectionListener() 
            @Override
            public void connected(XMPPConnection connection) 
                Log.d("","connected");

            
        @Override
        public void authenticated(XMPPConnection connection, boolean resumed) 
            Log.d("","6");
        

        @Override
        public void connectionClosed() 
            Log.d("","5");
        

        @Override
        public void connectionClosedOnError(Exception e) 
            Log.d("","4");
        

        @Override
        public void reconnectionSuccessful() 
            Log.d("","3");
        

        @Override
        public void reconnectingIn(int seconds) 
            Log.d("","2");
        

        @Override
        public void reconnectionFailed(Exception e) 
            Log.d("","1");
        
    );
    try 
        connection.login();
     catch (XMPPException e) 
        e.printStackTrace();
     catch (SmackException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
    




【讨论】:

以上是关于Parcelable 在将对象的实例发送到其他活动时遇到 IOException的主要内容,如果未能解决你的问题,请参考以下文章

将对象从服务发送到活动(无法编组非 Parcelable)

如何通过 Parcelable 接口将 WifiP2pManager 对象发送到另一个活动

Parcelable 用于进程通信的效率

如何通过parcelable发送包含列表的列表对象

使用 Parcelable 而不是序列化对象的好处

将 parcelable 对象传递给新活动返回 null