简历技能点

  1. 具备C、Java语言编写能力以及常见的设计模式,熟悉Kottlin 、Groovy语言,具备良好的编码习惯具备独立开发的能力

Java和c没有什么说的   

常见的设计模式单例模式、工厂模式、观察者模式、代理模式、适配器模式、建造者设计模式 、中介者模式、模板设计模式

 

  1. 代理模式  静态代理  动态代理(JDK和CJlib代理)主要区别是cjlib目标对象不需要实现接口
  2. 适配器设计模式  以生活中充电器的例子来讲解适配器,充电器本身相当于Adapter,220V交流电相当于src (即被适配者),我们的目dst(即目标)是5V直流电
  3. 建造者设计模式
  1.  Product(产品角色):一个具体的产品对象。
    2) Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类。
    3) ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件。
    4) Director(指挥者):构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程

 

  1. 单例的使用场景

(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。

(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。

 

  1. 熟悉 Android市面主流框架的搭建以及相关技术点(掌握 MVC架构、MVP架构,了解MVVM架构、UI、网络、图片的处理、数据缓存、异常处理性能优化等)。
  1. mvp结构设计

  其实我们日常开发中的Activity,Fragment和XML界面就相当于是一个 MVC 的架构模式,Activity中不仅要处理各种 UI 操作还要请求数据以及解析。这样的后果就是Activity可能会有几千行的代码,不便于维护,基于此现象及解耦的原则,才使用MVP的架构模式进行分离代码,其次MVP便于后期的代码重用,比如相同的业务逻辑,不同的ui界面等,开发MVP框架最重要的注意事项是内存泄漏。

参考文章:https://blog.csdn.net/johnny901114/article/details/54783106

搭建一套MVP架构框架:

*中介者设计模式

*Base基类的设计

*静态代理生命周期

*P层的安全、内存友好设计

*APT 在 MVP 框架中应用,提高车速

MVP架构由MVC发展而来。

在MVP中,M代表Model,V代表View,P代表Presenter。

Model 负责获取数据,数据的来源可以是网络或本地数据库等;

View 负责界面数据的展示,与用户进行交互;

Presenter 是Model与View之间的通信的桥梁,将Model与View分离开来。

具体实现的步骤

  1. 首先创建定义一个ILife的接口此接口关联View的生命周期方法,attchView()
  2. 定义抽象类LifeCirleMvpPresenter构造传递IMvp接口(采用弱引用的方式),同时get可以获取View对象。
  3. BaseMvpPresenter抽象中介者,不实现getView方法,让具体类来获取View对象
  4. 代理模式实现View层与Presenter的关联首先通过穿件Iview 接口,里面的方法就是获取代理类MvpControler实现ILife执行类是实现ILife的presenter
  5. 创建LifeCirleMvpActivity继承Activity实现Iview 让MvpControler实现代理
  6. 创建BaseActivity继承LifeCirleMvpActivity采用模板设计方法,具体Activity实现具体逻辑。
  7. 定义Contract把View和presenter相关联(谷歌推荐写法)

所以MVP的架构有如下好处:

1)降低了View和Model的耦合,通过Presenter层来通信;

2)把视图层抽象到View接口,逻辑层抽象到Presenter接口,提高了代码的可读性、可维护性;

3)Activity和Fragment功能变得更加单一,只需要处理View相关的逻辑;

4)Presenter抽象成接口,就可以有多种实现,方便单元测试。

 

  1. 对项目Http数据传输、Socket网络通信推送,Xml,Json数据解析与服务器交互,缓存机制认识深刻。

 

 

TCP/IP 四层 应用层  传输层  网络层  物理+数据链路层

HTTP  三次握手   客户端向服务器发出连接请求报文

                 TCP服务器收到请求报文后,如果同意连接,则发出确认报文

TCP客户进程收到确认后,还要向服务器给出确认。

  四次挥手

                 客户端进程发出连接释放报文,并且停止发送数据

                 服务端收到这个FIN,他发回一个ACK(确认)

服务端发送一个FIN(结束)到客户端,服务端关闭客户端的连接

客户端发送ACK(确认)报文确认,并将确认的序号+1,这样关闭完成。

4.对 Android 下常见机制,消息机制、事件分发机制、IPC机制,View 的绘制等有较深的理解。

  1. 消息机制  线程之间的通信
  2. Hander能否在主线程给子线程进行通信,首先handlerMessage默认在主线程运行的

HandlerMessage-》dispatchMessage-》Looper(loop)-》ActivityThread(main)-》主线程

1.Looper.prepareMainLooper();创建Looper和MessageQueue。

2.Looper.loop();获取当前线程的Looper和MessageQueue, 开启死循环获取MessageQueue的Message, 获取不到return, 获取到后调用Handler 的dispatchMessage,然后给客户端回调handleMessage()。

 

监听器的使用:1.事件方顶定义接口,定义回掉的函数,并且提供set方法

              2.哪里需要哪里回掉方法

              3.监听放设置监听器,重写回掉的方法

弊端: 必须定义接口

       发布方与监听方耦合在一起了

使用广播弊端:比较复杂,并且在UI线程,需要手动切换

 

Eventbus的使用

Subscriber事件的订阅方  注册,事件处理@Subscribe,不用的时候解除注册

                         

Publisher事件的发布方   发布事件

 

提供线程模式POSTING()在那个线程发布 就在这个线程

            MAIN()运行在主线程

            MAIN_ORDERED()运行在主线程()事件发布方不需要阻塞

            BACKGRIUND ()运行在不同线程

            ASYNC()运行在新开的线程

粘性事件:

先发布---》再订阅

发布直接发布postSticky()

订阅-》注册-》使用方法(sticky=true)-》解注册

 

 

事件分发机制

onTouchEvent:触摸事件的处理

dispatchTouchEvent:传递触摸事件

onInterceptTouchEvent:拦截事件传递

requestDisallowedInterceptTouchEvent(boolean disallowIntercept):请求自己的父布局不要拦截事件

 

1、安卓中事件的消费会 优先让子View去处理。

2、如果ViewGroup很想处理这个事件怎么办? onInterceptTouchEvent

3、requestDisallowedInterceptTouchEvent 请求ViewGroup不要去处理这个事件。

 

 

 

  1. 熟练掌握常见的网络请求框架(Xutils,OkHttp,Volley,Retrofit),图片加载框(Glide,Fresco,Picasso,WorldMap),数据库存储(GreenDao)音视频框架(ExoPlayer

OkHttp的简单使用

1. 创建⼀个 OkHttp 的实例

OkHttpClient client = new OkHttpClient.Builder().build();

2. 创建 Request

Request request = new Request.Builder()

.url("http://xxx.com")

.build();

3. 创建 Call 并发起⽹络请求

client.newCall(request).enqueue(new Callback() {

@Override

public void onFailure(Call call, IOException e) {

}

@Override

public void onResponse(Call call, Response response) throws IOException

{

Log.d("okhttp response", response.body().string());

}

})

OkHttp的源码解析

OkHttpClient 相当于配置中⼼,所有的请求都会共享这些配置(例如出错是否重试、共享的

连接池)。

Dispatcher dispatcher :调度器,⽤于调度后台发起的⽹络请求,有后台总请求数和

单主机总请求数的控制。

List protocols :⽀持的应⽤层协议,即 HTTP/1.1、HTTP/2 等。

List connectionSpecs :应⽤层⽀持的 Socket 设置,即使⽤明⽂

传输(⽤于 HTTP)还是某个版本的 TLS(⽤于 HTTPS)。

List interceptors :⼤多数时候使⽤的 Interceptor 都应该配置到这扔物线学堂

rengwuxian.com

2

⾥。

List networkInterceptors :直接和⽹络请求交互的 Interceptor 配

置到这⾥,例如如果你想查看返回的 301 报⽂或者未解压的 Response Body,需要在这⾥

看。

CookieJar cookieJar :管理 Cookie 的控制器。OkHttp 提供了 Cookie 存取的判断⽀

持(即什么时候需要存 Cookie,什么时候需要读取 Cookie,但没有给出具体的存取实现。

如果需要存取 Cookie,你得⾃⼰写实现,例如⽤ Map 存在内存⾥,或者⽤别的⽅式存在

本地存储或者数据库。

Cache cache :Cache 存储的配置。默认是没有,如果需要⽤,得⾃⼰配置出 Cache 存

储的⽂件位置以及存储空间上限。

HostnameVerifier hostnameVerifier :⽤于验证 HTTPS 握⼿过程中下载到的证书所

属者是否和⾃⼰要访问的主机名⼀致。

CertificatePinner certificatePinner :⽤于设置 HTTPS 握⼿过程中针对某个

Host 的 Certifificate Public Key Pinner,即把⽹站证书链中的每⼀个证书公钥直接拿来提前

配置进 OkHttpClient ⾥去,以跳过本地根证书,直接从代码⾥进⾏认证。这种⽤法⽐较少

⻅,⼀般⽤于防⽌⽹站证书被⼈仿制。

Authenticator authenticator :⽤于⾃动重新认证。配置之后,在请求收到 401 状

态码的响应是,会直接调⽤ authenticator ,⼿动加⼊ Authorization header 之后

⾃动重新发起请求。

boolean followRedirects :遇到重定向的要求是,是否⾃动 follow。

boolean followSslRedirects 在重定向时,如果原先请求的是 http ⽽重定向的⽬标是

https,或者原先请求的是 https ⽽重定向的⽬标是 http,是否依然⾃动 follow。(记得,

不是「是否⾃动 follow HTTPS URL 重定向的意思,⽽是是否⾃动 follow 在 HTTP 和

HTTPS 之间切换的重定向)

boolean retryOnConnectionFailure :在请求失败的时候是否⾃动重试。注意,⼤多

数的请求失败并不属于 OkHttp 所定义的「需要重试」,这种重试只适⽤于「同⼀个域名的

多个 IP 切换重试」「Socket 失效重试」等情况。

int connectTimeout :建⽴连接(TCP 或 TLS)的超时时间。

int readTimeout :发起请求到读到响应数据的超时时间。

int writeTimeout :发起请求并被⽬标服务器接受的超时时间。(为什么?因为有时候

对⽅服务器可能由于某种原因⽽不读取你的

 

client.newCall实际上是去执行RealCall.newRealCall()RealCall是Call接口的实现,最终返回RealCall对象。

当调用enqueue方法其实是执行的RealCall的enqueue方法其实是调用的Dispatcher的ExecutorService线程管理工具去执行,在此会判断线程的数量64,线程管理创建新的线程执行run方法里执行excute的Okhttp里面最核心的getResponseWithInterceptorChain

getResponseWithInterceptorChain() ⽅法做的事:把所有配置好的 Interceptor 放在

⼀个 List ⾥,然后作为参数,创建⼀个 RealInterceptorChain 对象,并调⽤

chain.proceed(request) 来发起请求和获取响应。

在 RealInterceptorChain 中,多个 Interceptor 会依次调⽤⾃⼰的 intercept() ⽅

法。这个⽅法会做三件事:

1. 对请求进⾏预处理

2. 预处理之后,重新调⽤ RealIntercepterChain.proceed() 把请求交给下⼀个3. 在下⼀个 Interceptor 处理完成并返回之后,拿到 Response 进⾏后续处理

从上到下,每级 Interceptor 做的事:

⾸先是开发者使⽤ addInterceptor(Interceptor) 所设置的,它们会按照开发者的要

求,在所有其他 Interceptor 处理之前,进⾏最早的预处理⼯作,以及在收到

Response 之后,做最后的善后⼯作。如果你有统⼀的 header 要添加,可以在这⾥设置;

然后是 RetryAndFollowUpInterceptor :它负责在请求失败时的重试,以及重定向的

⾃动后续请求。它的存在,可以让重试和重定向对于开发者是⽆感知的;

BridgeInterceptor :它负责⼀些不影响开发者开发,但影响 HTTP 交互的⼀些额外预

处理。例如,Content-Length 的计算和添加、gzip 的⽀持(Accept-Encoding: gzip)、

gzip 压缩数据的解包,都是发⽣在这⾥;

CacheInterceptor :它负责 Cache 的处理。把它放在后⾯的⽹络交互相关

Interceptor 的前⾯的好处是,如果本地有了可⽤的 Cache,⼀个请求可以在没有发⽣

实质⽹络交互的情况下就返回缓存结果,⽽完全不需要开发者做出任何的额外⼯作,让

Cache 更加⽆感知;

ConnectInterceptor :它负责建⽴连接。在这⾥,OkHttp 会创建出⽹络请求所需要的

TCP 连接(如果是 HTTP),或者是建⽴在 TCP 连接之上的 TLS 连接(如果是 HTTPS),

并且会创建出对应的 HttpCodec 对象(⽤于编码解码 HTTP 请求);

然后是开发者使⽤ addNetworkInterceptor(Interceptor) 所设置的,它们的⾏为逻

辑和使⽤ addInterceptor(Interceptor) 创建的⼀样,但由于位置不同,所以这⾥创

建的 Interceptor 会看到每个请求和响应的数据(包括重定向以及重试的⼀些中间请求

和响应),并且看到的是完整原始数据,⽽不是没有加 Content-Length 的请求数据,或者

Body 还没有被 gzip 解压的响应数据。多数情况,这个⽅法不需要被使⽤;

CallServerInterceptor :它负责实质的请求与响应的 I/O 操作,即往 Socket ⾥写⼊请

求数据,和从 Socket

 

Glide相关的面试知识点:

https://muyangmin.github.io/glide-docs-cn/

  1. 简单用法  Glide.with(this).load(url).into(imageView);
  2. 可以通过RequestOptions来设置相关配置

2.Glide的with方法不光接受Context,还接受Activity 和 Fragment,Context会自动的从他们获取

3.Glide支持加载各种各样的图片资源,包括网络图片、本地图片、应用资源、二进制流、Uri对象等等

4.placeholder()方法添加占位图

5.diskCacheStrategy()方法使用缓存机制

6.error(R.drawable.error)异常占位图

7.默认支持加载gif图片,asBitmap()方法只允许加载静态图片,asGif()支持加载gif图片

8.Glide对图片进行处理用多少加载多少,节省内存。

9.支持图片大小的加载override(100, 100)

1.RequestOptions多次加载解决的办法:可以使用静态的方法,封装使用

2.MyAppGide继承AppGilideModule加上注解@GildeModel配置,设置配置只加载一次,可以设置一些配置的内容如缓存、动画、监听、日志,registerComponents里面的参数registr.append可以加载资源类型和资源加载器

 

MyGildeExtension加上注解GildeExtension,声明方法构造传递RequestOpentions对象,对opentions进行统一配置,并且此方法要有注解@GildeOptentios,此方法是全局同意配置,然后再GildeAapp里面去调用injectOpentions()

 

Glide源码解析

With()

Glide会根据我们传入with()方法的参数来确定图片加载的生命周期,并没有什么特别复杂的逻辑。

Load()

给load()方法传入不同类型的参数,这里也会得到不同的ModelLoader对象。由于我们刚才传入的参数是String.class,因此最终得到的是StreamStringLoader对象,它是实现了ModelLoader接口的,并且DrawableRequestBuilder实现Glide绝大多数的API

Into()

DrawableRequestBuildersuper是父类是GenericRequestBuilder里面的into()

Request是用来发出加载图片请求的,它是Glide中非常关键的一个组件,在构造的过程中把placeholderId、errorPlaceholder、diskCacheStrategy等等都是在这里组装到Request对象当中的。

加载图片最终显示出来,默认使用的HttpUrlConntion同时也支持Volley和Okhttp进行拓展

Gilde的缓存机制

lide又将它分成了两个模块,一个是内存缓存,一个是硬盘缓存。

情况下Glide会优先从缓存当中读取,只有缓存中不存在要读取的图片时,才会去读取原始图片。

内存缓存:skipMemoryCache()方法并传入true,就表示禁用掉Glide的内存缓存功能,内存缓存的技术主要是一个使用的就是LruCache算法,另一个使用的就是弱引用

磁盘缓存:

DiskCacheStrategy.NONE: 表示不缓存任何内容。

DiskCacheStrategy.SOURCE: 表示只缓存原始图片。

DiskCacheStrategy.RESULT: 表示只缓存转换过后的图片(默认选项)。

DiskCacheStrategy.ALL : 表示既缓存原始图片,也缓存转换过后的图片。

硬盘缓存的实现也是使用的LruCache算法

 

GreenDao

是ORM框架,是关系型数据库,数据库与对象之间做一个映射,不用写SQL语句,重心放在业务逻辑上。

优点:性能好,易用性比较强,轻量最小的内存消耗,小于100kb的数据库

 

使用方法:

1.某实体类-----》某表----->@Entity注解   @Id(autoincrement=true)

Make Project--》@Generated 生成构造参数和对应的get和set方法,同时会生成一个对应的greendao文件夹会生成与这个对应的三个类

          某Dao--------》数据库访问对象(某表的操作)---->

          DaoMaster-----》数据库的连接对象

          DaoSession----》由连接生成的对话

  1. 在application里面连接数据库并创建会话
  2. 创建一个GreenDaoManager来管理对应的Dao增删改查

     插入insert重载的方法很多单个集合替换某一个都可以实现

     查询queryBuilder()返回QueryBuilder对象可以对数据进行排序

         Query.where(字段.eq())依然可以对其排序

     删除数据delete(数据)  

     修改数据update(数据)修改和删除之后可以在onResume()重新获取一下数据

  1. 数据库进行加密  需要借助 sqlcipher库来实现

     在获取数据的时候获取有密码的数据库

 

 

 

 

  1. 熟练掌握JNI 开发,通过JNI实现JAVA与C/C++程序间的调用及回调。

1.需要搭建NDK的开发环境

2.编译so文件  在activty里面加载第三方库也就是so文件

3.java调用本地方法获取c文件的内容(cpp文件夹下)(注意包名要一致)

手机的架构x86 arm64

 

  1. 具备html、css、JavaScript前端开发能力,熟悉原生Html5混合开发,熟悉Jquery Jquery Mobile框架。
  2. 可根据文档快速接入三方分享 Shared SDK、三方地图SDK、三方登录 SDK、三方支付 SDK、三方移动直播SDK、三方即时通讯以及消息推送。
  3. 熟悉Android 6.0 ,7.0 ,8.0 ,9.0,10.0版本行为变更和和适配

6.0危险权限需要动态申请

7.0

1文件访问权限

1、首先要在Manifest中注册provider:、

2、android:resource的值是自定义的一个xml文件,里面指定了可以访问的目录

2、PopupWindow在Android7.0系统中显示位置错误:

3、APK signature scheme V2(建议打包V1和V2都勾选)

8.0

1、需要添加权限:

2、通知栏显示(android 8.0以后必须设置通知渠道id否则通知无法显示)

      9.0   Android9.0不能加载http的url;

  10.0  Android10.0不能获取到设备的IMEI

1.1、当首次安装应用时生成一个UUID,将此uuid存到手机存储中,而不是使用SharedPreferences存储,将此uuid上传至服务器进行存储。(缺点:用户手动删除此存储、重置手机那就唯一标识失效了)

1.2、使用ANDROID_ID标识(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);)

缺点:重置手机失效,Android厂商特制系统不同设备拥有相同ANDROID_ID,或者获取ANDROID_ID为空;

1.3、使用极光推送、阿里推送等推送sdk获取它们的DeviceId作为设备唯一标识;

10、可以根据产品业务需求,基于 android 平台进行移动端应用程序独立开发设计、实现、测试及功能维护。  

11、有JavaWeb开发经验,有WebService交互的经验有微信公共号开发及微信小程序的经验。

12、熟悉组件化、插件化和热更新技术。

组件化:

插件化:

DexClassLoader  classLoader=new DexClassLoader(”apk的目录“,getCacheDir.getPath(),null,null);

获取classLoader经过反射之后获取apk里面的方法

dex: 普通的dex

Odex:Optimized Dex 优化的Dex

你可能感兴趣的:(ZUI易入门Android)