与服务器的交流,rest的交流方式是事实标准,这种交流方式保证了服务端写好rest接口后,开发的Android、IOS甚至Angular这种OPOA的网页程序都能共用这一套接口。rest的编码规范,网上早已有很多了,不多说。Android的HttpClient程序,只要指定url、参数、Get或Post等请求类型,即可发送请求,当服务器给出Http响应之后,Android程序可以从中拿到返回的json字符串,用JSON等库解析为集合或实体(其实json本质无非是map和list两种集合的混搭),然后遍历和取值,自动或手动构造成实体对象,然后改变页面的显示。在要页面显示时,由于Http返回的处理函数运行于另一个线程,直接调用页面的成员变量以试图修改其显示内容会报错。为此需要提早注册一个Handler,用于在接收到消息时读取页面的「数据属性」并改变页面显示,Http返回处理函数将数据更新到页面的「数据属性」中,向Handler发送一个消息,让Handler读取「数据属性」并更新页面即可。
在页面显示数据时,最常用到是ListView,可以定义一个Adapter,实现根据下标返回Item页面元素的方法,方法是声明一个Item布局文件,Adapter持有数据集合,在要实现的方法中使用传入的下标获得单个实体,再使用Item布局文件实例化一个页面元素对象,用实体的属性渲染页面元素对象,将页面元素对象返回即可,推荐使用ViewHolder来提高性能,这在包括《打造高质量Android应用》等书都讲了。
4.实践经验有了上面1至3的知识,理论上即可完成App的开发,善于将各种编程技能元素组合使用即可(界面知识 + 数据知识 = 一切),但还有些具体工作了才会获得的经验。
在Android Studio中引入第三方库是使用Gradle,类似maven,写配置文件即可。
App上架方面360、百度、腾讯、豌豆荚、小米都成功上线了,华为和PP助手不允许非公司用户上线,没办法。
尝试手动实现定时轮询来获得服务器上的提醒,不成功,但对Service和BroadcastReceiver的理解更深了,Service的主要用途就是保证它打开的线程一直活着,但怎么保证这Service不死?一是设成常驻在通知栏的前台Service,二是在安卓手机「设置」里将该App设为「锁屏后继续运行」,还要将网络设为「锁屏后不断网」,以保证锁屏后线程能继续轮询并从网络上得到最新信息。而BroadcastReceiver的主要作用是,让两个相互之间解耦合得很好的组件可以互相通讯,只需要发起通讯那方指定一个字符串——既不需要访问对象,也不需要指定class类对象,指定一个字符串即可,这时通讯发起方根本不知道会不会有人响应它、会有几个人响应它,零个、一个、多个响应者都有可能,这就是「广播」的意义,可以联系「消息队列」来理解它,主要的目的是解耦。
虽然如此还是常有用户反馈收不到消息推送,只好使用专业的推送服务,目前使用的是「友盟」,文档很好,还提供了编程式发消息的sdk,测试也很友好,调了两天,用户基本能顺利收到推送了,当然还是要在手机设置中将App加入「锁屏后继续运行」的白名单,否则友盟的PushService被杀掉就收不到推送了。另外第三方的「统计」还在摸索。
程序更新提示的实现是在启动时向服务器发一个请求了解最新版本号,与本地程序版本号比对后,如果有更新的,则询问是否要更新。apk包是在Android Studio里签名打包之后,用360加固了之后(否则各平台不允上线),传到了「七牛云存储」的服务器上,在App获取最新版本号时,将最新的apk包的地址一并获取下来,如果用户同意更新,则在后台启动线程下载该apk包,下载完成后自动安装。
App的登录,是将用户名密码提交到服务器,服务器检查正确后返回一个token,App将这token保存在本地,以后请求api时附带用户名和token一起发给服务器,服务器检查用户名和token正确,则将关键的数据返回给App,否则视具体需求返回不完整的数据(未注册用户看到的数据不完整),或者直接返回错误(未注册用户完全不允许访问的数据)。注册时,则是生成一个验证码,将手机号和验证码存到库里,调用发短信的服务商的接口发到用户手机,当用户输入验证码发送请求到服务器,服务器检查手机号和验证码是否匹配,如果匹配,则注册成功。
Android页面中嵌入Html页面很简单,但这两者产生交互的功能还没做过,如果以后做到,再补充进来,这里留个TODO的「抽象方法」占位置。还有图像的延迟加载、数据库的使用,都要留个「TODO」。有时间即实践之。
5.个人感想