月度归档: 2021 年 3 月

关于iOS订阅型内购开发

####由于公司项目里面有一个类似购买一个时期的产品,原本使用消耗式内购来做,但是被苹果审核拒*了,苹果建议(要求)使用订阅式内购来做这个,于是就来研究一下

#####1.*步添加内购产品

首先还是添加内购产品,但是这次添加的就不是消耗型项目了,而是添加订阅型项目,添加的订阅型项目是可以分为不同的组,比如组A里面包含订阅一周的产品(10元),包含订阅一月的产品(20元);组B里面包含订阅一周的产品(15元),包含订阅一月的产品(30元);不同组的产品是相互直接没有影响的,可以同时存在多个(比如我购买了A组的产品1,B组的产品1);但是相同组的产品是只能同时存在一个;

%title插图%num
点击创建之后会出现下图

%title插图%num

点击下一步之后会出现是否创建分组,我图片中已经显示创建处理订阅组A,订阅组A,这里就不在截图显示了

#####2.第2步添加沙盒测试帐号

点击+添加沙盒测试帐号,沙盒帐号的作用就是你在iPhone 手机上登录这个测试帐号来测试你的内购项目可以不用真正花钱

%title插图%num

#####3.第3步添加共享密钥

%title插图%num
#####4.第4步编写代码

我是直接使用git上的一个三方库YQInAppPurchaseTool,只是在其基础上稍作改动,只是修改了一下方法

 

#pragma mark 验证购买凭据
/**
* 验证购买凭据
*
* @param ProductID 商品ID
*/
– (void)verifyPruchaseWithID:(NSString *)ProductID
{
// 验证凭据,获取到苹果返回的交易凭据
// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 从沙盒中获取到购买凭据
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
// 发送网络POST请求,对购买凭据进行验证
//In the test environment, use https://sandbox.itunes.apple.com/verifyReceipt
//In the real environment, use https://buy.itunes.apple.com/verifyReceipt
// Create a POST request with the receipt data.
NSURL *url = [NSURL URLWithString:checkURL];

NSLog(@”checkURL:%@”,checkURL);

// 国内访问苹果服务器比较慢,timeoutInterval需要长一点
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0f];

request.HTTPMethod = @”POST”;

// 在网络中传输数据,大多情况下是传输的字符串而不是二进制数据
// 传输的是BASE64编码的字符串
/**
BASE64 常用的编码方案,通常用于数据传输,以及加密算法的基础算法,传输过程中能够保证数据传输的稳定性
BASE64是可以编码和解码的
*/
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSString *payload = [NSString stringWithFormat:@”{\”receipt-data\” : \”%@\”, \”exclude-old-transactions\” : \”true\”, \”password\” : \”1f0aae19eb7f344a818216af37d3c3f456\”}”, encodeStr];
NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];

request.HTTPBody = payloadData;

// 提交验证请求,并获得官方的验证JSON结果
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

// 官方验证结果为空
if (result == nil) {
//NSLog(@”验证失败”);
//验证失败,通知代理
[self.delegate IAPToolCheckFailedWithProductID:ProductID
andInfo:result];
return;
}

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result
options:NSJSONReadingAllowFragments error:nil];

//NSLog(@”RecivedVerifyPruchaseDict:%@”, dict);

if (dict != nil) {
// 验证成功,通知代理
// bundle_id&application_version&product_id&transaction_id
[self.delegate IAPToolBoughtProductSuccessedWithProductID:ProductID
andInfo:dict];
}else{
//验证失败,通知代理
[self.delegate IAPToolCheckFailedWithProductID:ProductID
andInfo:result];
}
}

上面代码里面的变量payload里面的password就是第三步生成的共享密钥

#####5.第5步就是数据传送给后台了

在把收据传给苹果验证,验证结束后苹果会把当前项目的开始时间,到期时间都返回给你,当然你可以可以直接把验证放在后台
验证返回的字段大致有一下:
latest_receipt *新凭证
latest_receipt_info *新凭证详情(可能会有多个,因为是不同组的产品,产品id是不同的)
expires_date 到期时间
expires_date_ms 到期时间毫秒
expires_date_pst 到期时间(太平洋的时间)
is_in_intro_offer_period 是否是在试用期
original_purchase_date *初的购买时间
original_purchase_date_ms *初的购买时间毫秒
original_purchase_date_pst *初的购买时间(太平洋的时间)
product_id 产品id
purchase_date *新的购买时间
purchase_date_ms *新的购买时间毫秒
purchase_date_pst *新的购买时间(太平洋的时间)

%title插图%num

以上就是这次订阅内购的实践,过程里面还会遇到很多坑,比如消耗型内购起名字和简介不能出现货币的名称(比如人民币),AppStore 审核的时候链接改为正式链接,其实苹果审核的时候也是需要测试链接,只有当上线了才能使用正式链接,这个地方后台注意一下,如果是指定的错误码是21007(此收据来自测试环境,但已发送到生产环境进行验证。而是将其发送到测试环境。)或者是21008 (此收据来自生产环境,但已发送到测试环境进行验证。而是将其发送到生产环境。)后台更换一下验证路径;漏单处理等其它的内购问题就不在一一说了;

Python类、模块、包的概念及区别

Python类、模块、包的概念及区别


类的概念在许多语言中出现,是面向对象编程的基础,很容易理解。抽象出不同物体的共同特征,根据相似性原则,把彼此相似的物体归于相同的类概念, 它将数据和操作进行封装,以便将来的复用。

模块
模块,在Python中一个文件就可以认为是一个模块。在创建了一个脚本文件后,定义了某些函数和变量。你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量。模块名就是文件名去掉.py后缀。

模块也可以简单的划分为built-in模块和自定义模块

built-in 模块就是Python内置的一些模块,比如:sys, os等基本模块

 

内建函数dir()可以查看模块定义了什么数据(包括变量名,模块名,函数名等):dir(模块名),没有参数时返回所有当前定义的名字

模块搜索路径

当导入一个模块时,解释器先在当前包中查找模块,若找不到,然后在内置的built-in模块中查找,找不到则按sys.path给定的路径找对应的模块文件(模块名.py)


包是一个有层次的文件目录结构,它定义了由n个模块或n个子包组成的python应用程序执行环境。

通俗一点:包是一个包含__init__.py 文件的目录,该目录下一定得有这个__init__.py文件和其它模块或子包。

包可以使用import导入包,或者from + import来导入包中的部分模块。包目录下为首的一个文件便是 init.py。

子包: 假如子目录中也有 init.py 那么它就是这个包的子包了。

 

使用Appium进行iOS的真机自动化测试

使用Appium进行iOS的真机自动化测试
##安装类库

Homebrew
如果没有安装过Homebrew,先安装 [ homebrew ]

npm
如果没有安装npm,请移步 [ node.js和npm安装 ]
######安装依赖库
brew install libimobiledevice –HEAD sudo npm install -g ios-deploy –unsafe-perm=true

如果执行sudo npm install -g ios-deploy –unsafe-perm=true报错,执行sudo xcode-select –switch/Applications/Xcode.app/Contents/Developer/

######如果没有安装 libimobiledevice,会导致Appium无法连接到iOS的设备,所以必须要安装,如果要在iOS10+的系统上使用appium,则需要安装ios-deploy
######appium-doctor 安装

npm install appium-doctor -g
######安装后执行appium-doctor –ios指令,可以查看与iOS相关配置是否完整,下图是全部配置都成功,如果出现有一项不正确在执行一次就可以,或者直接跳过
appium-doctor –ios

%title插图%num

######更新Appium中的WebDriverAgent

到WebDriverAgent下载*新版本的WebDriverAgent
cd 进入下载后的WebDriverAgent文件
执行 ./Scripts/bootstrap.sh
直接用Xcode打开WebDriverAgent.xcodepro文件
配置WebDriverAgentLib和WebDriverAgentRunner的证书

%title插图%num

连接并选择自己的iOS设备,然后按Cmd+U,或是点击Product->Test
运行成功时,在Xcode控制台应该可以打印出一个Ip地址和端口号

%title插图%num
在网址上输入http://192.168.2.101:8100/status,如果网页显示了一些json格式的数据,说明运行成功。

%title插图%num

**进入到Appium中的WebDriverAgent目录,目录路径如下/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/ **
将自己下载并编译后的WebDriverAgent替换Appium原有的WebDriverAgent
#####在Appium-Desktop下载传送门中下载*新版本的Appium-Desktop

运行Appium-Desktop

%title插图%num

开启start server

%title插图%num

点击start new session并且在Desired Capabilities 中输入相关的参数后点击Start Session

%title插图%num

运行成功后,会弹出一个控制界面,在该界面中可以控制手机上正在运行的程序

%title插图%num

######利用Appium-Python-Client进行iOS的自动化测试

安装python
brew install python

下载python-client
git clone https://github.com/appium/python-client.git
cd python-client
python setup.py install

在git上下载测试文件appiumSimpleDemo

######开始自动化测试

打开下载后的appiumSimpleDemo文件,打开appiumSimpleDemo.xcodepro程序,配置下TARGET的签名

在appiumSimpleDemo的根目录执行编译指令,编译出一个app文件xcodebuild -sdk iphoneos -target appiumSimpleDemo -configuration Release,编译成功后app文件的地址会打印在命令行中

%title插图%num
配置python文件

打开appiumSimpleDemo中的appiumSimpleDemo.py文件,将,修改setup中的几个参数,将app的路径,设备的相关信息修改成当前连接设备的信息。

######如果执行appiumSimpleDemo.py报错File”/usr/local/Cellar/python@2/2.7.15/Frameworks/Python.framework/Versions请升级python版本,如果你是iOS开发人员,请谨慎,升级python有可能是Xcode无法打包参考文稿

%title插图%num

Python学习路线

零基础Python学习路线,小白的进阶之路!大佬带你起飞

近几年Python的受欢迎程度可谓是扶摇直上,当然了学习的人也是愈来愈多。一些学习Python的小白在学习初期,总希望能够得到一份Python学习路线图,小编经过多方汇总为大家汇总了一份Python学习路线图。

对于一个零基础的想学习python的朋友来说,学习方法很重要, 学习方法不对努力白费 一定要有一个正确的学习线路与方法

零基础Python学习路线,小白的进阶之路!

必学知识:【Linux基础】【Python基础语法】【Python字符串】【文件操作】【异常处理】【Python面向对象】【项目实战】

路线讲解:该路线循序渐进,科学合理,帮助学习者建立正确的编程思想,具备基本的编程能力;

必学知识:【Python平台迁移Linux】【Python常用第三方库】【Python高级语法】【Python正则表达式】【网路编程】【系统编程】【数据结构与算法】【项目实战】

路线讲解:该路线强调数据结构和算法的学习,着重提升学习者的编程核心能力;使学习者能够熟练掌握Python高级用法及网络相关知识,能够独立承担Python网络相关的开发;

必学知识:【HTML】【CSS】【JavaScript】【DOM】【事件】【jQuery】【混合开发】【项目实战】

路线讲解:使学习者掌握web前端开发的相关知识,在工作中搭建高质量网站;

必学知识:【Linux网站配置】【git项目管理】【Python框架Django】【flask框架】【接口开发】【数据库MySQL、MongoDB、Redis开发】

路线讲解:熟练掌握框架的使用,掌握数据库原理及相关优化;

必学知识:【爬虫开发原理】【requests+beautifulsoup4静态网页解析】【selenium动态网页解析】【scrapy框架】【分布式爬虫系统】【项目实战】

路线讲解:使学习者能够掌握爬虫的工作原理,独立承担爬虫的相关工作,亦能够独立设计及实现分布式爬虫框架;

必学知识:【数据分析】【数据可视化】【机器学习理论与实践】【TensorFlow图像实战】【项目实战Python人工智能项目】

路线讲解:理论与实践并重,加强理论的讲解,理解机器的学习原理,更加系统完善的了解整个Python学习流程。

以上就是整套Python学习路线图,这套学习路线图从学习者实际出发经过长时间的研究孕育而成,可以说适合每一位Python学习者。

python前景介绍

python前景介绍

2019年刚到来,作为一个学Python,使用Python的学生来说,这无疑是一个令人振奋的消息——Python编程语言获得了“年度编程语言”的称号! Python之所以获得这一称号,是因为与所有其他语言相比,它在2018年获得了*多的排名。Python语言获得了3.62%的优势,其次是VisualBasic.NET和Java。Python现在肯定已经成为大型编程语言的一部分。近20年来,C、C+和Java一直排在前3名,遥遥*于其他方面。Python现在加入了这3种语言。它是当今大学教学*频繁的*语言,在统计领域排名*,在人工智能编程中排名*,在脚本编写方面排名*,在编写系统测试方面排名*。除此之外,Python在网络编程和科学计算方面也处于*地位。 曾经,Python被称为网红语言。大数据时代的到来,Python进入了人们的视线;人工智能的兴起,Python再次受人关注。语法简单,代码优美,Python开始被广泛的学习。Python凭借着社区强大的第三方库,已经被广泛的应用到各个领域中去,Python是脚本语言,Python是人工智能首选语言,Python是全栈式开发语言。总之,Python无处不在。

以智能原生为基础建设再造生产力

从科技抗疫到新基建,我们看到一场以智能化为趋势的数字化转型革命已经到来。

不同规模、不同业务模式的百行百业,既要面对技术更迭带来的冲击和影响,更要乘风破浪,从中寻找转型升级的机会。

智能化变革以智能原生为原点,以高效的基础建设,助力上层业务决策结果更精准、流程更高效,成为不可低估的新兴生产力。

从数字化到智能化 产业变革正在发生

过去半个多世纪,数字经济的迅速发展解决了社会经济中“看不见”的问题,数据代表着人类对世界认识的广度。

但是人类还远远没有“看透”世界,新一轮以5G、IoT、区块链、数字孪生等为代表的前沿技术,正逐步揭开数据蕴藏的巨大能量。

不过,当庞大的数据成为人类社会的核心资源,蕴含巨大价值的同时,也给数字基础设施带来了前所未有的挑战。

据IDC《数据时代2025》报告预测,随着5G、物联网技术的发展,数据正在呈海量式爆发,2025年将达到175ZB的惊人规模。

面对如此庞大的数据量,人们对智能化的需求正在日益增长。

我们认为,ICT基础设施在人工智能产业中地位将愈加重要,未来更加可靠的网络、更快速的存储以及更高效的计算设备,AI芯片,类脑芯片及边缘计算设备的需求量都将激增。

认知智能时代到来,智能技术将持续得到提升,应用场景将更为丰富;此外人工智能与5G、IoT、VR/AR技术相结合,将赋予更大的想象空间。

与此同时,随着“新基建”的火热开展,为ICT基础设施更具智能创造了巨大的发展契机。

我们认为,实现智能需要以数据、算力、算法三大要素为支撑。

在ICT基础设施上实现算力按需调度、数据顺畅流淌、算法敏捷高效,并通过智能基础设施、智能云平台、智能安全、智能运维、智能数据平台、智能算法六大核心技术能力,支撑智能应用部署,进一步推动智能化与百行百业业务场景的深度融合。

“智能原生”将成为智能时代的新生命力

我们先回顾一下云原生的发展。

云起步于2006年,当时百行百业普遍处于烟囱式、单点式的IT架构建设处境。

随着云的兴起,百行百业在架构设计之初即向云而生(即云原生),其本质上是在追求简洁、高效和扁平。

如今,我们看到了随着智能化技术的成熟,智能原生将为用户的技术架构带来新的生命力。

预计到2025年,智能将成为基础架构与生俱来的能力。

而当基础架天然具备了AI计算和AI分析的服务能力,也就不需要再考虑传统架构是不是具备对AI的兼容,它将成为基础建设高效、敏捷的生产力,也将把人们从繁琐复杂的工作中解脱出来,让人们有更多精力思考业务、人文层面的事情。相信到那时候,就没有人会再谈论传统架构了。

AI in ALL 使能智能未来

作为数字化解决方案领导者,紫光旗下新华三集团正在通过“AI in ALL”智能战略作为实现“智能原生”的起点。

从赋予基础架构智能,到产品和解决方案全面嵌入智能,再到助力客户的业务与运营更具智能,进而迎接“智能原生”的到来。

在智能战略之下,*具行动力的数字大脑计划从2019年首次发布以来,以智能化为核心帮助近2000个客户构建了数字大脑,加速他们的数字化转型。

2020年,“数字大脑计划”再次进行了升级,我们希望能够统一云计算和智能服务能力,让百行百业用户拥抱几乎无处不云,无处不智能的新时代。

具体而言,新华三除了继续将智能技术全面应用于数字基础设施、主动安全及统一运维中,还将业务能力平台全面升级为云与智能平台。

具体升级包括在网络方面,新华三已经具备网络精细数据的处理能力,并且可以做到“自诊断网络”和“自隔离网络”,让网络实现自动化、自优化和自主化。

在计算方面,面向AI计算而生的GPU服务器推出了各种衍生款型,为用户提供强大的智能算力。

%title插图%num

在存储方面,新华三的存储设备结合InfoSight 智能云管理产品,将已知的各种问题同步到未出现问题的设备以预防风险发生,同时对未来风险进行预判。

在云与智能平台上,针对计算虚拟化、存储虚机化和网络切片等资源的调度上引入AI的算法,全面具备对于基础设施的智能管理能力……

2020年,我们要将智能推向所有的产品、解决方案以及应用中。

从智能战略到数字大脑计划,从智能数字平台到智慧应用生态,新华三集团将融合5G、边缘计算、人工智能等前沿技术,实践落地更多智能化应用。

仰望星空,脚踏实地,面对即将来临的智能时代,新华三集团将秉承数字化解决方案领导者的使命,不断使能客户智能化,驱动未来数字世界的智能原生建设与发展。

Android APP架构

什么是架构

在我看来,软件架构*对不只是框架的堆砌,看我看来,架构是为了方便软件维护、扩展、安全性、切入性(我也不知道有没有人提出过这个关键字,因为的确很少看见,简单来说我这里说的切入性就是指一个以前没有接触过这个项目的人,能快速加入到这个项目中,对项目进行维护、修改和扩展)

维护性

一个好的软件(不一定是成功的软件,这里说的好只是程序员认为的代码方面)肯定是能方便维护的,出了问题能快速定位,需要修改时能快速修改,并且在一定程度上不会说一修改就一堆bug,这就是我认为的可维护性,当然后面要说到的切入性其实也算是维护性,不过为什么单独放出来在切入性时我会详细说明。至于怎么样才能使一个软件维护方便,我觉得有以下几点:

1.代码规范

一份代码如果没有遵循任何规范,那么我相信它的可维护性是很差的,就算是你一个人做出来的,估计过了几个月去修改的时候也会冒出一句这TM是什么鬼

2.框架稳定性

很多时候很多开源框架刚出来的时候,也许功能十分强大,但是毕竟刚出来,没有经过充分的测试,所以还是会或多或少存在一个不稳定因子,所以建议在选择框架时尽量选择成熟稳定的框架,哪怕功能和性能的确比不上刚出来的框架。当然这也不是说完全不用刚出来的框架,毕竟都不用,那么它也永远成熟不了,至于到底用不用和怎么用,本文的框架选择和使用篇也会详细分析说明

3.封装

本来想说AOP的,但是个人觉得很多专业性的名词也比不上一些通俗的形容,毕竟本文主要的目的是让人理解,不是提出理论。封装这个在Android中是经常使用的,简单来说就是把一些常用的、通用的东西进行一个封装,通过统一入口进行调用,这样出问题就只需要修改一个地方,就能全部修改过来。同时封装也要注意一些常见的坑,比如我曾经就踩过的context坑,当时封装了一个UIUtils(主要是针对UI相关的工具类),因为很多方法都要使用context,所以直接application传进去,保存了,所有方法都不用传context,但是这样却出了一个bug,那就是有些操作用application的context是有问题的。当然这种还比较好处理,但是如果因为封装导致内存泄露,这就难以查找了,比如你传入了一个activity的context,但是activity已经关闭了,但是因为你封装的方法里面还在继续使用这个context,所以activity的内存也是不会释放的,所以封装的时候也一定要注意,不要给自己挖坑

4.耦合

针对耦合这个东西相信很多文章都说过了,如何解耦合,不过个人感觉解耦合这个东西也要适度,不要因为解决一点耦合,花了大量的代码,浪费了大量的性能,所以解耦合这个东西就一定要把握这个度,过度设计是有问题的设计,这点我是赞同的。同时很多时候封装会导致一些耦合的问题,比如我曾经一个项目中就有个这个一个情况:

因为项目中使用了滑动选取身高的WheelView,因为当时是弹Dialog出来选择的,所以当时想也没想就直接封装了一个Dialog,后面又出来了一个选取年龄的,然后又封装了一个Dialog,以至于到后面封装的Dialog有7,8个了,但是有些界面因为选中后的处理有些不一样,导致Dialog里面的代码混乱,所以后面就直接简单的封装了一个Dialog,传入需要选中的数据集合和选中监听,这样就用了一个Dialog就能处理多种数据的选择,还能根据不同界面分别处理,当然这样也不是万金油,毕竟这样每个界面都需要自己实现监听,所以很多时候有利就有弊,至于具体怎么取舍,就看利是否大于弊

扩展性

扩展性简单来说就是当程序需要新的功能时,能否对其进行扩展以及扩展的难度来判断,如何提高扩展性,我觉得有以下几点:

1.抽象接口

这点相信大家都经常遇到,比如Android的点击事件,你想要实现什么样的点击效果,自己实现一个点击监听,然后设置给控件就可以了

2.元素重用

很多时候,很多功能模块可能使用到相同或者类似的元素,如何Android中的一些布局,这些如果抽取出公共部分在进行扩展的时候方便对其快速扩展,当然这个是项目一开始并不能预见的,所以需要在开发中不断的去重构

3.单一职责

这个跟其实就是面向对象的单一职责,比如前面提到的Dialog,一开始只有选择身高的功能,看起来是单一职责,但是其实相关处理也包含在其中,所以那个Dialog类本身职责已经不单纯,当然如果一直只有这一个,这样做没有任何问题,也能看做单一职责,但是如果有多个选择和处理的时候,就必须对其重构了

4.替换性

替换性包含里氏代换但是也不仅仅是里氏代换,比如常见的Android布局不同,但是其显示内容大致相同,这样写布局的时候就可以对相同内容的控件指定相同的id,这样就算替换布局,也不用重写ViewHolder,当然对于Adapter也仅仅只需要替换相应的布局就ok

5.耦合

这个和维护的耦合相同,毕竟很多地方本来就存在交叉,所以就没有必要再说了

安全性

个人觉得数据安全性并不仅仅是数据安全,还有程序的一些操作安全性(简单来说就是避免程序出现一些非崩溃性异常)

1.数据安全性

数据安全就包括数据抓取、数据拦截以及数据修改。当然这些并不能完全避免,只能是由我们写出尽量安全的代码,比如关键数据使用HTTPS以及对数据进行md5验证完整性,对于数据修改,可以通过多文件多地址保存文件修改记录,来确定保存的数据是否被修改,毕竟Android只要获取root权限,就能对很多文件进行修改了

2.操作安全性

简单来说经常遇到的一个问题,比如按钮的点击事件,有可能这个点击事件是请求网络或者打开Activity,这样就会存在事件还未处理完成再次收到事件,只要你一直猛点,肯定可以的,所以这样就需要我们队控件事件进行一些封装,比如打开界面的,可以在点击后禁用按钮,界面打开完成后才启用,请求网络的可以在开始就禁用按钮,请求结果反馈了才启用(不管是请求成功或者失败)

切入性

切入性就是当另外一个从未接触过此项目的人,能快速进入这个项目进行开发,当然想要切入性好,前面的维护和扩展是必须要满足的,下面我就说说我认为能增加切入性的一些点

1.文档

开发都不喜欢写文档,这是肯定的,但是每当我们去接手一个项目的时候,发现没有文档估计就要开始骂娘了,所以文档不仅要写,还要写的规范。我认为开发中必须要有的几个文档:代码规范文档(比如包名规范,文件命名规范,id命名规范等等,具体依据项目情况而定)、接口文档

2.注释

每个类必须要有注释,方法也要有注释,同时也要标注好方法*后修改人是谁,这样出现疑问或者问题别人就知道该去找谁了,当然有些方法是不需要有注释的,比如重写父类的方法,只是如果方法内逻辑很复杂,可以在方法中添加一些对逻辑的说明。当然注释也不是越多越好,具体注释该怎么写,Google*清楚,不能Google百度也行

3.包名

什么类放什么包简单,但是一但一个包中的类太多,也是非常不方便,所以正确的分包也是非常重要的,目前常见的Android分包包括针对功能分包(不是指程序功能,而是指UI,http,bean这些功能),还有就是模块分包(这就是程序的功能了,比如login,user等),当然具体怎么分包需要团队协商,防止一个包中类太多,而我现在一个程序很大的情况下,采用的分包是先功能分包,再模块分包,比如:

wang.raye.demo
|-activity
| |-user
| |-login
|-fragment
| |–user
| |–login

这样能减少每个包的类数量,当然如果项目本身并不是很大,可以完全不用这种分包模式,毕竟如果只是小项目,这样会使项目变得更加难以阅读

MVC 还是 MVP

现在针对移动端开发,衍生了很多种架构,如MVC、MVP、MVVM,当然这里着重分析MVC和MVP,毕竟MVVM我也只是了解过一下,没有详细接触,至于什么是MVC和MVP我也不想做过多描述,这类的文章实在太多,这里主要分析一下什么情况下用MVC和MVP

至于很多人接触过MVP后就觉得MVC就一无是处,我个人觉得这是不对的,不同的项目,不同的业务,用不同的架构,这是我觉得应该做的事,没有一种架构能适合所有项目开发(毕竟现在还没有),所以我们分析MVC和MVP分别在Android以什么样的方式实现

MVC

MVC是以XML布局为V(视图),Activity或Fragment为C(控制器),数据实体为M(模型),但是因为XML的局限性,所以其实我们还是需要在Activity或Fragment中对视图进行操作,所以这也就是为什么那么多人抵制MVC的原因,因为这也算不上完整的MVC

优点:开发迅速,结构易理解

缺点:当一个界面业务逻辑一多,不方便维护

MVP

MVP是为XML配合Activity或Fragment为V(视图),同时抽象出接口,界面相关业务抽离出来的P(Presenter)同时通过视图接口来更新UI,数据实体为M(模型)

优点:业务发生变化时易修改,同时能减少修改过程中引发bug,也能将多人协同开发充分调用起来(并不是针对一个人负责一个模块的模式,而是多人协同开发一个模块)

缺点:开发速度会有所降低

所以对比2种架构,发现MVC适合不需要太多业务逻辑和功能性少的APP,比如数据展示类应用,MVP适合每个界面有复杂逻辑以及大型多人开发的APP

框架选择及使用

如何选择框架

1.稳定性

如果框架本身就不稳定,那么导致的结果就是程序本身也会漏洞百出,所以选择框架一定要选择经历过考验的稳定的框架

2.扩展性

随着程序功能的增加,以前的框架可能会出现功能不足的情况,但是因为这点是不可预见的,所以我们选择框架时一定要了解好框架本身的扩展性如何,或者对框架有较深的理解,能够自己扩展框架,当然有些框架解决的问题比较单一,一般也不用担心过多的扩展性,比如Butterknife或PreIOC这类单一性框架,但是有些框架经常需要配合做一些操作,比如图片加载框架,常见的一些就是清理图片缓存、获取图片缓存大小、显示圆角或者圆形图片, 常用的图片加载框架UniversalImageLoader都提供了相关的方法或接口来实现

3.封装性

封装性是指能否针对框架进行二次封装,以及封装后的耦合度,详细会在使用篇说明

如何使用

选择好了框架千万不要拿来就用,因为再好的框架也有它局限的地方,当然你也可以简单的在遇到这个框架不能实现的时候,添加另外一种框架,只是这样项目会越来越大,对于APP来说APK也越来越大,65535 的问题也会提前出现,所以为了方便以后有可能出现的切换框架,以及防止初期对框架使用不熟悉而引发出新的bug,在选择好了框架后,一定要对框架进行二次封装,当然有些框架是不需要二次封装的,比如前面说的单一性的框架Butterknife或PreIOC,但是像UniversalImageLoader、OKHttp等框架,必须要进行二次封装,至于封装原则,则是封装后,调用框架对于调用代码来说是透明的,简单来说,就是对于框架调用都通过一个统一的入口进入,并且调用时,不需要传入任何跟框架相关的东西,如果必须要传入接口,可以通过继承框架来实现新的接口传入,这样在真正的使用框架的地方,没有任何关于框架的引用

封装的好处

之所以要这样封装,*大的好处就是一旦框架不能满足需求时,需要进行框架更换时,只需要换掉框架,同时修改统一入口处的代码,就能快速的替换整个框架

Android SDK开发技术分享

一、SDK开发的概念

Android SDK开发,指为第三方app开发提供功能性封装,提供文档(doc),实例(demo),封装包(jar/aar)等,目前互联网公司提供了许多功能性SDK接入,比如腾讯的QQ登录微信登录、广点通联盟、QQ地图接入,阿里的支付宝支付,百度的百度墙广告等等。

二、jar包和aar包

SDK开发目标是为了提供开发包给第三方app的开发者,常见情况下,提供jar包或者aar包。jar包可以包括代码、资源文件(包括图片、xml文件、动态链接库等,需要二次打包),jar由于不能直接引用xml页面布局,难以实现界面布局,必须用java实现所有界面,实现起来麻烦,一个简单的界面要写很多的代码,维护起来也比较麻烦,但是通过aapt编译xml页面布局,使其成为另外一种Android的布局系统更容易解析的一种格式(Compiled xml),在代码中通过反射使用XmlPullParser,inflate出xml中的布局,也可以得到页面。aar包可以包括许多资源(代码、资源文件、配置文件等等,既包含class又包含了res资源下的所有内容),使用常用的app开发方式进行开发,自动会把所有的资源文件、配置文件(甚至是app整体配置文件AndroidManifest.xml)全部引入aar包中,不需要开发人员进行其他工作,相对jar,aar的使用方便许多,但是由于许多开发者依然使用的IDE是Eclipse,在aar接入方面不便,jar接入使用依然较多,在google推荐的IDE Android Studio中,aar的打包和接入就十分方便。

三、sdk开发的原则

sdk编写的原则,可以总结为几点:

1.内容封闭,只开放少数接口,*大程度减少sdk接入方需要了解的细节。

2.包尽可能小,尽可能压缩图片和动态链接库

3.统一接口调用方式,比如:ComPayPlatform.init(context,key); ComPayPlatform.pay(context,key,listener);

四、aar包开发

AS(Android Studio)中Module以库的形式使用,编译后自动生成aar文件,文件包括了Module库的所有有用内容(AndroidMenifest.xml,res文件夹中的所有资源文件,libs中引用的jar和.so的动态链接库,java代码等)。Module可以依次依赖,Module1引用Module2,Module2引用Module3,但是Module1无法直接使用Module3中的内容,Module也可以进行平行依赖,Module1即引用了Module2,也引用了Module3,在sdk开发中也需要注意,尽快不要使用Module依赖,多Module无法打包为一个aar,也要避免依次依赖造成的可能bug。

sdk开发中res文件夹中,资源和id的前缀问题。sdk开发中,res文件夹中的所有资源(图片名,xml视图名,values文件夹下的定义属性名等)建议都加上前缀(比如我加上公司的前缀 bs_***.png),是因为作为aar包被其他app引用后,资源名使用时可能与原程序冲突,原程序名为back.png的图片与sdk中back.png的图片冲突造成bug.

sdk结果的出口,一般使用一个接口,在接口的回调函数返回结果。

/**

*@author张新锦

*/

public interfaceOnPayResultListener {

public voidOnSuccess(String platFormNo);

public voidOnFail();

}

ComPayPlatform.pay(MainActivity.this,”001″,fixPlatFormNo,”1000001″,”00101″,”222222″,

“测试111”, 0.01,getCurrentTimeFormatyyyyMMdd(),getCurrentTimeFormathhmmss(),”remark1″,””,

newOnPayResultListener() {

@Override

public voidOnSuccess(String platFormNo) {

textView.append(“支付成功 , 返回数据: platformNo :”+platFormNo+”\n”);

}

@Override

public voidOnFail() {

textView.append(“支付失败\n”);

}

});

五、发布前的工作

5.1     sdk的代码混淆

sdk代码混淆与app不同的地方,除了普通app的混淆机制外,sdk特别注意开放接口和内部引用包的不混淆。

5.2     sdk包内容的发布

编写sdk代码、并且测试通过后,sdk开发的工作才进行一半,另外一半的工作在写出demo程序和接入文档。sdk的*终目的是为了其他开发者接入,不止在编码是注意接入的代码要简洁、明了,更要在接入文档中详细写出方法、参数的意义,*好直接在文档中给出事例。文档*好也写清楚开发环境要求,jdk要求和引用aar文件的详解。demo程序也十分重要,demo程序简洁,注释详细,使用sdk接口的代码进行详细注释,让接入sdk的开发人员明白每段代码的含义。

搭建私人邮件服务器

怎样使用本地服务器搭建一个邮箱,这样就可以脱离qq或者其他企业邮箱的限制,即可以做到节省成本,又可以得到收发邮件的一个保密性。
这里我们先展示一下本地搭建邮箱服务器后的成功例子:

%title插图%num

可以看到,这里qq邮箱收到我这边发送的一个测试邮件例子(特别说明一下,这里的wordcap.top 是我自己购买的一个域名)
同样qq也可以向我发送邮件:

%title插图%num

怎样搭建一个属于自己的私人邮箱服务器了,我这里演示一遍:
准备:
一个顶级域名:国内国外的都可以,当然也可以不需要顶级域名,前提是这个域名需要解析到你的服务器ip上
frp 内网穿透(包含公网ip的服务器):这个方便本地调试(如果不是很懂也可以查看上篇微信中内网穿透文章)
邮件服务器:Linux上可以用iredmail,Windows是可以用hMailServer,由于我为了方便测试,所以我用的是Windows版本的。
Linux安装方式(这里大家如果是用的Linux服务器可以用这个)
官网(开源iredmail安装方式):
https://docs.iredmail.org/install.iredmail.on.rhel-zh_CN.html

1.安装软件
下载Windows版本的hMailServer
https://www.hmailserver.com/download
双击运行安装

1.1输入邮件登录密码
%title插图%num

安装完成之后连接本地服务器:
1.2添加一个主机域名:

%title插图%num

1.3添加一个邮箱账号

%title插图%num

1.4查看该邮箱服务器是否是启动状态:

%title插图%num

1.5使用foxmail 测试一下:
下载安装

%title插图%num

运行后手动配置(手动设置,设置密码等等):

%title插图%num

1.6本地写封邮件测试:

%title插图%num

本地虽然发送成功,但是收到腾讯的处理消息:

%title插图%num

2.配置软件需要环境
由于我们的ip地址是动态的,不是固定的所以受到限制
2.1配置域名解析到服务器IP上
这里我们为了方便测试,在某平台上花了9块人民币购买了一个域名,并配置了二级域名和解析地址:

%title插图%num

2.2配置内网穿透文件
同时为了方便测试,我们用内网穿透工具frp在本地进行测试:
首先我们测试一下,端口在不符合常规邮件端口的情况下能否收到邮件:
我们修改成这样:

%title插图%num

2.3测试
试着用qq发送邮件:

显示已经发生成功,但是我们查看邮件时却并未收到任何邮件

%title插图%num

2.4准确配置邮件监听端口
我们监听一下25这个端口(收邮件端口并不进行修改):

%title插图%num

2.6重新测试
再重新写一封,我们发现通过25这个端口是可以接收到邮件的:

发现也可以正常的收到
所以,设置邮件服务器端口和我平常设置网页不一样,平常http接口可以通过url后缀进行修改端口号,但是邮件服务器端口都是指定的
2.7使用代码实现注册邮件激活功能
我们现在试着用代码测试一下发送一个激活邮件的功能(这里我是用的是spring boot 框架):
代码如下(虽然可以配置spring boot yml 文件,但是测试时我这边使用的是代码,大家实际运用是改动一下就可以了):

@Test
public void sendSimpleMail() throws Exception {
//手动创建的实例的属性和配置文件中的大致相同
JavaMailSenderImpl sender=new JavaMailSenderImpl();
sender.setDefaultEncoding(“utf8”); //编码
sender.setHost(“mail.wordcap.top”);//163 smtp服务器
sender.setPort(25); //端口
sender.setUsername(“test@mail.wordcap.top”); //邮箱
sender.setPassword(“123456”);//授权码
sender.setProtocol(“smtp”); //协议
//配置额外属性
Properties properties=new Properties();//额外设置的属性
properties.setProperty(“mail.smtp.auth”, “true”);//是否需要验证
properties.setProperty(“mail.smtp.timeout”,”2000″);//超时
// properties.setProperty(“mail.smtp.ssl.enable”, “true”);//ssl加密

properties.setProperty(“mail.debug”, “true”);//是否显示调试信息(可选测试用)
properties.setProperty(“mail.transport.protocol”, “smtp”);//协议
properties.setProperty(“mail.smtp.auth”, “true”);//设置用户验证
properties.setProperty(“mail.smtp.timeout”,”250000″);//超时时间
properties.setProperty(“mail.smtp.connectiontimeout”,”250000″);//超时时间

sender.setJavaMailProperties(properties);

SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(“test@mail.wordcap.top”);

运行之后,qq上直接收到这封邮件:

%title插图%num

本地编译器输出如下:

%title插图%num

测试完毕感觉还是不错的。

Python来做物联网

使用Python来做物联网,就是这么easy!

%title插图%num

搭建整套物联网系统的方法有很多,*近四处捣鼓,使用python + 阿里云搭建一套*简单的物联系统,可以将单片机上的数据通过阿里云传输到PC端。 一、基本结构 先看架构图 框架.png 二、设备端接入 物联网终端是用的ESP32,是一款自带蓝牙和Wifi的单片机。利用它可以直接接入互联网,无需其他模块。当然你可以将现在流行的NB-Iot模块来联网,不过需要自己写一下驱动程序。我买的模块是支持micropython开发的,在淘宝上可以搜索到,用起来很方便。有时间我会补上这一块的初步教程。 ESP32模块.jpg Micropython是可以在低端硬件上运行的python,可以使用python语言直接操作IO 和MCU的外设比如UART、I2C等,用起来非常方便,不要搭建复杂的开发环境,也不需要学习寄存器配置。作为一个对传统MCU开发非常熟悉的硬件工程师来说,感觉操作起来非常简单。目前Micropython已经支持很多硬件了,应该用比较广泛的STM32部分系列也被支持。Micropython也已经支持很多常用的库,比如蓝牙,telnet,mqtt等。下面这个链接是micropython的中文论坛。 www.micropython.org.cn/bbs/forum.p… ESP32 通过wifi 接入互联网,使用mqtt协议接入阿里云,将温度数据上传至阿里云。在云端通过消息订阅可以直接查看温度信息。在PC端使用python调用MQTT协议,接入到阿里云。但是PC端和ESP32在阿里云上是两个不同的设备,需要通过阿里云来转发信息,这样PC就可以拿到ESP32上传的数据了。 ESP32 上的代码如下: from umqtt.simple import MQTTClient import usocket as socket import time import wifi

wifi.connect()

#Demo_01 ProductKey = “”#使用你自己的 ClientId = “1234|securemode=3,signmethod=hmacsha1|” DeviceName = “Demo_01” DeviceSecret = “**********************”#使用你自己的

strBroker = ProductKey + “.iot-as-mqtt.cn-shanghai.aliyuncs.com” Brokerport = 1883

user_name = “Demo_01&”#使用你自己的 user_password = “*************************************”#使用你自己的

print(“clientid:”,ClientId,” “,”Broker:”,strBroker,” “,”User Name:”,user_name,” “,”Password:”,user_password,” “)

def connect(): client = MQTTClient(client_id = ClientId,server= strBroker,port=Brokerport,user=user_name, password=user_password,keepalive=60) #please make sure keepalive value is not 0

有几点需要说明: 1.代码中的wifi.connect()函数需要自己编写,网上能搜到类似的,也可以打赏私信我所要源码。 2.阿里云物联网平台的接入需要进行三元组认证,会根据一定的规则生成登录名和密码,这个网上信息还是比较全面的。 3.向阿里云物联网平台发布消息的格式一定要按照代码中所写,网上很多代码,但是对这一块的描述都不清楚。 Micropython使用的umqtt.simple库,一定要设置keepalive时间,否则无法连接。这一点我是摸索了好久,*终通过查看库的源码才发现的问题。 三、云端设置 在云端建立一个高级产品,并创建两个设备,以供ESP32 和PC连接。 device.JPG 需要在产品中定义一下功能。 device_define.JPG 云端和设备端都建立好了之后,可以查看设备运行状态看到数据上传 云端数据查看.JPG 这是查看数据记录得到的结果 云端数据记录.JPG 当你看到正确的数据之后,就说明你的成功接入物联网并上传了数据。 接下来就是*重要的部分——设置是使用规则引擎来进行数据转发,将设备demo_01的数据转发到demo_02。这一步的语法很重要,虽然有官网有详细教程,但是当时还是搞了好久才完全正确。 规则查询语句: SELECT items.IndoorTemperature.value as IndoorTemperature FROM “/sys/use-your-productkey-here/Demo_01/thing/event/property/post” WHERE items.IndoorTemperature.value > 0 四、PC端接入 PC 端使用python模拟MQTT设备登陆阿里云订阅消息就行了,只要装好python很快就可以实现,网上也有很多代码。代码的很大一部分就是在做三元组认证,可以将这部分稍微修改一下来计算ESP32 登陆时所需的 PC端python代码如下: # coding=utf-8 import datetime import time import hmac import hashlib import math

try: import paho.mqtt.client as mqtt except ImportError: print(“MQTT client not find. Please install as follow:”) print(“pip install paho-mqtt”)

#Demo_02 ProductKey = “*********”#使用你自己的 ClientId = “2234” # 自定义clientId DeviceName = “Demo_02” DeviceSecret =”**********************************8″#使用你自己的

us = math.modf(time.time())[0] ms = int(round(us * 1000)) timestamp = str(ms)

def calculation_sign(signmethod): data = “”.join((“clientId”, ClientId, “deviceName”, DeviceName, “productKey”, ProductKey, “timestamp”, timestamp))

strBroker = ProductKey + “.iot-as-mqtt.cn-shanghai.aliyuncs.com” port = 1883

client_id = “”.join((ClientId, “|securemode=3”, “,signmethod=”, “hmacsha1”, “,timestamp=”, timestamp, “|”)) username = “”.join((DeviceName, “&”, ProductKey)) password = calculation_sign(“hmacsha1”)

print(“=”*60) print(strBroker) print(“client_id:”, client_id) print(“username:”, username) print(“password:”, password) print(“=”*60)

def on_connect(client, userdata, flags, rc): print(“OnConnetc, rc: ” + str(rc))

def on_publish(client, msg, rc): if rc == 0: print(“publish success, msg = ” + msg)

def on_subscribe(mqttc, obj, mid, granted_qos): print(“Subscribed: ” + str(mid) + ” ” + str(granted_qos))

def on_log(mqttc, obj, level, string): print(“Log:” + string)

def on_message(mqttc, obj, msg): curtime = datetime.datetime.now() strcurtime = curtime.strftime(“%Y-%m-%d %H:%M:%S”) print(strcurtime + “: ” + msg.topic + ” ” + str(msg.qos) + ” ” + str(msg.payload)) on_exec(str(msg.payload))

def on_exec(strcmd): print(“Exec:”, strcmd) strExec = strcmd

if name == ‘main’: mqttc = mqtt.Client(client_id) mqttc.username_pw_set(username, password) mqttc.on_message = on_message mqttc.on_connect = on_connect mqttc.on_publish = on_publish mqttc.on_subscribe = on_subscribe mqttc.on_log = on_log mqttc.connect(strBroker, port, 120) # mqttc.loop_start() time.sleep(1) temperature =27.55 mqttc.subscribe(“/sys/************/Demo_02/thing/service/property/set”, qos=1) # 换成自己的 #send_mseg = ‘{“pm_25″: %s,”area”:”%s”,”time”:”%s”}’ % (0, 0, datetime.datetime.now()) #send_mseg = ‘{“id”: “1234”, “version”: “1.0”,”params”: {“IndoorTemperature”: %s},”method”: “thing.event.property.post”}’%(temperature) send_mseg = ‘{“params”: {“IndoorTemperature”: %s},”method”: “thing.event.property.post”}’ % (temperature)

五、总结 工作之余了解了一下物联网的发展,看到有意思的东西打算学一下,刚好看到了microPython,震惊之余,决心做点小东西玩玩。 这套框架全部使用python实现,比我了解到的*大多数物联网方案要简单太多,虽然有些开发首先,但是用来实现一些简单设计应该是不成问题的,只要你会python,这套系统可以很快构建。当然python也是非常好学的,长期使用C语言的人根本不需要什么学习就可以上手。记住,你不是一个人在战斗。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速