Android

A collection of 50 posts
Android

Retrofit、Volley、HttpClient比较

Retrofit作为现在大家用的最多HTTP请求框架,非常流行,Github上star 3w+。它为什么能超越Volley、HTTPClient能够一枝独秀呢?那先看看其他两个HTTP栈的实现。 HTTPClient Java界老牌HTTP栈实现,由Apache维护,它支持HTTP1.0/1.1、极其丰富的API来支持各种子协议,代码庞大臃肿也变成了它的缺点,虽然它的创建一开始是为了弥补Java SDK中java.net包HTTP请求的简单实现,Android在6.0以后彻底弃用了它,转而推荐使用HTTPURLConnection。 Volley 作为Google官方开源的一款HTTP栈,它支持切换HTTPURLConnection、HTTPClient底层协议栈的切换,同时提供了请求线程池、缓存的支持,刚一推出也是收获许多赞赏,但是它就像G家好多产品一样,几年一次的维护和有些bug都需要使用方去维护解决,都是开发者逐渐抛弃的原因。虽然从Volley开始,这些HTTP栈的实现都在逐渐向上层实现,因为不管是Android、iOS大部分App的网络交互都是Restful-API的实现,
3 min read
Android

SVG Path命令属性

Android从5.0开始支持SVG矢量图,通过Vector Asset工具将SVG文件转换VectorDrawable定义的XML文件中,在运行时inflate这个xml文件来绘制图层,这对于减小APK资源文件体积和避免混乱的分辨率支持上都有很好的效果,同时Android通过Support支持库的形式给予了低版本的支持。 Android上对SVG的支持是受限制的,仅支持SVG tiny1.2版本的属性和标签,而且不支持text标签。 path标签是SVG中最常用的标签,这其中最重要的属性就是d(command)属性,它标明这个路径的绘制起点、终点、中间路径关键点、两点之间是否为直线、弧线、贝塞尔曲线等等。 d(command)属性主要分几类: 起点 用M、m来表示,如M150,0 表示从path的起点, 从x-150,y=0的坐标起点开始绘制 终点 用Z、z来表示,无参数 表示path的终点,链接到path的起点,闭合path,然后结束绘制 直线 假设当前点坐标为(10,10) L、l表示直线线段,如L100,100,
4 min read
Chrome

Chromium Android工程迁移编译过程

本文从Chromium编译的中间产物入手深入分析、学习Chromium Android版本的工程化定制流程。初始工作依赖于Chromium的ninja、GYP构建系统,在构建完成后基于编译中间产物,迁入Android Studio作为新的构建工程,测试编译发布的过程。 注:这种编译过程除了资源文件外其他编译中间产物,都不可修改,不具备大规模定制化的可能性,仅作为熟悉编译过程和代码结构的学习、测试使用。 前提 Chromium代码结构、Android开发、Android Studio使用 编译Chromium 编译步骤可以参考Chromium团队的文章 [https://chromium.googlesource.com/chromium/src/+/master/docs/android_build_instructions.md] ,可以选择编译目标为chrome_public_apk、content_shell_apk,本文以chrome_public_apk为例。 编译结果APK 在以chrome_public_apk为编译目标后,在经历一段时间后编译完成,在out/**
5 min read
Android

Android共享热点IP问题引发的“血案”

今天一朋友问Android手机的Wi-Fi共享热点IP能不能修改,他那边一直是192.168.43. ,自己记得在设置里面没有这个选项,便回复了他不能修改。后来猜测Android源码可能为了刻意避开常用局域网路由器192.168.0/1/2. 段,特意设置的其他网段,但会不会存在与基站代理在一个网段后冲突自我协调的机制呢?(当然这个可能性很低,一般基站的代理服务器分配的都是10.*段的内网地址),既然有了这个问题,那索性看看源码怎么设置的。 涉水 首先想到的是到StackOverFlow上看看有没有相关问题,搜索得之, http://stackoverflow.com/a/31238229/4865380 确实有人提到修改Hotspot网关的问题,给出的具体源码是在WiFiStateMachine.java中硬编码了192.168.43.1这个网关地址,这就解释了为什么共享出去的IP地址都是192.168.43.*了。手机用户想修改它,duang然是不可能了。 挣扎 从AOSP的master中去查找上文提到的platform/framework/base/wifi/java/a
4 min read
Android

Android 物联网SDK

原文链接 [https://developer.android.com/things/sdk/index.html] 支持库 主要包含两方面的支持:外部器件 IO API、用户驱动API 外部器件 IO API实现了相关的工业标准协议和接口,可以让App与传感器和制动元件进行通信。支持的接口主要有:GPIO、PWM、I2C、SPI、UART。 https://developer.android.com/things/sdk/pio/index.html 用户驱动API扩展自Android framework的Service组件,它允许App注入硬件事件到framework层,其他的Apps就可以通过标准的Android API来访问这些事件信息。 https://developer.android.com/things/sdk/drivers/index.html 与AndroidOS相比的变更 应用变化
3 min read
Android

Android 物联网初探

Android OS作为现今智能手机操作系统的老大,对智能设备的流行起到重要作用,从手机、平板到TV、手表、汽车等等,无处不在,无所不包,已然是现实意义的便携式设备OS的代表,虽然不同的设备厂商各怀鬼胎、高度定制,但不可否认Android OS确实推动了产业的迅速发展。随着智能设备的微型化和物联网的发展,Android团队也为我们带来了在物联网领域的又一力作-Android Things。与Android Wear、Android Auto一样,Android Things同样承袭了不开源的路子,预计后续开源的可能性也比较低。 Google在物联网领域主要有两方面:Android Things、Weave。 Android Things(原名为“Brillo”)是基于Android OS面向终端设备的一套定制化OS,旨在为了解决异构SoC物联网设备、不同传感器的数据处理等提出的一套解决方案,开发者只需要关注上层应用级别的数据传输和处理,同时还支持自定义传感器等元件的驱动。 Weave主要解决物联网对于后端数据传输和设备交互的需求,通过Google 的基础设施来采集、传输、交换、分
4 min read
Android

Android Data Binding代码分析

Android团队推出Data Binding支持已经一年有余,但碍于项目已经在使用原始setXXX的方式,想要完全替换需要一定时间,一直没有进入todo list。最近在一个小demo中试验了一下。详细的开发示例不再赘述,可以参考Android Dev官网 [https://developer.android.com/topic/libraries/data-binding/index.html] 的代码示例,中文版可以参考简书的一篇比较新鲜的译文 [http://connorlin.github.io/2016/07/02/Android-Data-Binding-%E7%B3%BB%E5%88%97-%E4%B8%80-%E8%AF%A6%E7%BB%86%E4%BB%8B%E7%BB%8D%
4 min read
Android

Android 6.0 运行时权限实践要点

Android在6.0之后添加了新的权限管理模型,每个应用必须在原油的Manifest.xml声明的基础上增加运行时的权限申请才能进行相关API的调用,这对终端用户的隐私保护是一大利好,浏览一下国内的很多应用,一个很简单的APP也会申请Contact、Location、ID、SMS、 *History等权限。自从6.0之后App安装完成未启动前你就可以去应用设置中关闭没必要的权限。当然国内的很多定制ROM比如MIUI、EMUI等在之前android版本中已经定制了相关模型,但这一次是从API级别上标准化了这一设置,所有支持后续版本的APP都必须实现这一原则。 相关运行时权限申请开发过程,可通过Android官方网站浏览 [https://developer.android.com/training/permissions/requesting.html]。更多 Android权限相关 [https://developer.android.com/guide/topics/security/permissions.html]。 这里只说明了几个开发要点: 当前流行的运行时权限申请流
4 min read
App

健身派 大陆用户使用Google Fit (非root)

Google Location History在国内目前处于非可用状态,可能是由于地图拍照之类的问题,所以基于地理位置实时跟踪的Google Fit也就悲剧了。 网上修复或者绕过的各种路数是手机rooted,然后更改google play注册地欺骗Google通过,还有其他的比如SIM卡贴欺骗,总之的意思就是让Google以为你在国外开放Location History的地方。 手机如果被rooted使用的风险性会大大增加,不建议使用。除了通过Location History来记录健身,还可以通过Google Fit API来正常使用Google Fit。 Google Fit API内建了各种数据模型,比如步数统计、骑自行车、业余训练等等。 相关API详情参考 [https://developers.google.com/fit/overview#the_sensor_framework]。 这里我也写了一个App,可以提供这些功能,欢迎下载使用。 当然如上这些还是需要某项技能才能同步。
1 min read
Android

Android Studio编译NDK工程

由于现在的开发都是基于AS的,但是当前AS对NDK的支持还不是特别完善,再切换ADT略显别扭,简单根据NDK文档写了一个Gradle脚本,来调用NDK ENV来编译。 目前的脚本仅能实现对*.c的编译,对NativeActivity的支持还不是特别完善。 主要分为3个步骤: 1)NDK编译链环境检查 2)编译 3)迁移编译后so文件、清理文件夹 //新建NDK compile任务 task compileNDK << { // TAG String TAG = ":" + project.getProject().name + ":ndk:" // Check NDK environment Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) def ndkDir = properties.getProperty('ndk.dir') ​ if
1 min read
Android

Android Gradle相关浅析

开发环境:Mac OS(10.10)+Android Studio(1.0) Android Studio(下称“AS”)目前在安装包中已经集成了Gradle的编译运行时环境,安装完成后会在AS的gradle文件夹下。 在介绍Gradle前,先看一下AS创建工程与导入工程的过程分析: 1、AS create project: AS在创建new project时会根据$Android_SDK_HOME/tools/lib/templates/projects下的模版创建默认project,依次创建Intellij Project Structure、Launcher Icon以及AndroidMainfest.xml,同时拷贝gradle wrapper(settings.gradle、build.gradle、gradle wrapper文件夹、gradlew)环境,此时android project的结构已经有了,但是还没有包含Gradle运行时环境的定义,下一步就是将$
3 min read
Android

Android开发要点

1、自定义View如果作为ListView Item不要对View单独设置setClickable、setFocusable,如果设置后ListView的Selector会失效。 2、ListView Item中CardView如果设置cardElevation值,Item选中的ripple效果会被置为底部,造成UI效果不理想,在ListView中添加android:drawSelectorOnTop="true"将背景前置到顶部可以解决。 3、Android WebView如果HTML内容内嵌iframe此时通过shouldOverrideLoadingUrl方法不能捕获到iframe内部跳转的URL,此时需要调用shouldInterceptRequest()来捕获,这个方法不仅仅会捕获的URL跳转,对HTML内容的HTTP资源请求也会捕获,比如css、js等。 4、微信分享时出现“分享受限,由于hit push hold!!无法分享到微信”,原因是分享用的微信账号在其他手机登录,但是本机还没有退出登录,导致没有权限分享,重新进入微信并登录就OK
3 min read
Android

Android gradle 库工程多版本编译问题

android application project中对于debug、release类型不同的编译配置可以通过buildConfig文件实现分离,代码如下: debug { buildConfigField "String", "SUFFIX", "\"123\"" } ​ release { buildConfigField "String", "SUFFIX", "\"\"" } 但对于android library project(子module),目前的gradle plugin并不支持debug、release这样的编译类型,如果还是按照如上配置,默认release产生效果,debug被忽略。 android gradle文档是这样说的: For the rest, libraries behave the same as application projects. They have build types and product flavors, and can potentially generate more than one
1 min read
Android

微信扫码直接跳转前台实现

微信在Mac、PC、浏览器都实现了扫码登录的功能,过程如下: 当用户已经使用过一次扫码登录后可以直接点击“Log in via My Phone”,微信服务器会向App发送通知,调用确认界面,用户点击“确认在PC上登录微信”,App向服务器确认请求,服务器响应Mac、PC的登录请求成功。 其中微信Android客户端的一个环节为抢占式弹出确认界面,这个过程参与实现的几个要点:Service、PendingIntent,但是还有一个关键点就是如果微信App 处于前台如何抢占式的将确认界面置为task stack的最上面?如果此Activity如果已经位于stack的任意位置如何保证single in task而且还能置于栈顶? 最近在看Android官方例子才发现Intent其实已经提供了相关的Flag来解答这个疑问。 public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 0X00020000; Intent类中提供这样一个Flag,官方解释它的作用:当某个Intent增加这个Flag会导致将要运行的Activity从
2 min read
Android

Android View背景与Shape

某个view需要有点击、焦点、选中的背景反馈是一般使用selector设置各个状态时的背景色。每一个item设置纯色一般比较少见,比较多的是使用bitmap或者shape,如果是bitmap很好理解,状态变化时直接切换渲染的图片就OK,但比较好的方式是用shape自定义图形。 这样做有两点好处,第一能够减小APK包的大小,现在的App很多已经是20+M,对用户的更新造成诸多不便,所以保持App大小很重要,其次能够避免图片平铺拉伸的处理,虽然.9图片从一定程度上保证了屏幕尺寸的兼容。 Shape使用时要注意Padding标签。 在Shape XML中定义了Padding并且此Shape作为某个View的Background时,View就不需要再设置android:padding,因为两者会产生冲突。 源代码分析可见冲突点: View.java setBackgroundDrawable()主要读取Drawable的Padding来设置当前View的Padding ------ if (background != null) { Rect padding = sThreadLocal
2 min read
Android

Android 读取classpath路径下的文件流&证书问题

今天在读取HTTPS证书时遇到的一个问题,src文件夹下的cer证书读取始终为空。 经过对APK包反编译发现cer证书竟然一直没有打包进去,怎么可能?!之前一直都很正常的。最后把问题聚焦在了Android Studio使用的Gradle编译环境上,因为之前Eclipse下的编译环境都可以将src文件夹下的XML、CER等文件一并打包进去,但是Gradle却不是这么做的。 由于刚刚切换到Android Studio,对Gradle编译系统还不是特别熟悉,从Intellij工程配置到Gradle编译配置没有发现对src下*.class以外文件的特殊配置,无奈只能选择其他方法。 解决方法: 将cer证书文件放在assets文件夹下,assets文件夹会被编译系统打包到APK包内,并且处于Root Path级别。 InputStream caInput = this.getClass().getClassLoader().getResourceAsStream("assets/d.com.cer"); 这样就可以读取到证书文件。 可能还有其他方式读取类似这种文件,比如通过cont
2 min read
Android

Android CSS 渐变 阴影

CSS中线性渐变的方向可以通过角度或关键字来指定,渐变中间色可以叠加多个。 语法: linear-gradient([[ | to ],]?[,]+) 角度值表示:从0deg到360deg,0表示从下向上,90表示从左到右,顺时针方向旋转; 关键字表示:“to top”表示从下向上,“to right”表示从左向右; 第三个参数为起始颜色,后面第N个参数依次指定后续渐变颜色。 Android中线性渐变的方向只能通过android:angle属性来指定角度,渐变色最多为三个。 其中Android线性渐变的角度与CSS的方向并不一致,0表示从左向右,90表示从下向上,逆时针方向旋转。
1 min read
Android

Android 读取媒体库文件 4.4

Nexus 4更新Android 4.4之后Doplus无法发送图片微博,今晚修复了这个问题,记录一下。 获取图片资源是通过Intent来调用媒体库。示例如下: Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, 0x01); Android4.4之前会默认调用Galley Provider选择图片,对应返回的URI是 content://media/external/images/media/65360 Android4.4则会调用Document Provider选择图片,在Document Provider整合了最近查看、内部存储器、SD卡、下载内容等本地资源,以及第三方的图片资源读取Provider比如Galley、Photos(Google+独立出来的图片应用)、Drive、Dropbox、Box、SkyDrive等等。 本地资源通过Document Provider选择后返回的URI如下:
2 min read
Android

观察者模式 监听器

位置:platform/packages/apps/Contacts 位置:platform/packages/apps/ContactsCommon 1、观察者模式 com.android.contacts.ContactSaveService 事件源类集中处理联系人、用户组的增删改,处理这些数据Activity注册ContactSaveService.RegisterListener监听,当调用数据处理方法完毕后通知各自的监听器。 //定义接口 public interface Listener { //触发事件后通知方法 public void onServiceCompleted(Intent callbackIntent); } //监听器列表 private static final CopyOnWriteArrayList sListeners = new CopyOnWriteArrayList(); ​ //注册监听 public static void registerListener(Listener listene
2 min read
Android

Android 4.4.1即将来袭

根据AOSP的编译信息,12月5号Android4.4.1_r1已通过测试平台被发布出来。 Android4.4.1_r1的最新代码为KOT49E。 11月底,Nexus系列的设备包括Nexus4、Nexus7、Nexus10均已获得Android 4.4的OTA更新。但是很多网友随后发现,Nexus 4、Nexus7更新至4.4后并没有出现透明可隐藏的状态栏、导航栏(虚拟按键),通过ROM提取发现,Google没有将更新设备的Launcher切换到Android4.4后才发布的Launcher3而是继续使用原有Launcher2,仅将原厂ROM的Nexus5切换到了Launcher。不知道Google会不会在4.4.1更新中正式安装Launcher3. 小道消息称,Google Play版的HTC One将直接从Android 4.3升级至4.4.1,目前尚未得到Google或者HTC的官方确认。 其他手机制造商的Android 4.4可升级设备信息: 三星: * Samsung Galaxy S4 Active * Samsung Galaxy S4 Zoom
1 min read
Android

Android 4.4 沉浸式设计思考

Android 4.4对UI的一大调整就是沉浸式设计,所谓沉浸式设计就是状态栏、虚拟按键可以动态隐藏,这使得开发者可以100%的使用屏幕,以Nexus 4为例,之前的竖屏可用空间为1084x768(顶部状态栏高度64px,底部虚拟按键132px)。这其中的好处也不止一点,在玩全屏游戏时一直受人诟病的虚拟按键问题通过这一设计也得到了解决。 最近几天Google自家的应用都开始陆续更新加入了这一设计,Google Play Book是最先更新使用这一设计风格的App。 图1-全屏幕的空间使用 图2-全屏后点击阅读区恢复状态栏、虚拟按键 Google Play Book在进入阅读界面是图2,当用户点击阅读区域,触发沉浸模式,与此同时ActionBar、SplitContentBar隐藏,完全实现全屏阅读。 但是在使用换另外一种情况,这一设计就显得有点捉襟见肘。与Google Play Book类似但在用户点击阅读区域时不隐藏ActionBar,但继续调用SystemUIVisiblablity()隐藏状态栏,在这个过程中界面会出现一个中间状态,如图。 此时顶部状态栏会被移除,但是
2 min read
Android

Android 图片数组定义和读取

位置:packages/apps/Launcher2 1、图片数组定义、资源读取 如果有多张图片,这些图片的使用与顺序无关,可以采取这种方式。 drawable-nodpi中有3张图片,wallpaper_1.jpg、wallpaper_2.jpg、wallpaper_3.jpg XML中定义数组ID wallpaper_1 wallpaper_2 wallpaper_3 Java代码获取图片资源ID final Resources resources = context.getResources(); final String packageName = resources.getResourcePackageName(R.array.wallpaper); ​ String[] wallPaperNames = resources.getStringArray(R.array.wallpaper); ​ for(String
1 min read