全部 文章 问答 分享 共找到127个相关内容
[文章] c语言入门(1)
#C语言的最框架#include<stdio.h>intmain(){....;....;....
2019-09-27 22:16 · 基础 / C语言入门 / 0基础学编程
[文章] 压缩GIF吗
1.背景对于网络传输照片和文件大小肯定是越小越好这点沙滩康师傅也是做了些后台判断图片小于500k才提供上传(亲测gif将近3M也能传应该是后台接口没限制gif后缀文件)但是为了服务器压力还是尽量压缩下图和动图吧2.起因和查阅资料因为本来想发gif动态图进行展示的发现原先压缩图片的代码对于gif不生效有查阅了一些资料博客和掘金等网站都是好几年前的水wen帮助不大(可以说10篇9篇广告剩下一篇还是图片压缩)周日无聊拿着手机掘金APP一搜就搜到了一篇文章不过博主没有进行很详细的解析贴出了github地址和使用方法3.原博贴:Android压缩GIF格式图片4.在我简化实操最终生成以下代码可以说每张gif可以减少最少一半的内存(其实原理很简单就是单纯抽帧保留多少帧后将帧再写入文件内就完成了)github引用第三方库gifFilehttps://github.com/koral--/android-gif-drawable一个实现类https://github.com/nbadal/android-gif-encoder首先需要能够获取gif的路径这一步自行解决啦代码如下/***先把GIF分解成bitmap,进行减帧操作,最后合成一张新的GIF*1.根据文件指定文件长度进行压缩*@paramgifFilegif文件*@paramtargetLength压缩的目标体积*@paramsavePath压缩后的保存路径*/publicstaticStringcompressFrame(FilegifFile,longtargetLength,StringsavePath){GifDrawablegifDrawable=null;try{longgifFileLength=gifFile.length()/1024;SLog.e("compressFramefilegifFileLength="+gifFileLength);gifDrawable=newpl.droidsonroids.gif.GifDrawable(gifFile);if(gifFileLength>targetLength){//计算压缩比例例如是2每2张取1张3456同理intmold=(int)Math.ceil(gifFileLength*1.0/targetLength)+1;SLog.e("compressFramefilemold="+mold);returncompressFrameGif(gifDrawable,mold,savePath);}}catch(Exceptione){SLog.e("compressFrameGife="+e.toString());}finally{if(gifDrawable!=null){gifDrawable.recycle();}}returnsavePath;}/***先把GIF分解成bitmap,进行减帧操作,最后合成一张新的GIF*2.根据指定帧数进行压缩*@paramgifFilegif文件*@parammaxFrames最大帧数*@paramsavePath压缩后的保存路径*/publicstaticStringcompressFrame(FilegifFile,intmaxFrames,StringsavePath){GifDrawablegifDrawable=null;try{gifDrawable=newGifDrawable(gifFile);intgifFrames=gifDrawable.getNumberOfFrames();if(gifFrames>maxFrames){//计算压缩比例例如是2每2张取1张3456同理intmold=(int)(Math.ceil(gifFrames*1.0/maxFrames))+1;returncompressFrameGif(gifDrawable,mold,savePath);}}catch(Exceptione){SLog.e("compressFrameGife="+e.toString());}finally{if(gifDrawable!=null){gifDrawable.recycle();}}returnsavePath;}//写入保存路径抽离方法privatestaticStringcompressFrameGif(GifDrawablegifDrawable,intmold,StringsavePath){ByteArrayOutputStreambos=null;FileOutputStreamoutStream=null;try{intgifFrames=gifDrawable.getNumberOfFrames();intgifDuration=gifDrawable.getDuration();bos=newByteArrayOutputStream();AnimatedGifEncoderencoder=newAnimatedGifEncoder();encoder.setRepeat(0);encoder.start(bos);encoder.setDelay(gifDuration/gifFrames);//核心内容抽帧并添加帧进入文件类for(inti=0;i<gifFrames;i++){//这里需要各自去定制本质上抽出来的帧数的大小都会比原图帧的大如何缩减达到减少内存的效果if(i%mold==0){encoder.addFrame(gifDrawable.seekToFrameAndGet(i));}}encoder.finish();outStream=newFileOutputStream(savePath);outStream.write(bos.toByteArray());}catch(Exceptione){SLog.e("compressFrameGife="+e.toString());}finally{try{if(bos!=null){bos.close();}if(outStream!=null){outStream.close();}returnsavePath;}catch(Exceptione){e.printStackTrace();}}returnsavePath;}如何使用涉及IO写入开启线程这里使用的是RxjavapublicstaticfinalStringSLASH="/";/***压缩GIF*/privatevoidcompressionGif(Stringpath){//转GIFStringdirectoryPrefix=context.getExternalFilesDir("").getAbsolutePath()+ImageCompressUtils.SLASH;Stringimagepath=directoryPrefix+"sugar"+ImageCompressUtils.SLASH+"image"+ImageCompressUtils.SLASH;Filefile=newFile(imagepath);if(!file.exists()){file.mkdirs();}Observable<String>observable=Observable.create(newObservableOnSubscribe<String>(){@Overridepublicvoidsubscribe(@io.reactivex.annotations.NonNullObservableEmitter<String>e)throwsException{FilecompressImageFile=null;compressImageFile=File.createTempFile("image",".gif",file);Strings=ImageCompressUtils.compressFrame(newFile(path),24,compressImageFile.getAbsolutePath());//s=ImageCompressUtils.compressFrame(newFile(path),500l,compressImageFile.getAbsolutePath());e.onNext(s);e.onComplete();}});observable.subscribeOn(Schedulers.io());observable.observeOn(AndroidSchedulers.mainThread());observable.subscribe(newObserver<String>(){@OverridepublicvoidonSubscribe(@io.reactivex.annotations.NonNullDisposabled){}@OverridepublicvoidonNext(@io.reactivex.annotations.NonNullStringcompath){if(!TextUtils.isEmpty(compath)){pic_file=newFile(compath);//上传操作或者进行Glide显示都可}}@OverridepublicvoidonError(@io.reactivex.annotations.NonNullThrowablee){}@OverridepublicvoidonComplete(){}});}压缩图片的代码挺多的这gif说是压缩其实减少帧的数量达到大小减小但是损坏了画质或者应该说是流畅度对于原图质量要求高的要谨慎使用有问题沙滩联系啦!!内卷起来吧滩友们!
2022-08-09 14:58 · GIF / gif / GIF压缩
[问答] 关于DayNightMode切换recreate的问题
找了很多的博客和github上的demo,也去StackOverflow看了一些例子,但是就是没找到和我这个很像的情况,要不就是太老了,要不就是重复的,看到的最像的就是android端的酷安和书了,都是一个
2020-04-13 22:38 · Android / 夜间模式 / DayNightMode
[问答] 顶部标题栏和底部导航栏具体怎么做?找了很多教程,一个教程一个写法,快晕了!救救孩子吧
救救孩子吧


顶部标题栏没有找到一个系统性学习的地方,包括返回键、自定义按钮啥的


底部导航栏在CSDN上、Github上、书、知乎等各种平台都找了

[问答] 获取知识方式

各位大佬们,我有个问题,就是平时你们通过怎么样去学习了解新的知识的(比如说通过什么网站之类的),比如说去学习Handler的话,去看官方文档的话又有点吃力,去看书之类的话又不知道从哪看起

2022-05-11 16:33 · 安卓学习
[问答] 学习路线
完中级领券联盟,是否要高级课程AOSP了。
2020-12-08 13:23 ·
[问答] 求初学Android学习路线

大佬们,刚开始Android,拉大锯老师的B站课程学习顺序是啥,p1-p9完之后再怎么丫!?

2022-04-15 17:24 · Android学习路线
[文章] 基于Go写一个极的通讯demo
说明该demo来源于B站教程视频【8小时转职Golang工程师(如果你想低成本学习Go语言)】https://www.bilibili.com/video/BV1gf4y1r79E/?p=52&share_source=copy_web&vd_source=727d145bfa2bc1ec2bdd67cf624091fc我跟随教程视频写的一个简单的demo,用于巩固基础其中根据自身习惯修改了部分代码源码仓库:https://github.com/hidewnd/imDemo.git其中可能包含一些错误逻辑和,欢迎指正window环境客户端构建:gobuild-oclient.exe.\client.go服务端构建:gobuild-gobuild-oserver.exe.\main.go.\server.go.\User.go定义服务端Server具体实现结构体typeServerstruct{//服务端的IP地址Ipstring//服务端的IP端口Portint//在线用户OnlineUserMapmap[string]*User//在线用户map的同步锁mapLocksync.RWMutex//消息广播channelMessagechanstring}创建Server接口funcNewServer(ipstring,portint)*Server{server:=&Server{Ip:ip,Port:port,OnlineUserMap:make(map[string]*User),Message:make(chanstring),}returnserver}监听用户上线//BroadCast服务端发送广播消息func(s*Server)BroadCast(user*User,msgstring){sendMsg:="["+user.Addr+"]"+user.Name+":"+msgs.Message<-sendMsg}//ListenMessage在线用户监听器func(s*Server)ListenMessage(){for{msg:=<-s.Messages.mapLock.Lock()for_,cli:=ranges.OnlineUserMap{cli.C<-msg}s.mapLock.Unlock()}}服务端对用户消息的处理器//Handlerhandler处理func(s*Server)Handler(connnet.Conn){fmt.Print("链接建立成功")//加入在线用户集user:=NewUser(conn,s)user.Online()fmt.Println("["+user.Addr+"]"+user.Name+":online...")isLive:=make(chanbool)//广播用户发送信息gofunc(){buf:=make([]byte,4096)for{n,err:=conn.Read(buf)ifn==0{user.Offline()fmt.Println("["+user.Addr+"]"+user.Name+":offline...")return}iferr!=nil&&err!=io.EOF{fmt.Println("connReaderr:",err)return}fmt.Println("["+user.Addr+"]"+user.Name+":"+string(buf))//提取用户信息去除'\n'msg:=string(buf[:n-1])user.DoMessage(msg)}}()//超时强制退出监听检测处理for{select{case<-isLive:case<-time.After(time.Second*60):user.DoMessage("Youhavebeenforcedoffline\n")fmt.Println("["+user.Addr+"]"+user.Name+":havebeenforcedoffline")close(user.C)err:=conn.Close()iferr!=nil{return}}}}服务端启动器func(s*Server)Start(){listener,err:=net.Listen("tcp",fmt.Sprintf("%s:%d",s.Ip,s.Port))iferr!=nil{fmt.Println("net.listenererr:",err)return}deferfunc(listenernet.Listener){err:=listener.Close()iferr!=nil{fmt.Println("net.listenererr:",err)}}(listener)//启动在线用户监听gos.ListenMessage()fmt.Println("startsuccess....")for{//acceptconn,err:=listener.Accept()iferr!=nil{fmt.Println("listenerAccepterr:",err)continue}//handlergos.Handler(conn)}}主函数启动packagemainfuncmain(){server:=NewServer("127.0.0.1",8888)server.Start()}完整代码server.gopackagemainimport("fmt""io""net""sync""time")typeServerstruct{IpstringPortint//在线用户OnlineUserMapmap[string]*UsermapLocksync.RWMutex//消息广播channelMessagechanstring}//NewServer创建Server接口funcNewServer(ipstring,portint)*Server{server:=&Server{Ip:ip,Port:port,OnlineUserMap:make(map[string]*User),Message:make(chanstring),}returnserver}func(s*Server)BroadCast(user*User,msgstring){sendMsg:="["+user.Addr+"]"+user.Name+":"+msgs.Message<-sendMsg}func(s*Server)ListenMessage(){for{msg:=<-s.Messages.mapLock.Lock()for_,cli:=ranges.OnlineUserMap{cli.C<-msg}s.mapLock.Unlock()}}//Handlerhandler处理func(s*Server)Handler(connnet.Conn){fmt.Print("链接建立成功")//加入在线用户集user:=NewUser(conn,s)user.Online()fmt.Println("["+user.Addr+"]"+user.Name+":online...")isLive:=make(chanbool)//广播用户发送信息gofunc(){buf:=make([]byte,4096)for{n,err:=conn.Read(buf)ifn==0{user.Offline()fmt.Println("["+user.Addr+"]"+user.Name+":offline...")return}iferr!=nil&&err!=io.EOF{fmt.Println("connReaderr:",err)return}fmt.Println("["+user.Addr+"]"+user.Name+":"+string(buf))//提取用户信息去除'\n'msg:=string(buf[:n-1])user.DoMessage(msg)}}()//超时强制退出监听检测处理for{select{case<-isLive:case<-time.After(time.Second*60):user.DoMessage("Youhavebeenforcedoffline\n")fmt.Println("["+user.Addr+"]"+user.Name+":havebeenforcedoffline")close(user.C)err:=conn.Close()iferr!=nil{return}}}}//Start启动服务器接口func(s*Server)Start(){listener,err:=net.Listen("tcp",fmt.Sprintf("%s:%d",s.Ip,s.Port))iferr!=nil{fmt.Println("net.listenererr:",err)return}deferfunc(listenernet.Listener){err:=listener.Close()iferr!=nil{fmt.Println("net.listenererr:",err)}}(listener)//启动在线用户监听gos.ListenMessage()fmt.Println("startsuccess....")for{//acceptconn,err:=listener.Accept()iferr!=nil{fmt.Println("listenerAccepterr:",err)continue}//handlergos.Handler(conn)}}User具体实现用户结构体typeUserstruct{//用户名Namestring//用户IP地址Addrstring//chanCchanstring//链接connnet.Conn//所属的服务server*Server}创建一个UserfuncNewUser(cnet.Conn,server*Server)*User{userAddr:=c.RemoteAddr().String()user:=&User{Name:userAddr,Addr:userAddr,C:make(chanstring),conn:c,server:server,}gouser.ListenMessage()returnuser}监听用户状态func(u*User)ListenMessage(){for{msg:=<-u.C_,err:=u.conn.Write([]byte(msg+"\n"))iferr!=nil{fmt.Println("writeerr:",err)return}}}//SendMsg给客户端发送消息func(u*User)SendMsg(msgstring){_,err:=u.conn.Write([]byte(msg))iferr!=nil{fmt.Println("sendMsgerr:",err)}}具体实现用户的上下线//Online广播用户上线通知func(u*User)Online(){u.server.mapLock.Lock()u.server.OnlineUserMap[u.Name]=uu.server.mapLock.Unlock()u.server.BroadCast(u,"online...")}//Offline广播用户下线通知func(u*User)Offline(){u.server.mapLock.Lock()delete(u.server.OnlineUserMap,u.Name)u.server.mapLock.Unlock()u.server.BroadCast(u,"offline...")}解析用户的消息func(u*User)DoMessage(messagestring){iflen(message)>0{msg:=strings.Split(message,"|")iflen(msg)>1{switchmsg[0]{case"rename":newName:=msg[1]_,ok:=u.server.OnlineUserMap[newName]ifok{u.SendMsg("thisnameisalreadyused\n")return}u.server.mapLock.Lock()u.server.OnlineUserMap[newName]=udelete(u.server.OnlineUserMap,u.Name)u.server.mapLock.Unlock()u.Name=newNameu.SendMsg("updatenewNamesuccess\n")breakcase"to"://to|用户名|消息iflen(msg)<3{u.server.BroadCast(u,"Commandformaterror\n")return}remoteUer,ok:=u.server.OnlineUserMap[msg[1]]if!ok{u.server.BroadCast(u,msg[1]+"notfound\n")return}remoteUer.SendMsg(msg[2])}}else{switchmessage{case"who":u.server.mapLock.Lock()for_,user:=rangeu.server.OnlineUserMap{onlineMsg:="["+user.Addr+"]"+user.Name+":online\n"u.SendMsg(onlineMsg)}u.server.mapLock.Unlock()breakdefault:u.server.BroadCast(u,message)}}}}完整代码packagemainimport("fmt""net""strings")typeUserstruct{NamestringAddrstringCchanstringconnnet.Connserver*Server}funcNewUser(cnet.Conn,server*Server)*User{userAddr:=c.RemoteAddr().String()user:=&User{Name:userAddr,Addr:userAddr,C:make(chanstring),conn:c,server:server,}gouser.ListenMessage()returnuser}//Online广播用户上线通知func(u*User)Online(){u.server.mapLock.Lock()u.server.OnlineUserMap[u.Name]=uu.server.mapLock.Unlock()u.server.BroadCast(u,"online...")}//Offline广播用户下线通知func(u*User)Offline(){u.server.mapLock.Lock()delete(u.server.OnlineUserMap,u.Name)u.server.mapLock.Unlock()u.server.BroadCast(u,"offline...")}func(u*User)DoMessage(messagestring){iflen(message)>0{msg:=strings.Split(message,"|")iflen(msg)>1{switchmsg[0]{case"rename":newName:=msg[1]_,ok:=u.server.OnlineUserMap[newName]ifok{u.SendMsg("thisnameisalreadyused\n")return}u.server.mapLock.Lock()u.server.OnlineUserMap[newName]=udelete(u.server.OnlineUserMap,u.Name)u.server.mapLock.Unlock()u.Name=newNameu.SendMsg("updatenewNamesuccess\n")breakcase"to"://to|用户名|消息iflen(msg)<3{u.server.BroadCast(u,"Commandformaterror\n")return}remoteUer,ok:=u.server.OnlineUserMap[msg[1]]if!ok{u.server.BroadCast(u,msg[1]+"notfound\n")return}remoteUer.SendMsg(msg[2])}}else{switchmessage{case"who":u.server.mapLock.Lock()for_,user:=rangeu.server.OnlineUserMap{onlineMsg:="["+user.Addr+"]"+user.Name+":online\n"u.SendMsg(onlineMsg)}u.server.mapLock.Unlock()breakdefault:u.server.BroadCast(u,message)}}}}func(u*User)ListenMessage(){for{msg:=<-u.C_,err:=u.conn.Write([]byte(msg+"\n"))iferr!=nil{fmt.Println("writeerr:",err)return}}}//SendMsg给客户端发送消息func(u*User)SendMsg(msgstring){_,err:=u.conn.Write([]byte(msg))iferr!=nil{fmt.Println("sendMsgerr:",err)}}定义客户端初始化客户端客户端结构体typeClientstruct{//服务端ipServerIpstring//服务端端口ServerPortint//客户端名Namestring//客户端管道connnet.Conn//客户端模式flagint}//NewClient创建一个监听funcNewClient(serverIpstring,serverPortint)*Client{client:=&Client{ServerIp:serverIp,ServerPort:serverPort,flag:999,}//建立tcp长链接conn,err:=net.Dial("tcp",fmt.Sprintf("%s:%d",client.ServerIp,client.ServerPort))iferr!=nil{fmt.Println("dialerr:",err)returnnil}client.conn=connreturnclient}通过参数命令来定义并启动客户端funcinit(){//初始化配置,通过-ip设置IP地址flag.StringVar(&serverIp,"i","127.0.0.1","设置服务器的IP地址(默认127.0.0.1)")//初始化配置,通过-p设置IP端口flag.IntVar(&serverPort,"p",8888,"设置服务器的端口(默认8888)")}//DealResponse监听服务端返回的消息func(client*Client)DealResponse(){_,err:=io.Copy(os.Stdout,client.conn)iferr!=nil{return}}//具体业务的实现func(client*Client)Run(){}funcmain(){//命令行解析flag.Parse()client:=NewClient(serverIp,serverPort)ifclient==nil{fmt.Println(">>>链接服务器失败")return}goclient.DealResponse()fmt.Println(">>>链接服务器成功")client.Run()}客户端封装功能封装修改用户名//包装更新用户名请求func(client*Client)updateUserName()bool{fmt.Println(">>>请输入用户名")_,err:=fmt.Scanln(&client.Name)iferr!=nil{returnfalse}sendMsg:="rename|"+client.Name+"\n"_,err=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)returnfalse}returntrue}封装查询在线用户func(client*Client)listUser()bool{sendMsg:="who\n"_,err:=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)returnfalse}returntrue}封装广播聊天//PublicChat公聊模式func(client*Client)publicChat(){varchatMsgstringfmt.Println(">>>请输入发送内容,输入exit退出")_,err:=fmt.Scanln(&chatMsg)iferr!=nil{return}forchatMsg!="exit"{iflen(chatMsg)!=0{sendMsg:=chatMsg+"\n"_,err:=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)break}}//继续监听下一个发送信息,直到exitchatMsg=""fmt.Println(">>>请输入发送内容,输入exit退出")_,err:=fmt.Scanln(&chatMsg)iferr!=nil{return}}}封装私聊//PrivateChat私聊模式func(client*Client)privateChat(){varremote,chatMsgstringclient.listUser()forremote!="exit"{fmt.Println(">>>请输入发送对象,输入exit退出")_,err:=fmt.Scanln(&remote)iferr!=nil{return}forchatMsg!="exit"{iflen(chatMsg)!=0{//发送消息到服务端sendMsg:="to|"+remote+"|"+chatMsg+"\n"_,err:=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)break}}//继续监听下一个发送信息,直到exitchatMsg=""fmt.Println(">>>请输入发送内容,输入exit退出")_,err:=fmt.Scanln(&chatMsg)iferr!=nil{return}}//内循环退出,继续监听输入内容选择用户,知道exitremote=""fmt.Println(">>>请输入发送对象,输入exit退出")_,err=fmt.Scanln(&remote)iferr!=nil{return}}}封装客户端菜单命令//Menu命令菜单func(client*Client)Menu()bool{varcodeintfmt.Println("1:公聊模式")fmt.Println("2:私聊模式")fmt.Println("3:更新用户名")fmt.Println("0:退出")_,err:=fmt.Scanln(&code)iferr!=nil{returnfalse}ifcode>=0&&code<=3{client.flag=codereturntrue}returnfalse}调整业务函数func(client*Client)Run(){forclient.flag!=0{//过滤非法的菜单codefor!client.Menu(){}//根据菜单code进行功能调度switchclient.flag{case1:client.publicChat()breakcase2:client.privateChat()breakcase3:client.updateUserName()break}}}完整代码packagemainimport("flag""fmt""io""net""os")varserverIpstringvarserverPortinttypeClientstruct{ServerIpstringServerPortintNamestringconnnet.Connflagint}//NewClient创建一个监听funcNewClient(serverIpstring,serverPortint)*Client{client:=&Client{ServerIp:serverIp,ServerPort:serverPort,flag:999,}//建立tcp长链接conn,err:=net.Dial("tcp",fmt.Sprintf("%s:%d",client.ServerIp,client.ServerPort))iferr!=nil{fmt.Println("dialerr:",err)returnnil}client.conn=connreturnclient}//Menu命令菜单func(client*Client)Menu()bool{varcodeintfmt.Println("1:公聊模式")fmt.Println("2:私聊模式")fmt.Println("3:更新用户名")fmt.Println("0:退出")_,err:=fmt.Scanln(&code)iferr!=nil{returnfalse}ifcode>=0&&code<=3{client.flag=codereturntrue}returnfalse}//包装更新用户名请求func(client*Client)updateUserName()bool{fmt.Println(">>>请输入用户名")_,err:=fmt.Scanln(&client.Name)iferr!=nil{returnfalse}sendMsg:="rename|"+client.Name+"\n"_,err=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)returnfalse}returntrue}//查询用户信息func(client*Client)listUser()bool{sendMsg:="who\n"_,err:=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)returnfalse}returntrue}//PrivateChat私聊模式func(client*Client)privateChat(){varremote,chatMsgstringclient.listUser()forremote!="exit"{fmt.Println(">>>请输入发送对象,输入exit退出")_,err:=fmt.Scanln(&remote)iferr!=nil{return}forchatMsg!="exit"{iflen(chatMsg)!=0{//发送消息到服务端sendMsg:="to|"+remote+"|"+chatMsg+"\n"_,err:=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)break}}//继续监听下一个发送信息,直到exitchatMsg=""fmt.Println(">>>请输入发送内容,输入exit退出")_,err:=fmt.Scanln(&chatMsg)iferr!=nil{return}}//内循环退出,继续监听输入内容选择用户,知道exitremote=""fmt.Println(">>>请输入发送对象,输入exit退出")_,err=fmt.Scanln(&remote)iferr!=nil{return}}}//PublicChat公聊模式func(client*Client)publicChat(){varchatMsgstringfmt.Println(">>>请输入发送内容,输入exit退出")_,err:=fmt.Scanln(&chatMsg)iferr!=nil{return}forchatMsg!="exit"{iflen(chatMsg)!=0{sendMsg:=chatMsg+"\n"_,err:=client.conn.Write([]byte(sendMsg))iferr!=nil{fmt.Println(">>>connwriteerr:",err)break}}//继续监听下一个发送信息,直到exitchatMsg=""fmt.Println(">>>请输入发送内容,输入exit退出")_,err:=fmt.Scanln(&chatMsg)iferr!=nil{return}}}func(client*Client)Run(){forclient.flag!=0{//过滤非法的菜单codefor!client.Menu(){}//根据菜单code进行功能调度switchclient.flag{case1:client.publicChat()breakcase2:client.privateChat()breakcase3:client.updateUserName()break}}}funcinit(){//初始化配置,通过-ip设置IP地址flag.StringVar(&serverIp,"i","127.0.0.1","设置服务器的IP地址(默认127.0.0.1)")//初始化配置,通过-p设置IP端口flag.IntVar(&serverPort,"p",8888,"设置服务器的端口(默认8888)")}func(client*Client)DealResponse(){_,err:=io.Copy(os.Stdout,client.conn)iferr!=nil{return}}funcmain(){//命令行解析flag.Parse()client:=NewClient(serverIp,serverPort)ifclient==nil{fmt.Println(">>>链接服务器失败")return}goclient.DealResponse()fmt.Println(">>>链接服务器成功")client.Run()}
2023-04-16 19:45 · go / im
[问答] 安卓基础网络编程 :出现IllegalStateException该怎么解决?
安卓基础课程网络编程这一块时经常出现IllegalStateException这个错误,今天Retrofit的Get请求时又出现了,只要点击按钮,程序就会闪退+报错,我百度了许多方法,但还是实在没有办法解决
2020-12-28 15:21 · Bug
[文章] 跟断点大佬装一个flutter
哈哈哈,先模仿到这。。。。最后在安装时,卡在了RunningGradletask‘assembleDebug’…修改gradle,maven{url'https://maven.aliyun.com/repository/google'}maven{url'https://maven.aliyun.com/repository/jcenter'}maven{url'http://maven.aliyun.com/nexus/content/groups/public'}
2020-08-07 09:58 · flutter
[问答] 建议老师搞领券联盟2(MVVM)


领券联盟2

1.服务器端接口不变,没大必要变动编程的是思想。

2021-08-29 09:26 · 安卓学习
[问答] SlideMenuActivity 编辑部分不显示问题
打开这个有显示TextView内容在模拟器上不显示咋回事呀我跟着老师的他有显示出来我的怎么没有
2020-06-10 14:31 · android
[文章] 新手Vue2还是直接Vue3?
Vue3和Vue2在核心架构上有一些显著的不同点,同时也引入了许多新特性以优化开发体验和性能表现。以下是Vue3相较于Vue2的主要区别、优缺点以及更新内容概述:Vue3主要区别与更新内容:CompositionAPI:Vue3引入了CompositionAPI,它提供了一个更加灵活和可复用的编程模型,允许开发者在逻辑相关的功能块内组织代码,而非基于选项对象(OptionAPI)进行分散配置。响应式系统重构:Vue3使用proxy对象替代Vue2中的Object.defineProperty,实现了更高效、更全面的响应式数据追踪。更好的性能:Vue3在编译优化、虚拟DOM实现等方面做了改进,提升了首次渲染和更新的速度,并减少了内存消耗。Tree-Shaking友好:Vue3的代码结构更适合现代打包工具进行Tree-Shaking,从而减小最终bundle的大小。Teleport:新增了<teleport>组件,可以将组件内容渲染到DOM树中的任何指定位置。Suspense:支持异步加载组件时的占位符和延迟渲染。Fragment和Slots:Vue3允许一个组件返回多个根节点(Fragment),并增强了对插槽(Slots)的处理能力。自定义渲染器:Vue3进一步完善了自定义渲染API,不仅限于Web平台,也更容易扩展到Web组件以外的环境,如Weex、NativeScript等。Vue3优点:更高的性能和效率更好的代码组织和复用性更先进的TypeScript支持更容易实现服务端渲染(SSR)优化Vue2优点:相对于Vue3,Vue2生态成熟,资源丰富,社区支持广泛学习曲线相对平缓,文档和教程众多Vue3缺点:升级过程中可能存在兼容性问题,老项目迁移成本较高新手入门时可能会觉得CompositionAPI相比于OptionsAPI更为复杂学习建议:对于初学者而言,由于Vue3是未来的发展趋势且其API设计更加现代化,从长远考虑,直接学习Vue3是一个不错的选择。然而,Vue2的庞大生态系统和成熟的教程体系仍然是新手快速入手的好途径。如果想要先通过实践项目积累经验,可以从Vue2开始学习,之后过渡到Vue3,这样可以同时了解Vue生态系统的变迁过程。当前许多项目仍处于Vue2阶段,因此掌握Vue2同样具有实际意义。但为了跟上技术潮流和为未来的项目做准备,学习Vue3的同时了解Vue2也是有益的。综上所述,新手可以根据个人偏好、项目需求以及未来职业发展来决定是从Vue2开始逐步过渡,还是直接进入Vue3的学习。无论选择哪个版本,理解和掌握Vue的核心思想都是关键所在。
2024-01-26 11:03 · vue / vue.js / vue2 / vue3 / 区别
[问答] 才学recyclerview 想请教一下问题

跟着up主的 怎么才能把这个条目改成我自己设置的名字呢 代码都是跟着up来的2022-11-02 21:51 · Android

[文章] SQL语句for Android Sqlite(视频+笔记+图解)
不管你是iOS还是学习andriod,都有可能用到这個Sqlite数据库,那么,你要知道这個SQL语句嗎?要,要,要!话不多话,具体看视频吧,笔记也不贴出來了,在网盘里直接下载。
2019-10-21 14:02 · sql / mysql / 数据库
[问答] 一个人学的没动力了,怎办?

上班族,想着转岗,纯靠自学,身边也没人做安卓,漫步目的的,越来越没动力了....

2021-12-11 10:18 · 自学 / 安卓 / Android / 孤独
[文章] c语言入门(2)
:::hljs-center:::框架解析上一篇我们讲了最框架#include<stdio.h>---------1intmain()-------------------2{....
2020-01-23 05:04 · c / 编程 / 最简框架
[问答] 图片编解码
想学图片编解码和音视频的知识,是不是要jni呀,大佬们?
2020-04-30 00:40 · android
[问答] 在子线程更新ui为什么没有崩溃?

线程,也搞不懂为什么

2022-02-28 20:48 · 安卓 / 线程
[问答] android 更新太快,各大教程与实际不符怎么办
跟着很多视频学习,但是发现他们创建的界面和我现在用as创建的界面都不太一样,有些部分就会卡住,不下去了。
2021-06-14 12:33 · Android / Google / 更新
[文章] Postman你不知道的小技巧
结束语以上就是全部内容啦,是不是又废一个有用的小技巧呢?这样操作只需要花费不到半分钟的时间就能编写一个网络请求的代码啦~请同学们点赞、评论、打赏+关注啦~
2020-12-17 10:56 · postman / 安卓 / Android / OKHttp / 工具
[问答] 安卓创建sqlite数据库时候报红,初学者不知怎么办???
求助一下这个问题该怎么解决,我是安卓初学者做毕业设计,刚几天,创建数据库运行的时候就弹出来这个错误,创建不了,不知道什么情况
[问答] 小白求巨佬们指点
本人有java语言基础,学过mysql和JDBC现在做项目需要制作一个app要满足获取后台数据功能(就是后台有实时数据需要显示在app内)只有一个月,想要做出一个这样的app想要问一下各位大佬,我现在该些什么能够满足这个
2020-09-13 16:56 · app
[分享] 看懂了责任链模式,你就能明白很多
否则感觉完就很容易就忘掉了,不能理解为什么要使用设计模式(因为没有真实的场景给我去使用)。
2020-02-26 15:15 · 设计模式 / 经验总结 / Java
[问答] 创建了as项目,进来后activity_main.xml就开始报错,也不能出现老师的那种设计页面。
这学习还没咋,环境弄这么久了。因为安环境的时候去网站资料没找到老师下载的版本了,所以真的很苦恼啊。。。
2020-09-17 22:05 · 学习
[问答] httpURLConnection.getResponseCode()为什么返回500?
打印结果源码说500是内部服务器错误,不懂啥意思这是跟这学院里面网络编程的,看视频里也没什么问题,自己做就出问题。请教一下各位
2019-12-25 19:48 · 网络编程
[分享] Rejecting re-init on previously-failed class java.lang.Clas
我能受这委屈吗,我刚的擒拿术!

2022-03-04 11:28 · 安卓 / Android / 疑难杂症 / 解BUG
[问答] 安卓 从后台获取到了多个对象,如何把json转对象
10280","univName":"上海大学","univRank":"5","univScore":"78"},{"id":328,"specCode":"0303","specName":"社会
2020-03-15 23:11 · Android
[文章] 25000字总结Android优秀的第三方框架、各种学习资料(上)
TextViewGithub一个功能强大的TextView,可以满足日常大部分布局方式GithubFacebook开源文本布局库Github一个对齐TextView文本的库Github自适应大小和行的TextView
2020-05-18 19:56 · android
[问答] 怎么有效率地学sql呢

想问问大家平时怎么sql语句的,今天刷sql的题,做的时候知道大概流程但是语句死活干不出来,看了题解才知道正确写法是咋样的,大概能知道方法的意思,要组合起来就懵逼了。。。

2021-08-23 23:11 · 求助
  • 1
  • 2
  • 3
  • 4
  • 5