10.0首次网络请求 ios

2018-04-21 11:57:26 JoyceZhaoQian 阅读数 256
  • 网络应用服务器(五)

    通过本课程的学习,学员从TCP/IP UDP Socket基础概念,到网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解。大量的实际项目,代码的学习,让学员掌握一个类似无人机,...

    221人学习 徐朋
    免费试看

框架

核心蓝牙

与蓝牙4.0低功耗设备通信


概述

核心蓝牙框架提供了一些你应用程序与装备了蓝牙低功耗无线技术的设备之间进行通信所必需的类
不要给核心蓝牙框架的类添加子类。重写这些框架类是不被框架本身支持的,也会导致不能被框架识别的后果。

重要
iOS 10.0或者之后的iOS应用程序在它的Info.plist文件中必须包含对它需要访问或者将会崩溃的数据类型的用法描述键。为了具体地访问蓝牙外围数据,Info.plist文件中必须包含NSBluetoothPeripheralUsageDescription

主题


  • CBATTRequest
    CBATTRequest类表示从远程中心设备(由CBCentral对象表示)请求读取和写入的属性协议(ATT)。远程中心使用这些ATT请求读取和写入本地外围设备的特征值(由CBPeripheralManager对象表示)。另一方面,本地外围设备使用CBATTRequest对象的属性适当地响应读取和写入请求,使用CBPeripheralManager类的respond(to:withResult:)方法
  • CBAttribute
    CBAttribute是一个抽象的基类,用来定义常见的集合对象的行为,这些集合对象代表了由外围设备提供的各方面的服务。
  • CBCentral
    CBCentral类表示已经连接上一个在本地设备上实现外围设备角色的应用程序的远程中心设备。也就是说,当你使用CBPeripheralManager类实现外围设备角色的时候,连接到你的本地外围设备的中心会被视为CBCentral对象。远程中心由全局唯一标识符(UUIDs)识别,由NSUUID对象表示。
  • CBCentralManager
    CBCentralManager对象用于管理发现的或者是连接的远程外围设备(由CBPeripheral对象表示),包括扫描,发现和连接到广告的外围设备。
  • CBCharacteristic
    CBCharacteristic和它的子类CBMutableCharacteristic一个外围设备的更多服务信息。CBCharacteristic对象特别表示远程外围设备的服务特征(远程外围设备由CBPeripheral对象表示)。一个特征包含单个值和很多描述这个值的描述符。特征的属性决定了特征值如何被使用和描述符是怎样被访问的。
  • CBDescriptor
    CBDescriptor和它的子类CBMutableDescriptor表示一个外围设备的特征描述符。CBDescriptor对象特别表示一个远程外围设备的特征描述符(远程外围设备由CBPeripheral对象表示)。描述符提供了特征值的更多信息。例如,它们可以描述人类可读形式的值,和描述怎样为表示目格式化值。
  • CBManager
    核心蓝牙管理对象的抽象基类(中央的和外围的)。
  • CBMutableCharacteristic
    CBMutableCharacteristic对象表示本地外围设备的服务特征(本地外围设备由CBPeripheralManager对象表示)。这个类在它继承的CBCharacteristic类上增加了很多属性的写访问。
  • CBMutableDescriptor
    CBMutableDescriptor对象表示一个本地外围设备的特征描述符(本地外围设备由CBPeripheralManager对象表示)。
  • CBMutableService
    CBMutableService类给它继承的CBService类的所有属性添加了写访问属性。你使用这个类创建一个服务或者一个本地外围设备所包含的服务(由CBPeripheralManager 对象表示)。在你创建一个服务后,你可以使用CBPeripheralManager类的add(_:)方法把它添加到外围设备的本地基础数据中。在你给外围设备的本地基础数据中添加了一个服务后,这个服务会被缓存,你就不能再改变它了。
  • CBPeer
    CBPeer是一个抽象的基类,用来定义表示远程设备对象常见的行为。你通常不用创建CBPeer或者它的具体子类的实例。
  • CBPeripheral
    CBPeripheral类表示你的应用程序通过中心管理器(CBCentralManager的实例)发现广播的或者当前连接上的远程外围设备。外围设备由NSUUID对象全局统一标识符(UUIDs)标识。外围设备可能包含一个或者多个服务,或者提供它们链接的信号强度的相关有用信息。
  • CBPeripheralManager
    CBPeripheralManager对象用于管理带有本地外围设备的通用属性配置文件(GATT)数据库的发布服务,和把这些服务广播给中心设备(由CBCentral对象表示)。虽然服务在数据库中,但它是可见的,而且可以通过任何连接的中心进行访问。也就是说,如果你的应用程序没有指定蓝牙外围设备后台模式,当应用程序处于后台模式或者暂停状态时,蓝牙服务的内容是不可用的;任何尝试访问服务的特征值或者特征描述符的远程中心都会接收到错误信息。
  • CBService
    CBService和它的子类CBMutableService表示一个外围设备实现一个函数或者一个设备功能(该设备的部分功能)的数据集合和相关行为的服务。CBService对象特别表示远程外围设备的服务(由CBPeripheral对象)。服务是主要的或是次要的,并且可能包含很多特征或者包含服务(引用别的服务)。
  • CBUUID
    CBUUID类的实例表示用在蓝牙低功耗通信中的128位全局统一标识符(UUIDs)属性,例如外围设备服务,特征和特征描述符。当你开发你的应用程序时,这个类提供了很多工厂方法来处理长UUIDs。例如,你可以创建一个CBUUID对象来表示它而不是传递它,而不是在你的代码中通过128位蓝牙低功耗属性的字符串传递。
  • CBL2CAPChannel

协议


*CBCentralManagerDelegate
CBCentralManagerDelegate协议定义了CBCentralManager对象的代理必须采用的方法。协议的可选方法允许代理监控外围设备的发现、连接、搜索。协议中唯一必须的方法显示了中心管理器的可用性,并且在中心管理器的状态更新时会被调用。
*CBPeripheralDelegate
CBPeripheral对象的代理必须采用CBPeripheralDelegate协议。这个代理使用这个协议的方法监控远程外围设备的服务和属性的发现、探索和交互。子啊这个协议中没有必须的方法。
*CBPeripheralManagerDelegate
CBPeripheralManager对象的代理必须采用CBPeripheralManagerDelegate协议,这个协议由很多可选方法和一个必须方法组成。这个协议的可选方法被代理用来验证发布和广播,监控读取和写入,订阅远程中心设备的请求。这个协议的必须方法,它显示外围设备管理器是否可用,当外围设备管理器的双腿更新时会被调用。

参考


*Core Bluetooth Constants
这篇文档表述了在核心蓝牙框架中发现的常量
*Core Bluetooth Enumerations
*Core Bluetooth Data Types

结构

*CBATTError结构体
*CBAttributePermissions结构体
表示一个特征值的读取、写入好加密权限的值
*CBCharacteristicProperties结构体
表示一个特征可能属性的值。由于特征属性可以组合,一个特征可能会有许多的属性值集合。
*CBError结构体


原文链接地址:https://developer.apple.com/documentation/corebluetooth
具体的类和协议会在后续的版本中进行更新
初次翻译,多有不足,欢迎大家指正

                                            持续更新中...
2019-04-27 22:28:09 jusulysunbeamy 阅读数 2446
  • 网络应用服务器(五)

    通过本课程的学习,学员从TCP/IP UDP Socket基础概念,到网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解。大量的实际项目,代码的学习,让学员掌握一个类似无人机,...

    221人学习 徐朋
    免费试看

 

1-APP的安装和卸载

1.1安装

  • 软件在不同操作系统(iOS 9.0/iOS 10.0/iOS 11.0/iOS 12.0及其他小迭代系统版本)上是否正常安装
  • 软件在不同的手机型号(iPhone 5、 iPhone 6/6 plus、iPhone 7/7 plus、iPhone 8/8 plus、iPhone X/XR等)上是否正常安装
  • 软件在不同屏幕分辨率/屏幕尺寸大小的手机上是否正常安装
  • 安装过程中,意外情况(如死机,重启,断电)的处理是否符合需求
  • 安装空间不足(内存或者磁盘空间不足)时是否有相应提示
  • 首次安装完成后,是否正常启动APP
  • 版本覆盖安装后,是否正常启动APP

1.2卸载

  • 卸载过程中,出现的意外情况(如死机、断电、重启)的处理是否符合需求说明
  • 卸载完成后,是否全部删除所有的安装文件夹
  • 第三方卸载,检查是否卸载完全

 

2-APP的界面测试

用户界面测试英文名为User interface testing,简称UI测试,测试用户界面的功能模块的布局是否合理,整体风格是否一致和各个控件的放置位置是否符合客户使用习惯,更重要的是要符合操作便捷,导航简单易懂,界面中文字是否正确,命名是否统一,页面是否美观,文字、图片组合是否完美等等。

UI测试的内容:包括导航测试、图形测试、内容测试、表格测试、H5界面测试、整体界面测试等

导航测试:导航描述了用户在一个页面内操作的方式,在不同的用户接口控制之间,导航的方式主要有:按钮、目录、菜单、弹框、列表等;

  • 按钮:按钮的可点击的条件,按钮按下的效果,按钮的的跳转引导等,如‘登录’按钮,输入账号和密码才会高亮显示为可点击状态
  • 目录:很多APP会在主页的右侧显示软件内容的目录结构供用户便捷有目的的浏览,也有的软件会放在顶部区域或底部区域,测试显示布局的正确性和跳转的正确性等
  • 菜单:右上角的‘···’一般是隐形的菜单,需要查看这些菜单是可配置的,还是固定的,已经显示文字的长短是否正常,跳转是否正确
  • 弹框:APP包含消息弹框/确认框/信息提示框/表单提交框等等,很多类型的弹框都会引导用户去其他页面,查看弹框中信息显示是否完整,点击不同按钮,是否如需求说明一样正确跳转
  • 列表:APP的列表分页其实不明显,一般不会明确的标示是第几页,但是在服务端是存在分页,查看是否存复用的问题

图形测试:图形包括图片、动画、边框、颜色、字体、背景、按钮等;

  • 横向比较。各控件操作方式是否统一,页面标签风格是否统一
  • 自适应界面设计(屏幕尺寸,屏幕分辨率),图形根据窗口大小自适应
  • 横屏/竖屏测试:游戏/图片/视频均有横竖屏自动切换,很多手机网站也做了横竖屏自适应,观察横屏或者竖屏页面的显示效果
  • 图片、动画、边框、颜色、字体、背景、按钮等动画效果是否符合需求设计
  • 图片或者动画的收起效果是否符合需求设计
  • 图片来源是用户自己上传/本地的/服务端配置的,查看图片在APP端的显示效果

内容测试:内容测试用来检验APP应用程序提供信息的正确性、准确性和相关性。信息的正确性是指信息时可靠的还是误传的。信息的相关性是指是否在当前页面可以找到与当前浏览信息相关的信息列表或入口;

  • 页面显示文案:文案是否表意不明,是否有错别字,是否有敏感性词汇,是否布局和设计一致,是否不同的屏幕尺寸/屏幕分辨率的手机上显示完整,文案来源是本地的还是后台可以配置的,文案的长短是否有限制等
  • 文本输入框:输入框的默认文案是否清楚正确,文字长度是否限制,输入的文字是否有敏感性词汇限制,达到最大长度是否允许继续输入,删除输入的内容是否再显示默认文案,输入过程光标是否一直显示在字的末尾等
  • 按钮上的文案:文案是否在边框内,文案的颜色是否正常,文案在点击效果下是否正常显示,文案在不同的屏幕尺寸/屏幕分辨率的手机上显示是否正常,文案表明意思和实际的操作是否相匹配等
  • 链接上的文案:一般的协议文案的内容和连接的协议一致,链接文案的颜色是否显示正确
  • 图形上的文案:文案是否表意不明,是否有错别字,是否有敏感性词汇,是否布局和设计一致,是否不同的屏幕尺寸/屏幕分辨率的手机上显示完整,文案来源是本地的还是后台可以配置的,文案的长短是否有限制,文案是否在图形边框内等
  • 确认信息文案:显示的文案是否和用户所填的信息保持一致,是否布局和设计一致,是否不同的屏幕尺寸/屏幕分辨率的手机上显示完整等
  • 提示信息文案:包含消息通知框,操作提示框,引导框等,一般这些提示信息框都包含了很多逻辑,测试对应逻辑下提示的信息是否正确

表格测试:表格通常用于批量显示数据,一般有标题行、标题列为固定的行列。

  • 标题行:有无标题行,标题行是否居中显示,标题行的单元格是否禁止编辑
  • 标题列:有无标题列(不一定),标题列是否居左显示(不一定),标题列中的单元格是否禁止编辑
  • 非标题行/列:非标题行/列中的单元格是否允许编辑(不一定),非标题行/列中的单元格允许编辑时,参考文本框控件进行测试;
  • 同一数据类型:所在行/列的单元格是否有统一的居左、居中、居右显示方式;
  • 日期型数据:所在行/列单元格的内容显示格式是否一致;
  • 时间型数据:所在行/列单元格内容显示格式是否一致;
  • 货币型数据:所在行/列单元格的内容显示格式是否一致;
  • 小数型数据:所在行/列单元格的内容显示格式是否一致;
  • 当前所在的单元格:是否提供突出显示功能,前景/背景色、字体、字号是否正确;换行、换列时,所在单元格和非所在的显示是否正确;
  • 当前选中的单元格:是否提供突出显示功能,前景/背景色、字体、字号是否正确;换行、换列时,选中单元格和非选中的显示是否正确;
  • 当前所在行/列:是否提供突出显示功能,前景/背景色、字体、字号是否正确。换行、换页时,突出显示的行显示是否正确;
  • 排序功能:某列是否具有自动排序功能(不一定)。比如日期型列提供有这样的功能:点击一次为从小到大排序,再点击为从大到小排序,查看点击后的执行效果是否正确;
  • 翻页功能:是否有默认数据条数,每页是否显示正常,是否有复用情况
  • 图片功能:是否存在图片,图片显示是否正常;是否可点击,点击后跳转是否正常
  • 滑动功能:上下多次连续是否会有显示正常,数据展示完全,页面底部是否有提示

H5页面界面测试:现在大部分的APP中都有H5页面,H5页面可以实现快速迭代,现在通用比较广

  • 兼容性:H5页面在不同的手机操作系统/不同手机品牌/屏幕尺寸/屏幕分辨率的手机上显示是否正常

整体界面测试:整体界面是指整个APP应用程序的页面结构设计,是给用户一格整体感

  • 测试界面设计是否合理、简洁、美观,操作是否方便;功能键、数据项信息是否齐全
  • 确认系统中同一功能的名称是否统一;同一个功能按钮,不同模块相同的错误提示信息是否统一
  • 不同模块相同字段值的输入方式是否统一
  • 所有弹出窗口显示位置是否统一
  • 设计样式、风格(查询条件样式;输入风格(点选/手输入))是否与系统其它模块统一
  • 确认页面内所有字段名称显示风格是否统一(居中、左对齐、右对齐,一般采用居中显示风格)
  • 添加/修改保存后,添加/修改界面是否自动关闭要求统一(建议修改保存后,修改界面一般是自动关闭)

 

3-APP的业务功能测试

3.1 APP的常规性业务功能测试

功能测试的内容归为:界面、数据、操作、逻辑、接口

  • 界面测试:指测试系统界面整体布局的合理性,以及是否清晰/美观,包括颜色搭配/字体/文字是否对齐/图片大小与位置/弹出窗口的位置是否合适。其次还会测试用户是否可以调整布局/是否自定义界面(包括文字/图片/颜色等)。
  • 数据测试:指接受正确的数据输入,并对一次数据的输入有提示和容错处理。
  • 操作测试:指用户操作菜单/按钮/链接/滑动/输入等对APP应用程序的操作,是否符合操作习惯,是否有正确的提示等等。
  • 逻辑测试:指某个操作需要多个步骤实现,应有清楚的提示,或者向导来帮助用户完成,某项功能,从不同的入口进入有不同的操作路径,但是逻辑上应该是一致,系统的各种状态要按照业务流程变化保持稳定。
  • 接口测试:指让接口配合多种硬件或者内部接口/外部接口,应保持其规范性/一致性/完备性,接口还需要是可定义或者可配置的,应具有良好的兼容性和扩充性。

3.2 APP功能测试的特殊性

APP业务功能测试的特殊性:包括应用的前后台切换、免登录、数据更新、离线浏览、系统权限等

应用的前后台切换测试:

  • APP切换到后台,再打开APP,检查是否停留在上一次操作界面,检查功能是否正常、程序是否崩溃、数据是否更新
  • 手机锁屏解锁后进入APP,检查是否停留在上一次操作界面,检查功能是否正常、程序是否崩溃、数据是否更新
  • APP使用过程中被电话中断,再回到APP,检查是否停留在上一次操作界面,检查功能是否正常、数据是否更新
  • Kill掉APP后,再打开APP,检查功能是否正常、数据是否更新、用户登录状态是否正常
  • 存在必须处理的提示框,切换到后台,再切换到前台,检查提示框是否存在
  • APP使用过程中,出现断电/意外关机重启等异常情况,再次打开APP,检查APP功能是否正常

免登录测试:

token的概念:token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。

简单token的组成;uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token的前几位以哈希算法压缩成的一定长度的十六进制字符串。为防止token泄露)。

APP利用token机制进行身份认证的加密解密步骤(RSA非对称加密算法):

  1. 客户端向服务器第一次发起登录请求(不传输用户名和密码)。
  2. 服务器利用RSA算法产生一对公钥和私钥。并保留私钥, 将公钥发送给客户端。
  3. 客户端收到公钥后, 加密用户密码,向服务器发送用户名和加密后的用户密码; 同时另外产生一对公钥和私钥,自己保留私钥, 向服务器发送公钥; 于是第二次登录请求传输了用户名和加密后的密码以及客户端生成的公钥。
  4. 服务器利用保留的私钥对密文进行解密,得到真正的密码。 经过判断, 确定用户可以登录后,生成sessionId和token, 同时利用客户端发送的公钥,对token进行加密。最后将sessionId和加密后的token返还给客户端。
  5. 客户端利用自己生成的私钥对token密文解密, 得到真正的token。

 

  • 非银行/金融等大部分APP都有免登录功能,打开APP,检查登录状态是否是最近一次登录的用户
  • APP切换到后台,再打开APP,检查登录状态是否是最近一次登录的用户
  • Kill APP,再打开APP,检查登录状态是否是最近一次登录的用户
  • 无网络情况,打开APP,检查登录状态是否是最近一次登录的用户
  • 手机重启,打开APP,检查登录状态是否是最近一次登录的用户
  • 切换账号登录,检查APP内的登录用户是否是当前登录账号,数据信息和当前账号是否保持一致
  • 用户登出APP后,再打开APP,检查APP的登录状态是否为未登录状态
  • 同一账号登录到多台设备(需求允许),检查多台设备的免登录状态是否正常
  • 用户更换密码后,有数据交互时,检查是否会再次进行身份的验证
  • 存在免登录日期限制的,检查在限制的日期外的登录状态是否为未登录

数据更新:手动更新和自动更新

  • 根据应用的业务规则,以及数据更新量的情况,来确定最优的数据更新方案。
  • 手动更新:上拉/下拉/上滑/下滑更新数据,检查更新的数据是否正确,更新的列表是否存在头像或者数据复用的问题
  • 手动更新:更新过程中的动画效果是否符合符合需求设计
  • 自动实时更新:自动更新的频率/自动更新的数据量是否符合需求设计
  • 自动实时更新:自动更新过程中,考虑用户是否让用户感知,是静默更新还是通知更新?
  • 自动定时更新:根据设定的时间,检查更新的数据是否正确(如:报表/抢购等)
  • 筛选数据:筛选的数据请求很多都是从本地取值,检查无网络能否正常筛选
  • 前后台切换:有数据更新后,再次打开APP,APP显示正常

离线浏览:无网络状态浏览APP的内容,即客户端会缓存一部分数据供用户查看

  • 无网络情况:根据APP的特性,是否允许查看存放在本地的部分内容(如某些小说类APP,本地游戏类APP,学习软件类APP等)
  • 无网络情况:APP切换到后台,再切换到前台,能否正常浏览部分内容(如缓存好的视频/音乐等)
  • 无网络情况:Kill掉APP,再打开APP,能否正常浏览部分内容(如缓存好的视频/音乐等)
  • 无网络情况:手机锁屏解锁后进入APP,能否正常浏览部分内容(如缓存好的视频/音乐等)
  • 无网络情况:浏览需要请求服务端的内容时候,检查是否给予了无网络的提示
  • 无网络情况:提交表单时,对于后台提交的请求,检查在连网后是否请求成功

系统权限:一般APP会询问用户定位权限、网络权限、相册权限、相机权限、通知权限

  • 定位权限:定位权限关闭,打开APP,检查APP中涉及定位权限的功能是否正常
  • 网络权限:网络权限关闭,打开APP,检查APP中涉及网络请求的功能是否正常
  • 相册权限:相册权限关闭,打开APP,检查APP中涉及相册权限的功能是否正常
  • 相机权限:相机权限关闭,打开APP,检查APP中涉及相机权限的功能是否正常
  • 通知权限:通知权限关闭,打开APP,检查APP中涉及通知权限的功能是否正常

 

4-APP的交叉事件测试

交叉事件测试是针对智能终端应用的服务等级划分方式及实时特性所提出的测试方法。

交叉事件测试又叫事件冲突测试,是指一个功能正在执行过程中,同时另外一个事件或操作对该过程进行干扰的测试。如;App在前/后台运行状态时与来电、文件下载、音乐收听等关键运用的交互情况测试等。

  • 同一手机设备上,多个APP同时运行,检查是否影响APP应用程序正常功能使用
  • APP使用过程中,前/后台切换,检查是否影响正常功能使用
  • APP使用过程中,拨打/接听电话,检查是否影响正常功能使用
  • APP使用过程中,发送/接收信息,检查是否影响正常功能使用
  • APP使用过程中,发送/收取邮件,检查是否影响正常功能使用
  • APP使用过程中,切换网络(4G、wifi),检查是否影响正常功能使用
  • APP使用过程中,使用蓝牙传送/接收数据,检查是否影响正常功能使用
  • APP使用过程中,使用使用相机、计算器等手机自带的应用功能,检查是否影响正常功能使用
  • APP使用过程中,正在使用其他APP收听音乐,检查APP的声音功能是否正常
  • APP使用过程中,APP有声音调大调小功能,检查APP的声音调节功能是否和手机的声音大小调节功能一致
  • APP使用过程中,通过通知栏通知打开其他应用APP,再回到APP中,检查是否影响正常功能使用

 

5-APP的兼容性测试

APP的兼容性一般包括版本兼容性、第三方兼容性、手机操作系统兼容性、屏幕分辨率兼容性、网络兼容性等

APP的版本兼容性:主要指服务端对客户端历史版本的兼容性

  • APP服务端兼容客户端的历史版本,检查新功能的服务端逻辑是否对旧版本有影响

第三方兼容性:主要指第三方接口或者SDK的兼容性

  • 第三方接口:APP中有调用登录或者支付等的第三方API接口(如在APP用微信或者QQ登录,用微信或者支付宝付款等),检查接口是否正常请求和返回
  • 第三方SDK(SDK 就是 Software Development Kit 的缩写,中文意思就是“软件开发工具包”):APP的第三方SDK的使用,检查在不同操作系统或者不同的品牌手机上涉及的功能是否正常

手机操作系统兼容性:

  • 软件在不同的手机型号(iPhone 5、 iPhone 6/6 plus、iPhone 7/7 plus、iPhone 8/8 plus、iPhone X/XR等)上是否正常安装
  • iOS的操作系统版本:iOS 9.0/iOS 10.0/iOS 11.0/iOS 12.0及其他小迭代系统版本还包括很多子版本号

屏幕分辨率兼容性:

分辨率主要是指显示器所能显示的像素的多少,可以从显示分辨率与图像分辨率两个方向来分类。显示分辨率(屏幕分辨率)是屏幕图像的精密度,是指显示器所能显示的像素的多少。由于屏幕上的点、线和面都是由像素组成的,显示器可显示的像素越多,画面就越精细,同样的屏幕区域内能显示的信息也越多,所以分辨率是个非常重要的性能指标之一。可以把整个图像想象成是一个大型的棋盘,而分辨率的表示方式就是所有经线和纬线交叉点的数目。显示分辨率一定的情况下,显示屏越小图像越清晰,反之,显示屏大小固定时,显示分辨率越高图像越清晰。

  • 检查iPhone 5、 iPhone 6/6 plus、iPhone 7/7 plus、iPhone 8/8 plus、iPhone X/XR等的屏幕兼容性

网络兼容性:

  • 在WIFI/4G/弱网下,查看APP的UI和功能使用是否正常

 

6-APP的升级更新测试

APP的更新分为:强制更新和非强制更新

强制更新:

  • 后台配置了强制更新,打开APP后,检查是否有强制更新提示,强制更新提示框是否可以关闭,强制更新是否有进度条显示
  • 强制更新过程中出现意外(如死机、断电、重启),再次打开APP,检查APP是否再次提示更新
  • 强制更新成功,打开APP,检查老账号的数据是否正常,老账号是否可以正常使用APP的功能
  • 强制更新成功,打开APP,检查已经剁掉的功能或者隐藏的功能,检查新增的功能是否按业务需求设计流程操作
  • 强制更新成功,打开APP,检查APP的版本号是否显示正确
  • 在不同的操作系统中,检查强制更新是否可以正常更新APP

非强制更新:

  • 后台配置了非强制更新,打开APP后,检查是否有非强制更新的提示,是否可以关闭提示
  • 关闭了更新提示,检查历史版本用户是否可以正常使用
  • 关闭了更新提示,再次打开APP,检查非强制更新的提示是否再弹(一般可以设置提示的频率)
  • 更新过程中出现意外(如死机、断电、重启),再次打开APP,检查APP是否再次提示更新,是否还能正常使用
  • 更新成功,打开APP,检查老账号的数据是否正常,老账号是否可以正常使用APP的功能
  • 更新成功,打开APP,检查已经剁掉的功能或者隐藏的功能,检查新增的功能是否按业务需求设计流程操作
  • 更新成功,打开APP,检查APP的版本号是否显示正确
  • 更新成功,检查新版本用户和老版本用户的交互是否正常(如互发消息/新版本的消息通知会不会发送到老版本上/新版本注册的用户登录到老版本上是否正常等)
  • 在不同的操作系统中,检查非强制更新是否可以正常更新APP

 

7-APP的消息通知测试

iOS的APP消息提醒的类型一般分为:Badge(应用图标)、Alert、标记(应用内)、Toast、通知栏、Sound (声音)

Badge(徽章通知) :标记通知是在程序图标的右上角显示的红色标记,里面显示的数字表示需要用户处理的通知的数量

  • 应用图标上的计数,检查计数的逻辑是否和需求设计一致,检查计数的正确性
  • 未打开APP,查看计数的增加是否和需求设计一致
  • 打开APP,再返回到桌面,检查未读计数是否还显示,显示逻辑是否和需求一致

Sound (声音) :声音提示是iOS的一种通知方式,可以自定义音效,可以与其他通知类型搭配使用

  • 声音显示的及时性,检查是否和需求设计一致
  • 提示的声音音效,检查是否和需求设计一致

Alert:强打断型提醒,在APP应用内,用户必须做出选择,否则强制提醒弹框不会关闭(如比赛邀请,APP版本强制更新等)

  • APP打开,在APP应用中操作或者浏览,检查Alert提醒弹框是否正常弹出,是否强制用户做出选择,是否做出选择后弹框关闭
  • 切换APP到后台,检查Alert提醒弹框是否会弹出
  • APP从后台切换到前台,检查Alert提醒弹框是否会正常弹出
  • Kill APP,再打开APP,检查Alert提醒弹框是否会弹出
  • 消息推送对象,检查消息推送的对象是否正确
  • 消息推送时间,检查消息推送的时间是否和需求一致
  • 同一手机,切换账号,打开APP,检查Alert提醒弹框是否会弹出
  • 同一账号,切换手机,打开APP,检查Alert提醒弹框是否会弹出

标记:一种不紧急的提醒方式,APP应用内的消息标记,部分用户有强迫清零的习惯

  • 消息标记的数字(一般是计算的是未读消息),检查计数的正确性,计数最多显示多少条,超过后显示的合理性
  • 在APP应用内,收到新消息,检查计数的及时性和正确性
  • 在APP应用外,收到新消息,再打开APP,检查计数的正确性
  • 消息列表的未读已读消息,检查是否有明确的标识
  • 消息列表的更新机制,检查有新消息提醒,消息列表是否会自动更新
  • 消息已读后,检查未读消息的计数是否相应的减少
  • 消息列表新增了消息类别,检查未读计数中是否加入了该消息类别
  • 消息推送对象,检查消息推送的对象是否正确
  • 消息推送时间,检查消息推送的时间是否和需求一致
  • 同一手机,切换账号,打开APP,检查消息的计数是否和当前账号相对应
  • 同一账号,切换手机,打开APP,检查消息的计数是否和当前账号相对应

Toast:纯告知,不需要处理,一般是针对正在操作的反馈(一般显示在页面的顶部)

  • 操作完成后,检查Toast消息是否及时弹出,检查Toast消息的文案是否正确
  • Toast消息弹出后,检查Toast消息是否在几秒后自动消失

通知栏:Notification支持文字内容显示、震动、三色灯、铃声等多种提示形式,在默认情况下,Notification仅显示消息标题、消息内容、送达时间这3项内容

 

 

  • 通知栏消息提醒,检查消息提醒的频率是否和需求设计一致
  • 通知栏消息提醒,检查消息显示的标题/内容/时间等是否和需求一致
  • 点击通知栏消息提醒,检查跳转的目标位置是否和需求一致,标记消息列表该消息是否显示为已读
  • 消息推送对象,检查消息推送的对象是否正确
  • 消息推送时间,检查消息推送的时间是否和需求一致
  • 系统通知权限,检查系统通知权限的设置是否和实际情况一

9-iOS的功能键测试

iOS APP应用内涉及最多的功能键为:Home键,音量键,锁屏键,关机键等

Home键:

  • 打开APP,点击Home键,检查APP是否切换到后台运行,检查APP后台运行的相关功能是否正常(如音乐播放)

音量键:

  • 打开APP,打开声音相关功能,物理调节音量键,检查声音是否会随物理调节变大变小
  • 打开APP,打开声音相关功能,系统声音设为静音,检查声音是否为静音

锁屏键:

  • 打开APP,锁屏,检查APP后台运行的相关功能是否正常(如音乐播放)
  • 打开APP,锁屏,解锁,检查APP运行是否正常

关机键:

  • 打开APP,关机,再开机,再打开APP,检查APP功能是否正常(特别是关机前正在付款等操作)

 

10-iOS的手势测试

  • 从屏幕左侧边缘向右滑动
  • 在屏幕上向左滑动
  • 从屏幕顶部向下滑动
  • 从屏幕底部向上滑动
  • 按住屏幕向下滑动
  • 在图片上双击
  • 按住图片下滑
  • 2根手指头分开和聚拢
  • 2根手指头按住屏幕旋转
  • 3根手指上滑(使用较少)
  • 4根手指上下/左右滑动(iPad)
  • 5根手指上下左右滑动(iPad)
  • 摇动手机
  • 长按屏幕

 

2020-03-31 16:53:22 u010090644 阅读数 140
  • 网络应用服务器(五)

    通过本课程的学习,学员从TCP/IP UDP Socket基础概念,到网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解。大量的实际项目,代码的学习,让学员掌握一个类似无人机,...

    221人学习 徐朋
    免费试看

北京时间2019年3月14日Google正式对外发布Android Q Beta 1及预览版SDK,这意味着安卓开发者们又即将迎来一年一度的新版本适配工作了。Android Q 为开发者们带来了许多新功能,如折叠屏增强项、新网络连接 API、全新的媒体解码器、摄像头新功能、NNAPI 扩展、Vulkan 1.1 图形支持 等等。

1.加权限

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> 
<uses-permission android:name="android.permission.CAMERA" />         
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
 

2.修改编译版本及目标版本

compileSdkVersion 29 (28+)

targetSdkVersion 29(28+)

 

3.选择相册图片时出现权限问题

application标签下添加

android:requestLegacyExternalStorage =“true”

4. 获取文件夹路径

String savePAth = Environment.getExternalStorageDirectory() + “/DownFile/”;

上面方法要换成下面的 否则获取会失败
String savePAth = getExternalCacheDir()+"/DownFile/";

 

5. Android Q 行为变更:所有应用

官方文档将这一部分内容独立于Q 行为变更:所有应用来介绍,是因为这一部分内容庞大且重要,其中最大的更新就是用户隐私权限变更。具体变更的权限如下:

权限 受影响应用 如何启用(影响范围)
存储权限 访问和共享外部存储设备中的文件的应用 adb shell sm set-isolated-storage on(下文详述)
定位权限 在后台时请求访问用户位置信息的应用 这种权限策略在 Android Q 上始终处于启用状态
从后台启动 Activity 不需要用户互动就启动 Activity 的应用 关闭允许系统执行后台活动开发者选项即可启用限制
设备标识符(deviceId) 访问设备序列号或 IMEI 的应用 在搭载 Android Q 的设备上安装应用
无线扫描权限 使用 WLAN API 和 Bluetooth API 的应用 以 Android Q 为目标平台

从后台启动Activity权限和无线扫描权限两种权限的变更影响较少 ,本文就不做介绍,详细可以查看请查阅官方文档:https://developer.android.com/preview/privacy/background-activity-starts
从后台启动Activity权限变更仅针对与用户毫无交互就启动一个Activity的情况,(比如微信登陆授权)。

本文将重点讲述存储权限,定位权限和设备标识符三种权限的变更与适配。

1.用户存储权限的变更

Android Q 在外部存储设备中为每个应用提供了一个“隔离存储沙盒”(例如 /sdcard)。任何其他应用都无法直接访问您应用的沙盒文件。由于文件是您应用的私有文件,因此您不再需要任何权限即可在外部存储设备中访问和保存自己的文件。此变更可让您更轻松地保证用户文件的隐私性,并有助于减少应用所需的权限数量。
谷歌官方推荐应用在沙盒内存储文件的地址为Context.getExternalFilesDir()下的文件夹。比如要存储一张图片,则应放在Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)中。

以下将按访问的目标文件的地址介绍如何适配:

  1. 访问自己文件:Q中用更精细的媒体特定权限替换并取消了 READ_EXTERNAL_STORAGE和 WRITE_EXTERNAL_STORAGE权限,并且无需特定权限,应用即可访问自己沙盒中的文件。

  2. 访问系统媒体文件:Q中引入了一个新定义媒体文件的共享集合,如果要访问沙盒外的媒体共享文件,比如照片,音乐,视频等,需要申请新的媒体权限:READ_MEDIA_IMAGES,READ_MEDIA_VIDEO,READ_MEDIA_AUDIO,申请方法同原来的存储权限。

  3. 访问系统下载文件:对于系统下载文件夹的访问,暂时没做限制,但是,要访问其中其他应用的文件,必须允许用户使用系统的文件选择器应用来选择文件。

  4. 访问其他应用沙盒文件:如果你的应用需要使用其他应用在沙盒内创建的文件,请点击使用其他应用的文件,本文不做介绍。

所以请判断当应用运行在Q平台上时,取消对READ_EXTERNAL_STORAGE和 WRITE_EXTERNAL_STORAGE两个权限的申请。并替换为新的媒体特定权限。

当满足以下每个条件时,将开启兼容模式,即不开启Q设备中的存储权限改动:

  1. 应用targetSDK<=P。
  2. 应用安装在从 Android P 升级到 Android Q 的设备上。

当应用重新安装(更新)时,不会重新开启兼容模式,存储权限改动将生效。
所以按官方文档所说,无论targetSDK是否为Q,必须对应用进行存储权限改动的适配。
在测试中,当targetSDK<=P,在Q Beat1版上申请两个旧权限时会自动改成申请三个新权限,不会影响应用正常使用,但当targetSDK==Q时,申请旧权限将失败并影响应用正常使用。

2.用户的定位权限的变更

为了让用户更好地控制应用对位置信息的访问权限,Android Q 引入了新的位置权限 ACCESS_BACKGROUND_LOCATION

与现有的 ACCESS_FINE_LOCATION和 ACCESS_COARSE_LOCATION权限不同,新权限仅会影响应用在后台运行时对位置信息的访问权。除非应用的某个 Activity 可见或应用正在运行前台服务,否则应用将被视为在后台运行。

与iOS系统一样,Q中也加入了后台位置权限ACCESS_BACKGROUND_LOCATION,如果应用需要在后台时也获得用户位置(比如滴滴),就需要动态申请ACCESS_BACKGROUND_LOCATION权限。

当然如果不需要的话,应用就无需任何改动,且谷歌会按照应用的targetSDK作出不同处理:
targetSDK <= P 应用如果请求了ACCESS_FINE_LOCATION或 ACCESS_COARSE_LOCATION权限,Q设备会自动帮你申请ACCESS_BACKGROUND_LOCATION权限。

3.设备唯一标识符的变更

从 Android Q 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE签名权限才能访问设备的不可重置标识符(包含 IMEI 和序列号)。
如果您的应用没有该权限,但您仍尝试查询标识符的相关信息,会返回空值或报错。
设备唯一标识符需要特别注意,原来的READ_PHONE_STATE权限已经不能获得IMEI和序列。

如果想在Q设备上通过使用以下代码获取设备的ID

((TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()
  • 1

则执行以上代码会返回空值(targetSDK<=P)或者报错(targetSDK==Q)。且官方所说的READ_PRIVILEGED_PHONE_STATE权限只提供给系统app,所以这个方法行不通了。

谷歌官方给予了设备唯一ID最佳做法,但是此方法给出的ID可变,可以按照具体需求具体解决。本文给出一个不变和基本不重复的UUID方法:

public static String getUUID() {
    String serial = null;
    String m_szDevIDShort = "35" +
        Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +
        Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +
        Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +
        Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +
        Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +
        Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +
        Build.USER.length() % 10; //13 位

    try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                serial = android.os.Build.getSerial();
            } else {
                serial = Build.SERIAL;
            }
            //API>=9 使用serial号
            return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
        } catch (Exception exception) {
            //serial需要一个初始化
            serial = "serial"; // 随便一个初始化
      }
    //使用硬件信息拼凑出来的15位号码
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

虽然由于唯一标识符权限的更改会导致android.os.Build.getSerial()返回unknown,但是由于m_szDevIDShort是由硬件信息拼出来的,所以仍然保证了UUID的唯一性和持久性。
测试输出结果如下
在这里插入图片描述

经测试上述方法完全相同的手机有可能重复,网上还有其他方案比如androidID,但是androidID可能由于机型原因返回null,所以个人认为两种方法半斤八两。设备ID的获取一个版本比一个版本艰难,如果有好的方法欢迎指出。

4.关于minSDK警告

在 Android Q 中,当用户首次运行以 Android 6.0(API 级别 23)以下的版本为目标平台的任何应用时,Android平台会向用户发出警告。

如果此应用要求用户授予权限,则系统会先向用户提供调整应用权限的机会,然后才会允许此应用首次运行。


6. Android Q 行为变更:以 Android Q 为目标平台的应用

非 SDK 接口限制

非SDK接口限制在Android P中就已提出,但是在Q中,被限制的接口的分类有较大变化。

非SDK接口介绍

为了确保应用稳定性和兼容性,Android 平台开始限制您的应用可在 Android 9(API 级别 28)中使用哪些非 SDK 接口。Android Q 包含更新后的受限非 SDK 接口列表(基于与 Android 开发者之间的协作以及最新的内部测试)。
非SDK接口限制就是某些SDK中的私用方法,如private方法,你通过Java反射等方法获取并调用了,那么这些调用将在target>=P或target>=Q的设备上被限制使用,当你使用了这些方法后,会报错

获取方法 报错信息
Dalvik instruction referencing a field NoSuchFieldError thrown
Dalvik instruction referencing a method NoSuchMethodError thrown
Reflection via Class.getDeclaredField() or Class.getField() NoSuchFieldException thrown
Reflection via Class.getDeclaredMethod(), Class.getMethod() NoSuchMethodException thrown
Reflection via Class.getDeclaredFields(), Class.getFields() Non-SDK members not in results
Reflection via Class.getDeclaredMethods(), Class.getMethods() Non-SDK members not in results
JNI via env->GetFieldID() NULL returned,NoSuchFieldError thrown
JNI via env->GetMethodID() NULL returned,NoSuchMethodError thrown

非SDK接口查找

如果您不确定自己的应用是否使用了非 SDK 接口,则可以测试该应用进行确认。当你调用了非SDK接口时,会有类似Accessing hidden XXX的日志:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
  • 1

但是一个大项目到底哪里使用了这些方法,靠review代码和看日志肯定是不现实的,谷歌官方也提供了官方检查器veridex用来检测一个apk中哪里使用了非SDK接口。veridex下载: https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat
其中有windows,linux和mac版本,对应下载即可。下载解压后命令行cd到veridex目录下使用./appcompat.sh --dex-file=Q.apk即可自动扫描。Q.apk为包的绝对路径,如果包与veridex在相同目录下直接输入包文件名即可。扫描结果分为两部分,一部分为被调用的非SDK接口的位置,另一部分为非SDK接口数量统计。

非SDK接口适配

如果您的应用依赖于非 SDK 接口,则应该开始计划迁移到 SDK 替代方案。如果您无法为应用中的某项功能找到使用非 SDK 接口的替代方案,则应该请求新的公共 API。

官方要求targetSDK>=P的应用不使用这些方法,并寻找其他的公共API去替代这些非SDK接口,如果找不到,则可以向谷歌申请,请求一个新的公共API: https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces#feature-request

项目中使用非SDK接口大概率有以下两种情况:

  1. 在自定义View的过程中为了方便,使用反射修改某个参数。
  2. 三方SDK中使用了非SDK接口(这种情况比较多)。

第一种是好解决的,毕竟是我们自己写的代码。第二种就头疼了,只能更新到最新的三方SDK版本,或者提工单、换库(也是整个适配过程中工作量最庞大的部分)。


7. Android项目升级遇到的问题

模拟器X86,项目中SO库为v7

  • 找到so库源代码,编译成x86
  • 如果so库只是某个功能点使用,对APP整体没大影响,就可以屏蔽特定so库功能或略过测试
  • 如果so库是项目核心库必须加载,也可使用腾讯云测,上面有谷歌亲儿子Q版本。腾讯云测有adb远程连接调试功能(我没成功过)。adb连不上也没关系,直接安装就行,云测上也可以直接看日志。
  • 至于inter的houdini我尝试研究过,理论上能安装在x86模拟器上让它编译v7的so库,但是由于关于houdini的介绍比较少也比较旧,建议大家时间不充裕的话就别研究了。

Requires development platform Q but this is a release platform.

由于目前Q是preview版,所以targetSDK==Q 的应用只能在Q设备上跑。

INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2

这个错误是由于打包压缩so库时造成的,具体原因可见:https://issuetracker.google.com/issues/37045367
在AndroidManifest.xml的application节点下加入android:extractNativeLibs="true"
可能有人加了上面代码还是不行,在app/build.gradle中的defaultConfig节点下加入

packagingOptions{ 
      doNotStrip "/armeabi/.so" doNotStrip "/armeabi-v7a/.so" doNotStrip "/x86/.so" }
  • 1
  • 2

Didn’t find class “org.apache.http.client.methods.HttpPost"

在AndroidManifest.xml的application节点下加入

<uses-library android:name="org.apache.http.legacy" android:required="false"/>
  • 1

如果你的项目没有适配过android O或P,那么你需要注意

android O的读取已安装应用权限(对应用内自动更新有影响)
android P的默认禁止访问http的API

 

 

本文的参考文档:

Android Q Beta开发者文档链接::https://developer.android.com/preview

Android Q Beta镜像下载链接:https://developer.android.com/preview/download

Android Q Beta 发布 blog:https://android-developers.googleblog.com/2019/03/introducing-android-q-beta.html

非SDK接口:https://juejin.im/post/5afe50eef265da0b70262463
 

2019-04-18 12:02:29 weitao_666 阅读数 21987
  • 网络应用服务器(五)

    通过本课程的学习,学员从TCP/IP UDP Socket基础概念,到网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解。大量的实际项目,代码的学习,让学员掌握一个类似无人机,...

    221人学习 徐朋
    免费试看

北京时间2019年3月14日Google正式对外发布Android Q Beta 1及预览版SDK,这意味着安卓开发者们又即将迎来一年一度的新版本适配工作了。Android Q 为开发者们带来了许多新功能,如折叠屏增强项、新网络连接 API、全新的媒体解码器、摄像头新功能、NNAPI 扩展、Vulkan 1.1 图形支持等等。2019/4  Beta2版本发布 ,5月份将会正式发布,本文将带大家对Android Q变更和新特性的详细解读。

还有一点值得Android开发者注意的事件,华为应用市场在3.26日发布了一则公告,要求华为市场上的App在2019年5月底前完成Android Q版本适配工作并自检通过,针对未适配或在Android Q版本体验欠佳的应用,华为应用市场将在Android Q版本机型上采取下架、不推荐更新或屏蔽策略。这一点还需要所有开发者注意了。以下是公告截图:

 同时华为4.2号的公告也需要开发者注意了:

自2019年5月1日起,华为应用市场新上架应用应基于Android 8.0 (API等级26,即targetSdkVersion大于等于26)及以上开发。自2019年8月1日起,现有应用的更新应基于Android 8.0 (API等级26,即targetSdkVersion大于等于26)及以上开发。

2019年5月1日后,未达到要求的新应用,华为应用市场将拒绝上架。2019年8月1日后,未达到要求的现有应用,华为应用市场将拒绝更新。如您的应用API等级小于26,请尽快完成应用的升级改造。

本文将从三个角度介绍Android Q的重要部分的适配问题,也是大家开发适配过程中大概率会遇到的问题:

  1. Android Q 行为变更:所有应用 (不管targetSdk是多少,对所有跑在Q设备上的应用均有影响)

  2. Android Q 行为变更:以 Android Q 为目标平台的应用(targetSDK == Q 才有影响)

  3. 项目升级遇到的问题

 一、Android Q 行为变更:所有应用

官方文档将这一部分内容独立于Q 行为变更:所有应用来介绍,是因为这一部分内容庞大且重要,其中最大的更新就是用户隐私权限变更。具体变更的权限如下:

              权限                       受影响应用                 如何启用(影响范围)
存储权限 访问和共享外部存储设备中的文件的应用 adb shell sm set-isolated-storage on(下文详述)
定位权限 在后台时请求访问用户位置信息的应用 这种权限策略在 Android Q 上始终处于启用状态
从后台启动 Activity 不需要用户互动就启动 Activity 的应用 关闭允许系统执行后台活动开发者选项即可启用限制
设备标识符(deviceId) 访问设备序列号或 IMEI 的应用 在搭载 Android Q 的设备上安装应用
无线扫描权限 使用 WLAN API 和 Bluetooth API 的应用 以 Android Q 为目标平台

从后台启动Activity权限和无线扫描权限两种权限的变更影响较少 ,本文就不做介绍,详细可以查看请查阅官方文档:

https://developer.android.com/preview/privacy/background-activity-starts

从后台启动Activity权限变更仅针对与用户毫无交互就启动一个Activity的情况,(比如微信登陆授权)。

本文将重点讲述存储权限,定位权限和设备标识符三种权限的变更与适配。

1.用户存储权限的变更

Android Q 在外部存储设备中为每个应用提供了一个“隔离存储沙盒”(例如 /sdcard)。任何其他应用都无法直接访问您应用的沙盒文件。由于文件是您应用的私有文件,因此您不再需要任何权限即可在外部存储设备中访问和保存自己的文件。此变更可让您更轻松地保证用户文件的隐私性,并有助于减少应用所需的权限数量。

沙盒,简单而言就是应用专属文件夹,并且访问这个文件夹无需权限。谷歌官方推荐应用在沙盒内存储文件的地址为Context.getExternalFilesDir()下的文件夹。比如要存储一张图片,则应放在Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)中

以下将按访问的目标文件的地址介绍如何适配。

1. 访问自己文件:Q中用更精细的媒体特定权限替换并取消了 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE权限,并且无需特定权限,应用即可访问自己沙盒中的文件。

2. 访问系统媒体文件:Q中引入了一个新定义媒体文件的共享集合,如果要访问沙盒外的媒体共享文件,比如照片,音乐,视频等,需要申请新的媒体权限:READ_MEDIA_IMAGES,READ_MEDIA_VIDEO,READ_MEDIA_AUDIO,申请方法同原来的存储权限。

3. 访问系统下载文件:对于系统下载文件夹的访问,暂时没做限制,但是,要访问其中其他应用的文件,必须允许用户使用系统的文件选择器应用来选择文件。

4. 访问其他应用沙盒文件:如果你的应用需要使用其他应用在沙盒内创建的文件,请点击使用其他应用的文件,本文不做介绍。

所以请判断当应用运行在Q平台上时,取消对READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE两个权限的申请。并替换为新的媒体特定权限。

当满足以下每个条件时,将开启兼容模式,即不开启Q设备中的存储权限改动:

  1. 应用targetSDK<=P。

  2. 应用安装在从 Android P 升级到 Android Q 的设备上。

但是当应用重新安装(更新)时,不会重新开启兼容模式,存储权限改动将生效。

所以按官方文档所说,无论targetSDK是否为Q,必须对应用进行存储权限改动的适配。

在测试中,当targetSDK<=P,在Q Beat1版上申请两个旧权限时会自动改成申请三个新权限,不会影响应用正常使用,但当targetSDK==Q时,申请旧权限将失败并影响应用正常使用。

2.用户的定位权限的变更

为了让用户更好地控制应用对位置信息的访问权限,Android Q 引入了新的位置权限 ACCESS_BACKGROUND_LOCATION

与现有的 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 权限不同,新权限仅会影响应用在后台运行时对位置信息的访问权。除非应用的某个 Activity 可见或应用正在运行前台服务,否则应用将被视为在后台运行。

与iOS系统一样,Q中也加入了后台位置权限ACCESS_BACKGROUND_LOCATION,如果应用需要在后台时也获得用户位置(比如滴滴),就需要动态申请ACCESS_BACKGROUND_LOCATION权限。

当然如果不需要的话,应用就无需任何改动,且谷歌会按照应用的targetSDK作出不同处理:

targetSDK <= P 应用如果请求了ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION权限,Q设备会自动帮你申请ACCESS_BACKGROUND_LOCATION权限

3.设备唯一标识符的变更

从 Android Q 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 签名权限才能访问设备的不可重置标识符(包含 IMEI 和序列号)。

许多用例不需要不可重置的设备标识符。如果您的应用没有该权限,但您仍尝试查询标识符的相关信息。会返回空值或报错。

设备唯一标识符需要特别注意,原来的READ_PHONE_STATE权限已经不能获得IMEI和序列号,如果想在Q设备上通过使用以下代码获取设备的ID

((TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()

则执行以上代码会返回空值(targetSDK<=P)或者报错(targetSDK==Q)。且官方所说的READ_PRIVILEGED_PHONE_STATE权限只提供给系统app,所以这个方法行不通了

谷歌官方给予了设备唯一ID最佳做法,但是此方法给出的ID可变,可以按照具体需求具体解决。本文给出一个不变和基本不重复的UUID方法。

public static String getUUID() {

  String serial = null;

  String m_szDevIDShort = "35" +
        Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

        Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +

        Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +

        Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +

        Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +

        Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +

        Build.USER.length() % 10; //13 位

  try {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        serial = android.os.Build.getSerial();
      } else {
        serial = Build.SERIAL;
      }
      //API>=9 使用serial号
      return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    } catch (Exception exception) {
    //serial需要一个初始化
    serial = "serial"; // 随便一个初始化
  }
    //使用硬件信息拼凑出来的15位号码
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

虽然由于唯一标识符权限的更改会导致android.os.Build.getSerial()返回unknown,但是由于m_szDevIDShort是由硬件信息拼出来的,所以仍然保证了UUID的唯一性和持久性。

经测试上述方法完全相同的手机有可能重复,网上还有其他方案比如androidID,但是androidID可能由于机型原因返回null,所以个人任务两种方法半斤八两。设备ID的获取一个版本比一个版本艰难,如果有好的方法欢迎指出。

4.关于minSDK警告

在 Android Q 中,当用户首次运行以 Android 6.0(API 级别 23)以下的版本为目标平台的任何应用时,Android平台会向用户发出警告。

如果此应用要求用户授予权限,则系统会先向用户提供调整应用权限的机会,然后才会允许此应用首次运行。

谷歌要求运行在Q设备上的应用targetSDK>=23,不然会向用户发出警告。

二、Android Q 行为变更:以 Android Q 为目标平台的应用

非 SDK 接口限制

非SDK接口限制在Android P中就已提出,但是在Q中,被限制的接口的分类有较大变化。

非SDK接口介绍

为了确保应用稳定性和兼容性,Android 平台开始限制您的应用可在 Android 9(API 级别 28)中使用哪些非 SDK 接口。Android Q 包含更新后的受限非 SDK 接口列表(基于与 Android 开发者之间的协作以及最新的内部测试)。

非SDK接口限制就是某些SDK中的私用方法,如private方法,你通过Java反射等方法获取并调用了。那么这些调用将在target>=P或target>=Q的设备上被限制使用,当你使用了这些方法后,会报错:

                                 获取方法                            报错信息
Dalvik instruction referencing a field NoSuchFieldError thrown
Dalvik instruction referencing a method NoSuchMethodError thrown
Reflection via Class.getDeclaredField() or Class.getField() NoSuchFieldException thrown
Reflection via Class.getDeclaredMethod(), Class.getMethod() NoSuchMethodException thrown
Reflection via Class.getDeclaredFields(), Class.getFields() Non-SDK members not in results
Reflection via Class.getDeclaredMethods(), Class.getMethods() Non-SDK members not in results
JNI via env->GetFieldID() NULL returned, NoSuchFieldError thrown
JNI via env->GetMethodID() NULL returned, NoSuchMethodError thrown

非SDK接口查找

如果您不确定自己的应用是否使用了非 SDK 接口,则可以测试该应用进行确认。当你调用了非SDK接口时,会有类似Accessing hidden XXX的日志:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

但是一个大项目到底哪里使用了这些方法,靠review代码和看日志肯定是不现实的,谷歌官方也提供了官方检查器veridex用来检测一个apk中哪里使用了非SDK接口。veridex下载。https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat,其中有windows,linux和mac版本,对应下载即可。下载解压后命令行cd到veridex目录下使用./appcompat.sh --dex-file=Q.apk即可自动扫描。Q.apk为包的绝对路径,如果包与veridex在相同目录下直接输入包文件名即可。扫描结果分为两部分,一部分为被调用的非SDK接口的位置,另一部分为非SDK接口数量统计。

非SDK接口适配

如果您的应用依赖于非 SDK 接口,则应该开始计划迁移到 SDK 替代方案。如果您无法为应用中的某项功能找到使用非 SDK 接口的替代方案,则应该请求新的公共 API。

官方要求targetSDK>=P的应用不使用这些方法,并寻找其他的公共API去替代这些非SDK接口,如果找不到,则可以向谷歌申请,请求一个新的公共API https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces#feature-request (一般不需要)。

就我个人扫描并定位的结果来看,项目中使用非SDK接口大概率有以下两种情况:

  1. 在自定义View的过程中为了方便,使用反射修改某个参数。

  2. 三方SDK中使用了非SDK接口(这种情况比较多)。

第一种是好解决的,毕竟是我们自己写的代码。第二种就头疼了,只能更新到最新的三方SDK版本,或者提工单、换库(也是整个适配过程中工作量最庞大的部分)。

 三、Android项目升级遇到的问题

模拟器X86,项目中SO库为v7

  • 找到so库源代码,编译成x86

  • 如果so库只是某个功能点使用,对APP整体没大影响,就可以屏蔽特定so库功能或略过测试

  • 如果so库是项目核心库必须加载,也可使用腾讯云测,上面有谷歌亲儿子Q版本。腾讯云测有adb远程连接调试功能(我没成功过)。adb连不上也没关系,直接安装就行,云测上也可以直接看日志。

  • 至于inter的houdini我尝试研究过,理论上能安装在x86模拟器上让它编译v7的so库,但是由于关于houdini的介绍比较少也比较旧,建议大家时间不充裕的话就别研究了。

Requires development platform Q but this is a release platform.

由于目前Q是preview版,所以targetSDK==Q 的应用只能在Q设备上跑。

INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2

这个错误是由于打包压缩so库时造成的,具体原因可见:https://issuetracker.google.com/issues/37045367

在AndroidManifest.xml的application节点下加入android:extractNativeLibs="true"

可能有人加了上面代码还是不行,在app/build.gradle中的defaultConfig节点下加入

packagingOptions{ 
      doNotStrip "/armeabi/.so" doNotStrip "/armeabi-v7a/.so" doNotStrip "/x86/.so" }

Didn't find class “org.apache.http.client.methods.HttpPost"

 

在AndroidManifest.xml的application节点下加入

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

如果你的项目没有适配过android O或P,那么你需要注意:

  1. android O的读取已安装应用权限(对应用内自动更新有影响)

  2. android P的默认禁止访问http的API

这两个版本的适配问题本文就不做详述,大家可以查看网上详细的介绍。

以上就是Android Q(10.0)版本新特性和兼容性适配,中间会遇到各种各样的坑,还是建议详细查看Google的官方文档。

本文的参考文档:

Android Q Beta开发者文档链接::https://developer.android.com/preview

Android Q Beta镜像下载链接:https://developer.android.com/preview/download

Android Q Beta 发布 blog:https://android-developers.googleblog.com/2019/03/introducing-android-q-beta.html

非SDK接口:https://juejin.im/post/5afe50eef265da0b70262463

 

2019-07-09 10:48:47 weixin_40611659 阅读数 88185
  • 网络应用服务器(五)

    通过本课程的学习,学员从TCP/IP UDP Socket基础概念,到网络编程接口介绍,POSIX线程封装,私有协议定义,开发,服务器模型,客户端编程等详细实战讲解。大量的实际项目,代码的学习,让学员掌握一个类似无人机,...

    221人学习 徐朋
    免费试看

本文将从三个角度介绍Android Q的部分适配问题,也是大家开发适配过程中大概率会遇到的问题:

  • Q 行为变更:所有应用 (不管targetSdk是多少,对所有跑在Q设备上的应用均有影响)
  • Q 行为变更:以 Android Q 为目标平台的应用(targetSDK == Q 才有影响)
  • 项目升级遇到的问题

至于Q的新功能及SDK,项目中并没有涉及,故暂不介绍,只放出链接AndroidQ新API及功能。

https://developer.android.com/preview/features

Q行为变更:所有应用

用户隐私权限变更

AndroidQ引入了大量更改和限制以增强对用户隐私的保护。

官方文档将这一部分内容独立于Q 行为变更:所有应用来介绍,是因为这一部分内容庞大且重要,个人认为Q的最大更新就是用户隐私权限变更。具体变更的权限如下:

权限;   受影响应用;   如何启用(影响范围)

 

 

 

存储权限

访问和共享外部存储设备中的文件的应用

adb shell sm set-isolated-storage on(下文详述)

定位权限

在后台时请求访问用户位置信息的应用

这种权限策略在 Android Q 上始终处于启用状态

从后台启动 Activity

不需要用户互动就启动 Activity 的应用

关闭允许系统执行后台活动开发者选项即可启用限制

设备标识符(deviceId)

访问设备序列号或 IMEI 的应用

在搭载 Android Q 的设备上安装应用

无线扫描权限

使用 WLAN API 和 Bluetooth API 的应用

以 Android Q 为目标平台

 

 

 因为从后台启动Activity权限和无线扫描权限两种权限的变更影响较少。本文不作详述,如有涉及请查阅官方文档。

https://developer.android.com/preview/privacy/background-activity-starts

从后台启动Activity权限变更仅针对与用户毫无交互就启动一个Activity的情况,(比如微信登陆授权)

以下会着重介绍存储权限,定位权限和设备标识符三种权限的变更与适配。

存储权限

Android Q 在外部存储设备中为每个应用提供了一个“隔离存储沙盒”(例如 /sdcard)。任何其他应用都无法直接访问您应用的沙盒文件。由于文件是您应用的私有文件,因此您不再需要任何权限即可在外部存储设备中访问和保存自己的文件。此变更可让您更轻松地保证用户文件的隐私性,并有助于减少应用所需的权限数量。

沙盒,简单而言就是应用专属文件夹,并且访问这个文件夹无需权限。谷歌官方推荐应用在沙盒内存储文件的地址为Context.getExternalFilesDir()下的文件夹。比如要存储一张图片,则应放在Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)中。

以下将按访问的目标文件的地址介绍如何适配。

1. 访问自己文件:Q中用更精细的媒体特定权限替换并取消了 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE权限,并且无需特定权限,应用即可访问自己沙盒中的文件。

2. 访问系统媒体文件:Q中引入了一个新定义媒体文件的共享集合,如果要访问沙盒外的媒体共享文件,比如照片,音乐,视频等,需要申请新的媒体权限:READ_MEDIA_IMAGES,READ_MEDIA_VIDEO,READ_MEDIA_AUDIO,申请方法同原来的存储权限。

3. 访问系统下载文件:对于系统下载文件夹的访问,暂时没做限制,但是,要访问其中其他应用的文件,必须允许用户使用系统的文件选择器应用来选择文件。

4. 访问其他应用沙盒文件:如果你的应用需要使用其他应用在沙盒内创建的文件,请点击使用其他应用的文件,本文不做介绍。

所以请判断当应用运行在Q平台上时,取消对READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE两个权限的申请。并替换为新的媒体特定权限。

关于存储权限的(如何启用)影响范围

模拟器

在Android Q Beat1中,谷歌暂未开放存储权限的改动。我们需要使用adb命令

adb shell sm set-isolated-storage on

来开启模拟器对于存储权限的变更来进行适配。

真机

当满足以下每个条件时,将开启兼容模式,即不开启Q设备中的存储权限改动:

  1. 应用targetSDK<=P。
  2. 应用安装在从 Android P 升级到 Android Q 的设备上。

但是当应用重新安装(更新)时,不会重新开启兼容模式,存储权限改动将生效。

所以按官方文档所说,无论targetSDK是否为Q,必须对应用进行存储权限改动的适配。

在我的测试中,当targetSDK<=P,在Q Beat1版上申请两个旧权限时会自动改成申请三个新权限,不会影响应用正常使用,但当targetSDK==Q时,申请旧权限将失败并影响应用正常使用。

定位权限

为了让用户更好地控制应用对位置信息的访问权限,Android Q 引入了新的位置权限 ACCESS_BACKGROUND_LOCATION。

与现有的 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 权限不同,新权限仅会影响应用在后台运行时对位置信息的访问权。除非应用的某个 Activity 可见或应用正在运行前台服务,否则应用将被视为在后台运行。

与iOS系统一样,Q中也加入了后台位置权限ACCESS_BACKGROUND_LOCATION,如果应用需要在后台时也获得用户位置(比如滴滴),就需要动态申请ACCESS_BACKGROUND_LOCATION权限。

当然如果不需要的话,应用就无需任何改动,且谷歌会按照应用的targetSDK作出不同处理:

targetSDK <= P 应用如果请求了ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION权限,Q设备会自动帮你申请ACCESS_BACKGROUND_LOCATION权限。

设备唯一标识符

从 Android Q 开始,应用必须具有 READ_PRIVILEGED_PHONE_STATE 签名权限才能访问设备的不可重置标识符(包含 IMEI 和序列号)。

许多用例不需要不可重置的设备标识符。如果您的应用没有该权限,但您仍尝试查询标识符的相关信息。会返回空值或报错。

设备唯一标识符需要特别注意,原来的READ_PHONE_STATE权限已经不能获得IMEI和序列号,如果想在Q设备上通过

((TelephonyManager) getActivity()      .getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()

获得设备ID,会返回空值(targetSDK<=P)或者报错(targetSDK==Q)。且官方所说的READ_PRIVILEGED_PHONE_STATE权限只提供给系统app,所以这个方法算是废了。

谷歌官方给予了设备唯一ID最佳做法,但是此方法给出的ID可变,可以按照具体需求具体解决。

本文给出一个不变和基本不重复的UUID方法。

public static String getUUID() {

String serial = null;

String m_szDevIDShort = "35" +
        Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

        Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +

        Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +

        Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +

        Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +

        Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +

        Build.USER.length() % 10; //13 位

try {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        serial = android.os.Build.getSerial();
    } else {
        serial = Build.SERIAL;
    }
    //API>=9 使用serial号
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
    //serial需要一个初始化
    serial = "serial"; // 随便一个初始化
}
    //使用硬件信息拼凑出来的15位号码
    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}

虽然由于唯一标识符权限的更改会导致android.os.Build.getSerial()返回unknown,但是由于m_szDevIDShort是由硬件信息拼出来的,所以仍然保证了UUID的唯一性和持久性。

经测试上述方法完全相同的手机有可能重复,网上还有其他方案比如androidID,但是androidID可能由于机型原因返回null,所以个人任务两种方法半斤八两。设备ID的获取一个版本比一个版本艰难,如果有好的方法欢迎指出。

minSDK警告

在 Android Q 中,当用户首次运行以 Android 6.0(API 级别 23)以下的版本为目标平台的任何应用时,Android平台会向用户发出警告。

如果此应用要求用户授予权限,则系统会先向用户提供调整应用权限的机会,然后才会允许此应用首次运行。

谷歌要求运行在Q设备上的应用targetSDK>=23,不然会向用户发出警告。

3.Q 行为变更:以 Android Q 为目标平台的应用

非 SDK 接口限制

非SDK接口限制在Android P中就已提出,但是在Q中,被限制的接口的分类有较大变化。

非SDK接口介绍

为了确保应用稳定性和兼容性,Android 平台开始限制您的应用可在 Android 9(API 级别 28)中使用哪些非 SDK 接口。Android Q 包含更新后的受限非 SDK 接口列表(基于与 Android 开发者之间的协作以及最新的内部测试)。

非SDK接口限制就是某些SDK中的私用方法,如private方法,你通过Java反射等方法获取并调用了。那么这些调用将在target>=P或target>=Q的设备上被限制使用,当你使用了这些方法后,会报错:

获取方法

报错信息

 

 

Dalvik instruction referencing a field

NoSuchFieldError thrown

Dalvik instruction referencing a method

NoSuchMethodError thrown

Reflection via Class.getDeclaredField() or Class.getField()

NoSuchFieldException thrown

Reflection via Class.getDeclaredMethod(), Class.getMethod()

NoSuchMethodException thrown

Reflection via Class.getDeclaredFields(), Class.getFields()

Non-SDK members not in results

Reflection via Class.getDeclaredMethods(), Class.getMethods()

Non-SDK members not in results

JNI via env->GetFieldID()

NULL returned, NoSuchFieldError thrown

JNI via env->GetMethodID()

NULL returned, NoSuchMethodError thrown

非SDK接口查找

如果您不确定自己的应用是否使用了非 SDK 接口,则可以测试该应用进行确认。

当你调用了非SDK接口时,会有类似Accessing hidden XXX的日志:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

但是一个大项目到底哪里使用了这些方法,靠review代码和看日志肯定是不现实的,谷歌官方也提供了官方检查器veridex用来检测一个apk中哪里使用了非SDK接口。veridex下载。

https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat

其中有windows,linux和mac版本,对应下载即可。

下载解压后命令行cd到veridex目录下使用./appcompat.sh --dex-file=Q.apk即可自动扫描。Q.apk为包的绝对路径,如果包与veridex在相同目录下直接输入包文件名即可。

扫描结果分为两部分,一部分为被调用的非SDK接口的位置,另一部分为非SDK接口数量统计,例如:

  1. greylist: 灰名单,即当前版本仍能使用的非SDK接口,但在下一版本中可能变成被限制的非SDK接口
  2. blacklist:黑名单,使用了就会报错。也是我们项目中必须解决的非SDK接口
  3. greylist-max-o:在targetSDK<=O中能使用,但是在targetSDK>=P中被限制的非SDK接口
  4. greylist-max-p:在targetSDK<=P中能使用,但是在targetSDK>=Q中被限制的非SDK接口

所以从适配Q的角度出发,除了greylist我们可以暂时不解决以外,其余三种类型的非SDK接口需要我们进行适配。

非SDK接口适配

如果您的应用依赖于非 SDK 接口,则应该开始计划迁移到 SDK 替代方案。如果您无法为应用中的某项功能找到使用非 SDK 接口的替代方案,则应该请求新的公共 API。

官方要求targetSDK>=P的应用不使用这些方法,并寻找其他的公共API去替代这些非SDK接口,如果找不到,则可以向谷歌申请,请求一个新的公共API https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces#feature-request (一般不需要)。

就我个人扫描并定位的结果来看,项目中使用非SDK接口大概率有以下两种情况:

  1. 在自定义View的过程中为了方便,使用反射修改某个参数。
  2. 三方SDK中使用了非SDK接口(这种情况比较多)。

第一种是好解决的,毕竟是我们自己写的代码。

第二种就头疼了,只能更新到最新的三方SDK版本,或者提工单、换库(也是整个适配过程中工作量最庞大的部分)。

4.项目升级遇到的问题

模拟器X86,项目中SO库为v7

  • 找到so库源代码,编译成x86
  • 如果so库只是某个功能点使用,对APP整体没大影响,就可以屏蔽特定so库功能或略过测试
  • 如果so库是项目核心库必须加载,也可使用腾讯云测,上面有谷歌亲儿子Q版本。腾讯云测有adb远程连接调试功能(我没成功过)。adb连不上也没关系,直接安装就行,云测上也可以直接看日志。
  • 至于inter的houdini我尝试研究过,理论上能安装在x86模拟器上让它编译v7的so库,但是由于关于houdini的介绍比较少也比较旧,建议大家时间不充裕的话就别研究了。

Requires development platform Q but this is a release platform.

由于目前Q是preview版,所以targetSDK==Q 的应用只能在Q设备上跑。

INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2

这个错误是由于打包压缩so库时造成的,具体原因可见

https://issuetracker.google.com/issues/37045367

在AndroidManifest.xml的application节点下加入android:extractNativeLibs="true"

可能有人加了上面代码还是不行,在app/build.gradle中的defaultConfig节点下加入

packagingOptions{ 
      doNotStrip "/armeabi/.so" doNotStrip "/armeabi-v7a/.so" doNotStrip "/x86/.so" }

Didn't find class “org.apache.http.client.methods.HttpPost"

在AndroidManifest.xml的application节点下加入

<uses-library android:name="org.apache.http.legacy" android:required="false"/>

如果你的项目没有适配过android O或P,那么你需要注意:

  1. android O的读取已安装应用权限(对应用内自动更新有影响)
  2. android P的默认禁止访问http的API

这两个版本的适配问题本文就不做详述,网上有很多详细的介绍。

参考文献

官方文档

https://developer.android.com/preview

出处:云栖社区 https://cloud.tencent.com/developer/article/1437956

如果对您能有所帮助,请点个赞吧亲!!!