周精益分享 - 程序员装逼指南

Android 单元测试

『图像和滤镜』

@(Share)[UIImage]

[toc]

图像

常见的图像格式

  • png(Portable Network Graphic)便携式网络图形格式
  • tiff、tif(Tagged Image File Format)标记图像文件格式
  • jpg、jpeg(Joint Photographic Experts Group)联合摄影专家组
  • gif(Graphic Interchange Format)图形交换格式

图像实例化

  • imageNamed:

    使用频率高,内存缓存优化

  • imageWithContentsOfFile:

    单次使用,暂时不清楚如何支持ImageAssert下的图片路径

  • imageWithData:

    本地或网络的文件数据加载

  • imageWithCGImage:

    绘制生成图,代码如下

1
2
3
4
5
// 旧图局部裁剪
CGImageRef myImageRef = [oldImage CGImageRef];
CGRect subRect = CGRectMake(20, 20, 100, 100);
CGImageRef cgCrop = CGImageCreateWithImageInRect(myImageRef, subRect);
UIImage *imageCrop = [UIImage imageWithCGImage:cgCrop];

显示图像

屏幕的缩放因子,导致我们需要@2x及@3x图,对视图截图操作也同样需要针对Retina及plus优化

1
2
3
4
5
6
7
8
9
10
11
- (UIImage*)screenShotBy:(UIImageView*)imagView
{
// UIGraphicsBeginImageContext(imagView.bounds.size);
// 2表示Retina,3表示plus分辨率,1正常,0则是当前设备的缩放因子
// YES 表示不包含图像的alpha通道
UIGraphicsBeginImageContextWithOptions((imagView.bounds.size), YES, 2);
[imagView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

contentModel

图像内容展现方式

  • UIViewContentModelScaleToFill(默认)
  • UIViewContentModelScaleAspectFill(下拉放大)
  • UIViewContentModelScaleAspectFit
  • UIViewContentModelCenter (一些停靠模式)
  • UIViewContentModelTop/Bottom
  • UIViewContentModelLeft/Right
拉伸属性

代码

1
2
3
4
5
// 方法一
image=[oldIconImage stretchableImageWithLeftCapWidth:10 topCapHeight:12];

// 方法二
image = [oldIconImage resizableImageWithCapInsets:UIEdgeInsetsMake(17, 17, 17, 25)];

ImageAssert

Alt text
使用slicing,小变大无视差
Alt text


图像选择器

系统自带

自定义


滤镜

人脸识别

聊聊 QCon2015 - 曾铭

pure-native 移动跨平台架构设计与实战

by 赵世婚

好处

  • 重复逻辑:网络层、账户逻辑
  • 性能(网络压缩、打破内存限制)
  • 多一层封装应对业务变动

坏处

  • 跨平台开发代码生成
  • 调试:异常捕获

总结:

  • 学不来:人员构成决定技术选型,技术选型决定依赖人员 {:&.rollIn}
  • 分层来应对业务变动(横向分层和纵向分层)

JavaScript - The World’s Best Programming Language

by Hax

JavaScript 最好 ?

  • 语言简陋:弱类型、标准库、面向对象、模块、异步 {:&.rollIn}
  • 编程时注意:好的范式、不好的范式

不过

  • npm 飞速发展的 packages 数量 {:&.rollIn}
  • ECMAScript 6,语言特性问题完美解决 (c)
  • Babel 6to5 (python)
    • most hard to upgrade -> always use latest feature!
  • 最快的动态语言,还会更快 (ruby)
  • JS as a Platform:中间语言 (c#, java)
  • 生态系统:浏览器、node.js、公司、社区

总结:

  • js 是现阶段发展最快的语言 {:&.rollIn}
  • 前端前途无量!

react

jQuery

  • DOM 操作
  • 组件散乱,社区力量难以聚合

AngularJS

  • 绑定 数据与数据、数据与视图之间的关系
  • npm

React

  • 用 js 写界面……(似乎是一种倒退)
  • 还整个 JSX 让界面好写一点
  • React Native

总结

  • 前端风起云涌 {:&.rollIn}
  • 小扎灭我客户端之心不死

总的总结

  • 拥抱变化
  • 最差也可以变最好,关键要敢于拥抱变化
  • 技术紧迫感:勇于尝试新东西
  • 业务紧迫感:技术改变留学

推荐:

  • JavaScript - The World’s Best Programming Language
  • pure-native移动跨平台架构设计与实战
  • 注重实效的性能
  • ReactJS 实战
  • ELE.ME是如何运行的

Android 6.0运行权限 - 王胜

一般权限和危险权限

Android 6.0以前,所有的权限在应用安装或者更新时自动完成授权。如果用户想安装这个App,必需接受所有的权限申请。为了保护用户的隐私,Android M特意调整了Android的授权架构。将应用权限分为一般(Normal)和危险(Dangerous)两种级别的权限:

  • 一般权限不会直接危害用户的隐私。如果你的App在manifest列出一般权限,那么系统会自动授予这些权限。

  • 危险权限可以访问用户的隐私数据。 如果你的App在manifest列出一般权限,那么系统会自动授予这些权限。如果列出危险权限,需要通过用户显示交互通过你的应用权限申请。

权限组

Anroid系统里所有的危险权限都拥有所归属的权限组。如果设备运行在Android6.0(API level 23),并且App的targetSdkVersion是23或者更高,当App请求危险权限时将会有以下表现:

  • 如果App请求manifest里声明的危险权限,并且App当前还没有获取任何权限组里的权限,系统将弹出一个描述App想要访问权限的对话框。但是对话框不会描述该权限属于哪个权限组。例如:App请求权限 READ_CONTACTS ,系统对话框只显示App需要访问设备的联系人。如果用户授权通过,系统仅仅给App需要的权限。

  • 如果App请求manifest里声明的危险权限,并且App已经用户该危险权限所在的权限组的权限,系统则直接授予此次请求的权限,而不需要用户手动交互。例如:如果App已经有先前的 READ_CONTACTS 权限,那么再请求 WRITE_CONTACTS 权限,系统则直接授予。

任何权限都有所归属的权限组,包括一般权限和App自定义的权限。然而,权限组只影响那些危险权限相关的用户体验。你可以忽略一般权限的权限组。

危险权限和权限组

权限组 权限
CALENDAR
  • READ_CALENDAR
  • WRITE_CALENDAR
CAMERA
  • CAMERA
CONTACTS
  • READ_CONTACTS
  • WRITE_CONTACTS
  • GET_ACCOUNTS
LOCATION
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION
MICROPHONE
  • RECORD_AUDIO
PHONE
  • READ_PHONE_STATE
  • CALL_PHONE
  • READ_CALL_LOG
  • WRITE_CALL_LOG
  • ADD_VOICEMAIL
  • USE_SIP
  • PROCESS_OUTGOING_CALLS
SENSORS
  • BODY_SENSORS
SMS
  • SEND_SMS
  • RECEIVE_SMS
  • READ_SMS
  • RECEIVE_WAP_PUSH
  • RECEIVE_MMS
STORAGE
  • READ_EXTERNAL_STORAGE
  • WRITE_EXTERNAL_STORAGE

权限检测

Android的所有版本里,都需要将所需的一般权限和危险权限都声明在App的manifest里。然而这些声明在不同的系统版本和App的target SDK Level会有不同的影响:

  • 如果设备运行在Android 5.1或者更低,或者你的App target SDK是22或者更低:如果你在manifest里声明了危险权限,用户则不得不在安装App时给予授权;如果他们不授权,系统将不会安装此App。

  • 如果设备运行在Android 6.0或者更高,或者你的App target SDK是23或者更高:App不仅需要在manifest里声明危险权限,而且App在运行时还需要在每次需要危险权限时发起请求。用户可以接受也可以拒绝权限申请,App也需要在用户拒绝危险权限申请时能长长运行。

注意:此处的权限处理只有App的target API level 23或者更高,而且运行在Android 6.0 (API level 23)或者更高的设备上才会如此。如果设备的中App的targetSdkVersion 是 22或者更低,系统则在安装或者更新App时自动授予危险权限。

The Android Support Library能很好地处理检测、请求和权限。Android 6.0 (API level 23) framework也提供了类似的方法。然而,使用support库能更简单一些,因为你不需要在调用方法之前检测android系统的版本。

发起权限申请请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Here, this Activity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {

// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.

} else {

// No explanation needed, we can request the permission.

ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);

// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}

处理权限请求结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults)
{

switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {

// permission was granted, yay! Do the
// contacts-related task you need to do.

} else {

// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}

// other 'case' lines to check for other
// permissions this app might request
}
}

注意:每次需要权限时,都需要显示请求调用,即使你已经获得的同权限组的其他权限。另外,权限分组处理的机制在将来的Android发型版本中有可能更改。因此你的App不应该依赖所需的权限在或者不在同一个权限组里。

参考:

Swift Access Control - 潘君

(未完待续)

  • 三个级别

    • Public
    • Internal
    • Private

      大部分默认是internal

  • 可应用于

    • Module
      • application
      • framework
    • source file
      • properties
      • types
      • functions
      • and so on(苹果文档这个太二了)
  • 准则

    • public变量不能定义为internal或者private的类型
    • 函数的访问权限不能高于参数和返回值
  • 应用场景

    • Single-Target Apps Internal
    • Frameworks Public
    • Unit Test Targets @testableAlt text
  • 会级联影响 例如修饰了type 同时也会影响type的members

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class SomePublicClass {          // explicitly public class
    public var somePublicProperty = 0 // explicitly public class member
    var someInternalProperty = 0 // implicitly internal class member
    private func somePrivateMethod() {} // explicitly private class member
    }

    class SomeInternalClass { // implicitly internal class
    var someInternalProperty = 0 // implicitly internal class member
    private func somePrivateMethod() {} // explicitly private class member
    }

    private class SomePrivateClass { // explicitly private class
    var somePrivateProperty = 0 // implicitly private class member
    func somePrivateMethod() {} // implicitly private class member
    }
  • Function

  • Tuple

    • 取元素中访问level最小的为准
    • 例如 (PrivateClass, InternalClass) 则取private
  • Enumeration

    • 一样
  • class

    1
    2
    3
    4
    5
    6
    7
    public class A {
    private func someMethod() {}
    }

    internal class B: A {
    override internal func someMethod() {}
    }