知识树杂谈(1)
1. DNS劫持是什么;解决办法。
又称域名劫持,是指在特定网络下,拦截所有域名解析请求,返回假的或不可用的网址。
解决办法:
1. 手动修改路由DNS地址和密码;
2. 使用 HTTPDNS解决:
区别:
a. DNS协议建立在UDP之上,53端口;HTTPDNS协议建立在http之上,80端口.
b. 速度快(多次转发、绕路),域名解析失败率底,绕过运营商的 Local DNS ,避免域名劫持。
c. 访问过程如下图:
解决方法:
a. 使用阿里云、腾讯云、新浪等提供的HTTPDNS服务;
b. 使用可以定制DNS逻辑的网路库,如okhttp.
private static class MyDns implements Dns { @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException { List<String> strIps = HttpDns.getInstance().getIpByHost(hostname); // !!! 注意 List<InetAddress> ipList; if (strIps != null && strIps.size() > 0) { ipList = new ArrayList<>(); for (String ip : strIps) { ipList.add(InetAddress.getByName(ip)); } } else { ipList = Dns.SYSTEM.lookup(hostname); } return ipList; } } private OkHttp3Utils() { okhttp3.OkHttpClient.Builder builder = new okhttp3.OkHttpClient.Builder(); builder.dns(new MyDns()); mOkHttpClient = builder.build(); }
4. 推荐文章
基础知识: http://www.cnblogs.com/softidea/p/5325162.html
okhttp: http://blog.csdn.net/sbsujjbcy/article/details/51612832
2. Android 兼容性(屏幕适配)
1. 支持各种屏幕尺寸
使用wrap_content、match_parent、weight
android:layout_weight的真实含义是:如果View设置了该属性并且有效,那么该 View的宽度等于原有宽度(android:layout_width)加上剩余空间的占比。
2. 使用相对布局,禁用绝对布局
3. 使用限定符
a. 使用尺寸限定符
例如: 双面板布局 /res/layout/main.xml /res/layout-large/main.xml
b. 使用最小宽度限定符
例如: /res/layout/main.xml /res/layout-sw600dp/main.xml
c. 使用别名布局
res/values-large/layout.xml:
res/values-sw600dp/layout.xml:
4. 使用屏幕方向限定符
-
小屏幕,纵向:单面板,带徽标
-
小屏幕,横向:单面板,带徽标
-
7 英寸平板电脑,纵向:单面板,带操作栏
-
7 英寸平板电脑,横向:双面板,宽,带操作栏
-
10 英寸平板电脑,纵向:双面板,窄,带操作栏
-
10 英寸平板电脑,横向:双面板,宽,带操作栏
-
电视,横向:双面板,宽,带操作栏
5. 使用自动拉伸位图
.9的制作,实际上就是在原图片上添加1px的边界,然后按照我们的需求,把对应的位置设置成黑色线,系统就会根据我们的实际需求进行拉伸。
6. 支持各种屏幕密度
a. 使用密度无关像素 dp、sp(配合权重)
当然,我们尽量使用match_parent和wrap_content,尽可能少的用dp来指定控件的具体长宽,再结合上权重,大部分的情况我们都是可以做到适配的。
b. 提供多种位图
-
xhdpi:2.0
-
hdpi:1.5
-
mdpi:1.0(最低要求)
-
ldpi:0.75
7. 实施自适应用户界面流程
根据当前布局,选择适当界面流程
a. 确定当前布局
b. 根据当前布局做出响应
c. 重复使用其他活动中的片段
最佳实践
关于高清设计图尺寸
Google官方给出的高清设计图尺寸有两种方案,一种是以mdpi设计,然后对应放大得到更高分辨率的图片,另外一种则是以高分辨率作为设计大小,然后按照倍数对应缩小到小分辨率的图片。
根据经验,我更推荐第二种方法,因为小分辨率在生成高分辨率图片的时候,会出现像素丢失,我不知道是不是有方法可以阻止这种情况发生。
而分辨率可以以1280*720或者是1960*1080作为主要分辨率进行设计。
ImageView的ScaleType属性
设置不同的ScaleType会得到不同的显示效果,一般情况下,设置为centerCrop能获得较好的适配效果。
动态设置
有一些情况下,我们需要动态的设置控件大小或者是位置,比如说popwindow的显示位置和偏移量等,这个时候我们可以动态的获取当前的屏幕属性,然后设置合适的数值
1
2
3
4
5
6
7
8
9
10
11
|
public class ScreenSizeUtil { public static int getScreenWidth(Activity activity) { return activity.getWindowManager().getDefaultDisplay().getWidth(); } public static int getScreenHeight(Activity activity) { return activity.getWindowManager().getDefaultDisplay().getHeight(); } } |
推荐文章:
http://www.cocoachina.com/android/20151030/13971.html
http://www.cnblogs.com/qishuai/p/7605549.html
3. OOP设计原则(核心基础原则或架构或设计模式铺垫)
a. 面向对象7大设计原则
OOP的方法论(高内聚、低耦合、易复用)
1. 开闭原则(Open-Closed Principle,OCP).
软件实体应当扩展开放、修改封闭。
这是面向对象设计(OOD)的基石,也是最重要的原则。
实现:合理划分构件,一种可变性不应当散落在代码的很多角落里,而应当封装到一个对象里;一种可变现不应当与另一种可变性混合在一起。
2. 依赖倒置原则(Dependency Inversion Principle,DIP)
摆脱面向过程编程思想中高层模块依赖于底层实现,抽象依赖于具体细节。OOP要做到的是,高层模块不依赖于底层模块,两者都依赖于抽象;抽象不依赖具体实现细节,细节依赖抽象。
实现:应该通过抽象解耦的方式,是具体类最多可能的仅与抽象类(接口)发生耦合;程序在需要引用一个对象时,应当尽可能的使用抽象类型作为变量的静态类型,这是针对接口编程的含义。
3. 里氏替换原则(Liskov Substitution Principle, LSP)
继承思想的基石.“只有当衍生类可以替换掉基类,软件功能不会受影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。”
4. 接口隔离原则(Interface Insolation Principle,ISP)
接口功能单一,避免污染.
实现: 一个类对另外一个类的依赖性应当建立在最小的接口上的。使用多个专门的接口比使用单一的总接口更好。
5. 单一职责原则(Single Resposibility Principle,SRP)
就一个类而言,应该仅有一个引起他变化的原因,如果一个类的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能抑制这个类完成其他职责的能力。
6. 合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
设计模式告诉我们对象委托优于类继承,从UML的角度讲,就是关联优于继承关系,尽量使用合成/聚合、尽量不使用继承.
实现:在一个新的对象里面使用一些已有的对象,是之成为新对象的一部分,以整合其功能。
7. 迪米特原则或最少知识原则(Low Of Demeter or Priniciple of Least Kenwledge)
就是说一个对象应当对其他对象尽可能少的了解。即只直接与朋友通信,或者通过朋友和陌生人通信。
朋友的定义(或关系):
(1)当前对象本身。
(2)以参量的形式传入到当前对象方法中的对象。
(3)当前对象的实例变量直接引用的对象。
(4)当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友。
(5)当前对象所创建的对象。
实现:
(1)在类的划分上,应当创建有弱耦合的类。类之间的耦合越弱,就越有利于复用。
(2)在类的结构设计上,每一个类都应当尽量降低成员的访问权限。一个类不应当public自己的属性,而应当提供取值和赋值的方法让外界间接访问自己的属性。
(3)在类的设计上,只要有可能,一个类应当设计成不变类。
(4)在对其它对象的引用上,一个类对其它对象的引用应该降到最低。
(5)尽量限制局部变量的有效范围.
4. Android 架构初探(1)
a. 基本架构方向、满足特性
方向: 分层->模块化->组件化->插件化.
目标: 方便自动化测试、低耦合(方便维护和扩展)、易复用。
b. 框架简介
1. ORM框架 (解决:数据库-对象映射)
主流: hibernate、mybates/ibates、springjdbc
解决问题: 通过对象-关系映射系统,实现程序对象到关系型数据库的映射,减少大量数据库操作开发量。
劣势: hibernaet 太重性能不好、复杂多表关联查询吃力。
ibates 半自动化,可以自己写sql. 文档、调试、复杂查询不方便。
2. MVC, MVP, MMVM用来解决业务逻辑和视图之间的耦合
MVC: M是指业务模型,V是指用户界面,C则是控制器.
a. 主动MVC
MVC的理论思想对应的是主动MVC, 这里的主动的意思是, Model会主动通知View更新。而我们使用MVC框架, Struts, asp.net mvc等都不是主动MVC(视图的更新都是通过Controller完成的)
Model
用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。
模型中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此模型的视图必须事先在此模型上注册,从而,视图可以了解在数据模型上发生的改变。
View
视图层负责数据的展示。
在视图中一般没有程序上的逻辑。为了实现视图上的刷新功能,视图需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里订阅Model的事件。
Controller
控制器是M和V之间的连接器,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据模型上的改变。
b. 被动MVC
被动MVC 中,与主动MVC的区别在于:
1、模型对视图和控制器一无所知,它仅仅是被它们使用
2、控制器使用视图,并通知它更新数据显示
3、视图仅仅是在控制器通知它去模型取数据的时候它才这么做(视图并不会订阅或监视模型的更新)
Web中的MVC框架都是被动MVC模式,因为web应用中, 由于http是基于请求和响应方式协同工作的,因此当服务器端的model(数据)发生变化时,它不会立即更新客户端的view,只有客户端重新请求或刷新页面时才更新.
下图是典型的MVC框架中的MVC一个请求流程。
c. MVC 缺陷
MVC的缺点
完美的MVC应用场景应该是这样的:
有个Student Model, 关联StudentListView, StudentEditView.
对于StudentListView, Student Model提供Student的集合数据来显示StudentListView
对于StudentEditView, Student Model提供单个Student数据来展示StudentEditView并且响应StudentEditView的保存操作。
但是这只是完美的情况,实际应用中,在ListView上,不单单显示Student的信息,可能还需要这个Student的历史成绩,家庭情况, 老师信息。而这些是Student Model不能提供的。
也许我们可以扩展Student Model, 将Student Model能够提供的信息扩展,包含成绩信息等,这本身也可以。但是,如果Student显示的View,这个需要只是需要额外的成绩信息,另一个View只是需要额外的家庭信息,Student Model是不是有些疲于奔命,你能知道还会有多少个差异化的View的需求? 而且让逻辑端代码这样不断的修改来适应View端,好吗?
由于MVC的设计思想是从Model出发,而没有考虑到View端的复杂性,这样导致的问题是Model难以符合复杂多变的View端变化。
相对这点,MVP和MVVM就要好得多。它们都独立出了Presenter 和ViewModel来对应每个View。
5. Android Mac无法识别手机或USB调试
a. 排查USB是否识别,确保硬件USB接口和USB数据线正常。
方法:
1. Mac->关于本机->系统报告->USB 如图:
2. 执行 adb devices,查看有无设备
一般情况下都是线或手机USB接口的问题。