第一篇博客

来源:互联网 发布:笛子入门 知乎 编辑:程序博客网 时间:2024/05/22 12:42
如标题所说,这是我第一次写有关java的东西,我一直以一个学习者的身份来对待java,一直以来都是看得多写的少,这次之所以写这篇日志,主要是因为这个bug我调了整整三天,期间试了很多方法也学到了很多东西(手机码字真麻烦,但我又懒得下载电脑版,就这样将就吧),说是一个bug,其实是一连串的bug,这次的安卓聊天程序的开发是直接借鉴上次pc端聊天软件开发的经验,服务器端也是直接用的上次写的服务器端,客户端后台的程序也基本copy PC端的,正是因为这样,出现了各种bug,首先是无法正常登陆,主要表现是,手机上点击登陆后,服务器已经显示客户已登陆但手机上并没有进入下一个界面,最后找到原因是服务器端在接收到客户端的登陆请求后如果成功则给客户端发送loginSuccess包,此包中除了包类型是loginSuccess外还有各种数据,但我在手机端程序中并没有处理,以至于发生bug,解决办法是我让服务器发送phoneLoginSuccess包,此包中先不发送数据以后再完善,解决了bug。

问题并没有完全解决,我在登陆界面(MainActivity)中new了一个Socket对象并以此Socket向服务器端发送消息,进入主界面以后我想继续发送消息给服务器,但是一旦new一个Socket来发送消息给服务器(比如按退出按钮),程序就会闪退,最后我搞明白了TCP是面向连接的,new一个Socket对象即使和前面的Socket参数相同,也是两个不同的连接,因此造成程序崩溃。解决办法是在登录界面完成登陆后,关闭登录界面(前一个界面)的Socket,这样整个客户端就只会有一个Socket了,确实这样程序不会闪退,但是退出按钮好像并不起作用,这个bug我用时最久,通过打印输出的方法我发现服务器端的接受线程(Accept)和服务线程(server)用的是一个socke连接,到这我基本明白了,我登陆用的是一个socket连接,但是登陆成功后我便关闭了该连接,并在主聊天界面上new了一个参数相同的socket连接,表面上看这两个连接是一个连接但其实我们学过TCP连接是由源IP,源端口号,目的IP,目的端口号四项构成其他三项可以认为设置成一样的,但源端口号是系统自动分配,并不一定一样,所以两个参数一样的Socket连接并不是同一个连接,既然如此,服务器端用的连接从始至终都是手机端登陆试用的连接,而手机端登陆成功后就关闭了登陆的连接而重新new了一个新的参数相同但事实上并不同的Socket连接,这就导致我点击推出按钮是并没有反应,就是因为我现在手机上的TCP连接并没有被加到服务器端的服务(Server)线程中去,解决办法是让都有Activity都用同一个Socket对象进行数据传输,在度娘的帮助下找到三种方法(1.单例模式。2.写一个类继承Application并在AndroidMainfest.xml文件中的<application>标签后加一句android:name="MySocket",加这个是因为我写的类名叫MySocket,并在第一次使用时实例化Socket即用MySocket中的setSocket方法,以后再用到Socket时,只需要用MySocket.getSocket()方法即可。3.service)从我码的字数多少也可以明显看出我用的是第二种方法,本以为解决了所有问题,但点击退出按钮还是没有反应,通过打印异常,我发现异常为invalid type code:AC,再次度娘,网友给出的答案是该异常类似于java自身bug一样的存在,主要原因是在一个java文件中ObjectOutputStream对象只能new一次,其他的只能引用该对象(具体原因好像是ObjectOutputStream的自锁),我检查了一遍,发现我真的是new了好几个ObjectOutputStream对象,于是我把ObjectOutputStream对象也放进了MySocket类中,和socket一样写了实例化一个它的get和set方法,并在第一次使用时用set方法实例化一个ObjectOutputStream对象,后面再使用是就可以直接用get方法得到第一次实例化的该ObjeceOutputStream对象。至此,问题完美解决。

码字真是一件痛苦的事,特别是用手机码字,谨以此纪念一下我这三天被bug折磨的生活!!!!!!

最后要对自己说0110 0110 0110!!!
原创粉丝点击