Android AsyncTask引起的NotSerializableException

Android AsyncTask引起的NotSerializableException,android,android-studio,android-asynctask,parcelable,serializable,Android,Android Studio,Android Asynctask,Parcelable,Serializable,我想在活动之间导航并传递对象。 对象是客户端(电话)和服务器(计算机)之间的Tcp连接。当用户按下按钮时,新活动将启动,用户将重定向到新页面 我希望能够从不同的活动向服务器发送某些命令 但是,我在活动之间传递对象时遇到问题。 每当我尝试转到下一个活动时,都会出现以下错误: java.lang.RuntimeException:Parcelable在写入可序列化对象时遇到IOException 原因:java.io.NotSerializableException: com.example.use

我想在活动之间导航并传递对象。 对象是客户端(电话)和服务器(计算机)之间的Tcp连接。当用户按下按钮时,新活动将启动,用户将重定向到新页面

我希望能够从不同的活动向服务器发送某些命令

但是,我在活动之间传递对象时遇到问题。 每当我尝试转到下一个活动时,都会出现以下错误:

java.lang.RuntimeException:Parcelable在写入可序列化对象时遇到IOException 原因:java.io.NotSerializableException: com.example.user.myapp.HomePage$ConnectTask$1

Asynctask正在抛出错误,我相信它不是的副本。 所有类都已实现可序列化

在我的onCreate中

    connecttask = new ConnectTask();
    connecttask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

    final Intent i = new Intent(getBaseContext(),Menu.class);
    final ArrayList<TcpClient> testing = new ArrayList<TcpClient>();
异步任务:

public class ConnectTask extends AsyncTask<String, String, TcpClient> implements Serializable {

    @Override
    protected TcpClient doInBackground(String... message) {

        System.out.println("Executed call");
        mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
            @Override
            public void messageReceived(String message) {
                try {
                    publishProgress(message);
                    if (message != null) {
                        System.out.println("Returned message from socket::::: >>>>>>" + message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, ipAddressOfServerDevice);
        if (mTcpClient != null) {
            mTcpClient.sendMessage("Initial message when connected with Socket Server");
        }
        delay();
        return mTcpClient;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        arrayList.add(values[0]);
        mAdapter.notifyDataSetChanged();
    }
}
公共类ConnectTask扩展AsyncTask实现可序列化{
@凌驾
受保护的TcpClient doInBackground(字符串…消息){
System.out.println(“已执行调用”);
mTcpClient=新的TcpClient(新的TcpClient.OnMessageReceived(){
@凌驾
已接收公共无效消息(字符串消息){
试一试{
出版进度(信息);
如果(消息!=null){
System.out.println(“从套接字返回的消息::>>>>>”+消息);
}
}捕获(例外e){
e、 printStackTrace();
}
}
},ipAddressOfServerDevice);
if(mTcpClient!=null){
mTcpClient.sendMessage(“与套接字服务器连接时的初始消息”);
}
延迟();
返回mTcpClient;
}
@凌驾
受保护的void onProgressUpdate(字符串…值){
super.onProgressUpdate(值);
arrayList.add(值[0]);
mAdapter.notifyDataSetChanged();
}
}
想想“可包裹”是什么意思。这意味着您可以将其序列化为二进制流,并可能在进程之间传递它。你怎么能用一个任务或一个线程来完成呢?没有发生

您需要稍微阅读一下活动生命周期,以及管理比活动寿命更长的对象的各种策略

您需要考虑的场景。(1) 你的活动会因为方向的改变(活动的短期终止)而被拆除和恢复。(2) 您的活动进入后台,因此android会删除您的应用程序,并在稍后重新启动(活动的长期终止)。(3) 您的应用程序进入后台,Android终止整个过程,目的是稍后将其从序列化状态恢复。场景(3)是使用包裹序列化活动状态的原因:包裹被写入某个临时存储器,进程终止,很长一段时间后重新启动,包裹从临时存储器读取,一个新的活动开始于那些作为适当参数提供的包裹。很明显,你的线程将无法生存

正确的做法是将整个TCP连接包装在一个服务中,如果Android希望在进程进入后台时终止进程,并在以后重新启动进程,那么这个服务将更好地生存。服务的优势在于,即使你的应用程序在后台,它也可以在后台状态下运行30分钟;如果你为你的服务发布通知,那就永远如此。服务管理有些痛苦;但很多痛苦都和你们必须做的事情有关。最大的痛苦是您的活动必须完全删除后台任务中的所有回调,这样应用程序才能被垃圾收集。该服务提供了一个这样做的框架,以及一些可能有用的生命周期管理

您还可以使用片段(没有UI)来解决场景(1)。在场景(2)中有一段时间。您可以认为,对于简单的连接,片段任务是合适的。但是我的猜测是,一旦你连接了,你会在维护连接时遇到同样的问题。所以服务可能是正确的选择。或者是一个片段,负责将异步TCP操作引导到后台线程上,然后再返回

如果您的TCP连接完全是一次性的,并且您不介意丢失它,那么您也可以使用静态变量。不过,在管理生命周期时确实需要非常小心,在挂起对已终止活动的引用时也要非常小心


有点痛。但是,如果您完成了所有这些工作,并且如果您选择自定义解决方案,那么实现服务的大部分艰苦工作都必须以其他方式完成。

可能重复@ADM我已经读到了,我相信这是一个不同的问题,因为抛出可序列化错误的是AsyncTask。没有区别?既然我必须执行“public static transient ConnectTask ConnectTask=null”,我如何声明它?
AsyncTask
不是
Parcelable
。你为什么要做这样的事?如果您想与多个活动共享同一个对象,那么只需为其创建一个Singleton实用程序类。
public class ConnectTask extends AsyncTask<String, String, TcpClient> implements Serializable {

    @Override
    protected TcpClient doInBackground(String... message) {

        System.out.println("Executed call");
        mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
            @Override
            public void messageReceived(String message) {
                try {
                    publishProgress(message);
                    if (message != null) {
                        System.out.println("Returned message from socket::::: >>>>>>" + message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, ipAddressOfServerDevice);
        if (mTcpClient != null) {
            mTcpClient.sendMessage("Initial message when connected with Socket Server");
        }
        delay();
        return mTcpClient;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        arrayList.add(values[0]);
        mAdapter.notifyDataSetChanged();
    }
}