知识树杂谈(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:

QQ截图20151029151423.jpg

res/values-sw600dp/layout.xml:

QQ截图20151029151436.jpg

       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一个请求流程。

image

                                

        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接口的问题。           

齊帥
原文地址:https://www.cnblogs.com/qishuai/p/7616385.html