Android - 即使使用 .reset(),ObjectInputStream 也会继续读取先前的值
Posted
技术标签:
【中文标题】Android - 即使使用 .reset(),ObjectInputStream 也会继续读取先前的值【英文标题】:Android - ObjectInputStream keeps on reading the previous value even with .reset() 【发布时间】:2013-05-04 09:18:12 【问题描述】:我正在构建一个用于在两部 android 手机之间发送文件的应用程序,现在我有一个 ListActivity 可以检索 sdcard 并列出文件,当 ListActivity 第一次在两台设备上启动时,会设置一个 ServerSocket 并使用 @987654322 进行侦听@...
这个线程在 ListActivity 启动时启动:
ReceiveFileSendRequestThread ReceiveFileSendRequestThread = new ReceiveFileSendRequestThread();
ReceiveFileSendRequestThread.start();
这是完整的线程类:
static public class ReceiveFileSendRequestThread extends Thread
public void run()
ServerSocket serverSocket;
try
serverSocket = new ServerSocket(6789, 200);
connectionServ = serverSocket.accept();
requestFileInServer = new ObjectInputStream(
connectionServ.getInputStream());
requestFileString = (String) requestFileInServer.readObject();
handler.post(new AcceptFileSendAlertDialogRunnable());
while (okToSend == null)
if (okToSend == true)
requestFileOutServer = new ObjectOutputStream(
connectionServ.getOutputStream());
requestFileOutServer.writeObject("oktosend");
requestFileOutServer.flush();
serverSocket.close(); // // Receive File
else if (okToSend == false)
requestFileOutServer = new ObjectOutputStream(
connectionServ.getOutputStream());
requestFileOutServer.reset();
requestFileOutServer.writeObject("notosend");
requestFileOutServer.flush();
serverSocket.close();
ReceiveFileSendRequestThread ReceiveFileSendRequestThread = new ReceiveFileSendRequestThread();
ReceiveFileSendRequestThread.start();
catch (IOException e)
Log.d("Connection Error:", "Error binding port!");
e.printStackTrace();
catch (ClassNotFoundException e)
// TODO Auto-generated catch block
e.printStackTrace();
当 onLongClick 一个项目(发送文件)时,以下线程启动:
public boolean onItemLongClick(AdapterView<?> parentView, View childView,
int position, long id)
// TODO Auto-generated method stub
fileClickedName = (((TextView) childView).getText()).toString();
fileClickedPath = file.toString() + "/" + fileClickedName;
fileClickedFile = new File(fileClickedPath);
SendFileThread SendFileThread = new SendFileThread();
SendFileThread.start();
return true;
发送文件线程:
static public class SendFileThread extends Thread
public void run()
Socket socket = new Socket();
try
socket.connect(new InetSocketAddress(sharedIp, 6789), 200);
requestFileOutClient = new ObjectOutputStream(
socket.getOutputStream());
requestFileOutClient.writeObject(fileClickedName);
requestFileOutClient.flush();
requestFileInClient = new ObjectInputStream(
socket.getInputStream());
toSendOrNot = (String) requestFileInClient.readObject();
if (toSendOrNot.equals("oktosend"))
socket.close();
else if (toSendOrNot.equals("notosend"))
socket.close();
ReceiveFileSendRequestThread ReceiveFileSendRequestThread = new ReceiveFileSendRequestThread();
ReceiveFileSendRequestThread.start();
handler.post(new ClientFileSendAlertDialogRunnable());
// //
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (ClassNotFoundException e)
// TODO Auto-generated catch block
e.printStackTrace();
现在,当我启动 ListActivity 并 longClick 一个项目时,文件名被发送到第二台设备,第二台设备弹出一个 alertDialog 询问用户是否接受文件,(接受文件仍然现在还没有准备好)如果用户按下 CANCEL(在 ReceiveFileSendRequestThread 上)一个字符串被发送到第一个设备"notosend"
,第一个用户接收到字符串"notosend"
并且根据该线程关闭套接字并重新调用如果他想发送另一个文件,线程会监听第二个对等方,并弹出一个 alertDialog 告诉第一个用户您的文件被拒绝接收...>>>>这完全可行>>>>但是当第一个设备尝试发送另一个文件(再次长按文件 [列表中的项目])第二个用户成功接收第一个用户选择的新文件名,如果接受或取消,则会弹出 alertDialog 但第一个用户收到文件发送被拒绝......没有第二个d 用户按下取消按钮!!! ...我不知道为什么toSendOrNot = (String) requestFileInClient.readObject();
继续采用以前的值,甚至没有等待第二个设备写入新对象。
如果有人可以帮助我,我将不胜感激,非常感谢。
【问题讨论】:
我也有这个问题..我读到 ObjectInputStream 和 ObjectOutputStream 有一个缓存内存..重置方法应该清除缓存,所以新数据将通过它..在我的情况下它有效但是当我发送一条新消息时,它会重复该消息..这是我的帖子..但没有人回答..也许那里的代码会给你一些关于如何解决你的问题的想法,***.com/questions/16318526/… @Elior ,感谢您的贡献,我跟踪了您的代码,但不幸的是没有任何帮助...关于缓存,我也读过它,可以使用以下方法重置:.reset()
其主要目的是:重置流的状态并避免循环引用,我所做的方式应该是有效的,但没有机会......正在努力,但到目前为止我没有找到解决方案。
这里有太多无法运行的代码。将其简化为独立的测试用例。该过程可能会消除错误,这本身就是有益的。我注意到您在ReceiveFileSendRequestThread
中的每次发送都创建了一个新的ObjectOutputStream
。仅此一项就可能导致问题。在套接字的整个生命周期中,两端都必须使用相同的 ObjectInput/OutputStreams
。
@Elior ,我认为你必须为你的变量做一些清理工作。
@EJP ,现在它运行良好,感谢您的建议 > 我已经编辑了我的代码,所以它只有一个 ObjectInputStream
, ObjectOutputStream
用于套接字的生命周期。 :D
【参考方案1】:
经过几个小时的调试>>>我终于找到了错误!
在线程ReceiveFileSendRequestThread()
中,Boolean
变量okToSend
在第一次接收来自第二个设备的请求时为空,当第二个设备取消请求时,oKtoSend
将设置为notosend
,因此每当第二个设备尝试要发送另一个文件,变量okToSend
将始终具有先前分配的值。所以我只是在while
循环之前添加了okToSend = null;
,现在可以正常工作了。
【讨论】:
但是当你发送一个新数据时,它是重复的吗?我的意思是,在我的情况下,当我发送第一条消息时,我只发送一次,但客户端设备读取了两次,而当我发送第二条消息时,客户端读取了四次..以上是关于Android - 即使使用 .reset(),ObjectInputStream 也会继续读取先前的值的主要内容,如果未能解决你的问题,请参考以下文章
Office365 - 如何在Android手机中reset OneDrive
FlinkHttpClient 报错 I/O SocketException caught when processing request to Connection Reset