使用Netty进行Android与Server端通信实现文字发送接收与图片上传 – 原创

ANOTHER TITLE:

Let’s use netty to achieve text send and receive and  image transfer to server based on android and jdk1.7

就让我来Rap<MC Hotdog>,使用netty进行安卓端发送接收文字,并且附带发送图片功能,折腾了几天的netty总算有点眉目了,做下记录。

需求是安卓端拍照上传到服务器,服务器返回上传成功或失败bla bla bla,需求比较简单。最初使用的传统的post加multipart/form-data,一般的手机照片大小1-2M,测试没问题,但实际情况是有的用户使用3G网络,有的4G,有的WIFI还有的使用2G,网络环境稍微有点差的上传图片时间持续到十多分钟(我都不好意思说了),然后想到了使用socket,然后google到了netty,有的大神说这样的需求没必要上netty啊,其实我就是想通过这个需求学习下关于socket,关于netty,关于channel,关于byte[],关于NIO,多学习点总是没坏处的,后面我也可以牛逼点说玩过高性能基于事件的异步网络框架了。

刚开始直接啃的netty.io的document,照葫芦画瓢抄完了TimeServer之后就满世界的google其他的netty知识,比较零散,然后入手了《Netty权威指南第二版》,啃了几章之后怎么也是TimeServer,不过对NIO一些基本组件有了一个初步的认识。

OK,入正题,我要实现一个Demo,就说是个Netty的聊天室吧(群聊,没有单聊的功能,demo味儿十足),不过客户端换成了安卓,一个服务器对多个客户端,所有数据经过服务器端,要定义中间信息交换组件。关于Google的Protobuf还有MessagePack和JBoss Marshalling这些编解码中间件都没有玩过,似乎有点看不懂,我的需求很简单,如下图(抱歉键盘党多年手已废掉,可能只有我自己看得懂):

Echo-Server、Echo-Pojo、Lets's Chat Relationship

一共包含三个对象:

Echo-Pojo,信息交换中间对象,用于Android端与Server端封装byte[]之后的序列化对象。

Let’s Chat,安卓客户端,构建EchoMessage或EchoFile对象,然后发送到channel;EchoMessage与EchoFile用于服务端判断信息对象的类别。

Echo-Server,服务端。ChannelRead时判断信息对象类型,决定是广播到所有用户还是保存文件。

对于ByteBuf对象一直没有弄很明白,所以上述也就没有使用。

来张安卓端(小米PAD)Let’s Chat的运行截图:

Let's Chat小米Pad运行截图
Let’s Chat小米Pad运行截图

三星手机Let’s Chat运行截图:

Let's Chat三星手机运行截图
Let’s Chat三星手机运行截图

服务端(Echo-Server)的运行截图:

Echo-Server输出日志与说明截图
Echo-Server输出日志与说明截图

上传的文件:

QQ截图20160518132859

文件名格式为:Build.MANUFACTURE+UUID.randomUUID()+”.jpg”,第二张图片为12.9M,上传时间六七秒钟,应该还有优化的空间。

Echo-Pojo的代码就不截图了,直接下载查看就可以,或者也可以继续扩展,目前只是图片跟文字。

上述功能一共分为三个程序,Echo-Pojo信息交换对象使用eclipse-Mars2开发,Echo-Server使用Intellij idea开发,Let’s Chat使用Android Studio2,有点蛋疼,但好在实现了功能,中间折腾的很多,尤其公司电脑跟家里电脑jdk不一致,一个1.8,一个1.7,因为这个出了很多莫名的错误,也浪费了很多时间,中间的各种折腾各种烦躁就不记录了。

代码注释比较少,也有很多废弃的没有删掉,只是实现了功能可以运行,没有做完全整理,有问题可以直接回复或者@EMAIL ME

借鉴刘源的NettyFileTransfer,只是我把客户端修改成了Android,然后Netty版本我用的是4.0.36Final,感谢大神。

剩下的就是把功能揉进项目里了,Keep Fighting !

项目开源地址:https://github.com/LisonLiou/netty-learning.git

Android控件之带清空按钮(功能)的AutoCompleteTextView自动提示

功能折腾完了记录一下。带删除按钮的AutoCompleteTextView,普通的自动提示控件用起来比较简单,准备好数组给控件setAdapter一下行了,这里要说的是提取sqlite中的数据绑定并且加上清空按钮,先来张图片。

带删除按钮的AutoCompleteTextView

最初没有用过AutoCompleteTextView的时候,就直接百度了下,想必都会得到这样一段代码:

上面的代码简单,但是不大实用,比如我的需求就是,要有清空按钮。然后继续百度,又找到了这篇文章(继承AutoCompleteTextView自定义控件ClearableAutoCompleteTextView,自定义adapter方式实现)

然后就闭着眼抄了一下,修改一点,满足了需求。其实碰上问题就百度这种方式是很不对的,所有的控件使用方法在Android Develop Docs中都有介绍:/sdk/docs/reference/android/widget/AutoCompleteTextView.html。哎,我们都是应用程序猿,但我们又连API都不看。。。或许你觉得密密麻麻的英文看着头疼?或许你又翻不了墙?或许吧,还是那句老话,成功的人找方法,而失败的人嘛,对吧。

今天想给AutoCompleteTextView加个图标,就是上图左侧那个放大镜按钮,于是找好素材,设置drawableLeft,运行,发现没有效果。于是查看自定义控件的源码(就是上面使用自定义adapter的那个链接里提到的),发现是在init方法中绑定了setOnTouchListener, 然后onTouchListener中又通过MotionEvent判断触摸的区域,而触摸的对象使用的是setCompoundDrawablesWithIntrinsicBounds,这不就是drawableLeft、drawableRight所对应的方法嘛,果断删除自定义控件ClearableAutoCompleteTextView,使用原生AutoCompleteTextView,加入drawableLeft放大镜按钮,drawableRight使用删除小图标,然后对控件setOnTouchListener,代码如下:

一下子就腰不疼腿不酸了。注意“触摸点位置判断”那行,意思是当前触摸点如果大于AutoCompleteTextView的宽度减去paddingRight的值再剪掉一个固定值(R.dimen.space_4_touch,我这里是10dip),就算触摸到了删除小图标;固定值是多少根据情况来,值越大可以触摸的空间越大,相反越小,用户可能就点击不到那块区域(删除小图标的区域)从而激发不了事件,这也算是优化用户体验的一种手段吧。

所以,按照上述代码,也可以举一反三为放大镜按钮加上事件,或者为删除小图标设置隐藏/显示条件,比如文本框没有内容时删除图标隐藏,有内容则显示等。

Continue reading

记@Android Studio使用初体验杂记

最初时候用eclipse JUNO,谷歌给出的adt-bundle包下载下来什么都有了,sdk manager、plateform-tools、adb等等,只需要自己翻墙下载相应的sdk就可以helloworld了,当时的Android Studio 1.x版本那个难用啊。。。

但是google已经宣布不在支持eclipse了,虽我等已经习惯了eclipse,但是谷歌大法说用新的,用旧的出问题不负责,至少android开发领域,eclipse的用户与资料不会在上升了,于是这两天捣鼓了下Android Studio,杂记下。

1.Android Studio基于IntelliJ IDE,我也没怎么用过,不过响应速度确实是快。

2.Android Studio可以使用ADT-Bundle包中的sdk目录,若之前已经下载了个版本的SDK,则可以直接指向此目录,无需二次下载,无需费时费力费硬盘。

3.之前整理代码的快捷键是Ctrl+Shift+F,现已加入肯德基豪华午餐:Ctrl+Alt+L,此热键与QQ锁界面的热键冲突,怎么办自己看着办。

4.关于Android Studio的默认界面(真是丑的一比)。修改IDE的字体及字号:File>Settings 左上角搜索框输入appearance,找到Appearance & Behavior > Appearance,右边勾选Override default fonts by(not recommended),然后Name跟Size就自己看着选了。

5.关于编辑器的字体(主题)设置,我使用的是Darcula。File>Settings>Editor>Colors & Fonts,点击Save As按钮,将当前主题另存一份,确定之后,在点击左侧树菜单Colors & Fonts下的Font,然后选择字体跟字号,OK。

6.Android Studio的布局实时预览,赞一个。

7.Android Studio的Develper Services赞一个,好像可以一键增加AD,Analytics还有推送那些东西?暂时还没研究。

8.对于Gradle的概念还是没有弄的很明白,跟make有什么区别?Groovy更是不懂了。

9.那么Maven到底是怎么回事,统一各版本jar包集合平台?不冲突依赖解决方案吗。。。

10.集成的ADT Manager好像比JUNO那个启动快很多。

11.Android Studio启动时会很卡,其他有些操作有时候也会很卡,多注意看看控制台输出,IDE加入了Gradle自动构建,很多时候都在帮你clean或者rebuild或者render项目文件,所以会卡,但是自动提示功能我觉得比宇宙最强IDE Visual Studio还要强了。

12.如何删除项目?新建了个hello world删不掉了吧。File>Project Structure,在下面的Modules中选中要删除的项目,点击上面的”减号“按钮。

暂时就这些,hello world去了Android Studio主界面截图

startActivityForResult获取不到返回值 – Android

使用startActivityForResult与setResult通常解决的场景是:

A Activity打开B Activity,B执行完业务后返回结果给A。

 

 

结果发现无论如何也不能输出结果,查找网络后发现Activity在Manifest注册时lauchMode不能使用singleInstance模式;将A与B的singleInstance去掉之后,正常获取值。