ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:23.30KB ,
资源ID:4243935      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4243935.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(推荐下载Android框架基础知识梳理.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

推荐下载Android框架基础知识梳理.docx

1、推荐下载Android框架基础知识梳理Android 框架基础知识梳理2017/02/22 0 转载自大神谷歌小弟的博客经过几年的发展和沉淀,Android 开发中涌现出许多优秀的框架,比如:Retrofit、Afinal、OKHttp、ButterKnife、AndFix 等等。这些框架的出现极大地简化了开发流程,提高了工作效率。在项目开发的过程中我们主要是使用这些轮子完成项目,很难有时间去顾及框架的内部实现。在项目交付之后我们可能就要去看看这些框架的源码了。这些主流框架的功能各不相同,但每当打开浩繁的源码时我们几乎都可以看到反射,注解,泛型的广泛应用;也正是这些技术使得框架具有了高度的灵活

2、性,优良的扩展性和健壮的稳定性。鉴于这些框架必备知识的重要性故在此对这部分内容做一个全面的梳理和总结主要内容:ClassLoader ClassLoader 的分析几种不同 ClassLoader 的介绍 ClassLoader 的应用泛型 泛型的由来自定义泛型泛型的擦除反射 class 常用反射技术 Type 以及ParameterizedType 反射与泛型的结合使用注解 常用注解的介绍和使用元注解自定义注解及其使用 1. ClassLoader 在程序运行时首先要将类加载到内存中,这个加载工作就是由 ClassLoader 完成的,故在中文文档中将其翻译为“类加载器”那么我们代码中所用到

3、的类有什么不同呢?它们的“来源”是不一样的有的类是属于系统提供的类,比如:String、Date、Object 等 因此,在 Android系统启动时会自动创建一个 Boot 类型的 ClassLoader,该 ClassLoader 用于加载一些系统层级的类有的类属于我们自己写的类,比如:User、Girl、Beauty 等等 因此,每个 APP 会创建一个自己的 ClassLoader 实例,该 ClassLoader 用于加载 dex private void getClassLoaders() ClassLoader classLoader = getClassLoader(); wh

4、ile(null != classLoader) System.out.println(“- classLoader=“ + classLoader); classLoader= classLoader.getParent(); 此处一共展示了三个 ClassLoader第一个 ClassLoader,如下:dalvik.system.PathClassLoaderDexPathListzip_file”/data/app/com.lizi.classloaderdemo-1/base.apk”,nativeLibraryDirectories=/data/app/com.lizi.class

5、loaderdemo-1/lib/x86,/vendor/lib, /system/lib该 PathClassLoader 在应用启动时创建,用于加载/data/app/cc.testreflection-2/base.apk 中的类ClassLoader 是一个抽象类,它有三个常用的子类:PathClassLoader、URLClassLoader、DexClassLoaderPathClassLoader 它只能加载已经安装的 apk 中的资源,比如 dex 文件URLClassLoader 它只能用于加载 jar 文件中的资源。但是 dalvik 不能直接识别 jar,因此这个加载器极

6、少使用。DexClassLoader 它用于从.jar 和.apk 类型的文件内部加载 classes.dex。该类加载器常用来完成动态加载 apk 的需求第二个 ClassLoader,我不是很清楚,嘿嘿,欢迎指点。第三个 ClassLoader,如下:java.lang.BootClassLoader112e4ef 该 BootClassLoader 在系统启动的时候创建,用于加载系统层级的类看看解释的这两个类加载器的应用 private void testClassLoader() try Class clazz =Class.forName(“cc.testreflection.Gir

7、l”); ClassLoader classLoader =clazz.getClassLoader(); System.out.println(“- classLoader=“ + classLoader);classLoader = mContext.getClass().getClassLoader(); InputStream inputStream =classLoader.getResourceAsStream(“assets/ic_launcher.png”); System.out.println(“-classLoader=“ + classLoader); clazz =

8、Class.forName(“java.lang.String”); classLoader =clazz.getClassLoader(); System.out.println(“- classLoader=“ + classLoader); catch(Exception e) 我们自己的类 com.lizi.classloaderdemo 和 assets 文件夹中的图片 ic_launcher.png 都是由 PathClassLoader 加载的,而 java.lang.String 是由 BootClassLoader 加载的2. 泛型 2.1 概念泛型始现于 JDK1.5,从那

9、以后大家在项目常常使用泛型,比如: ArrayList Girl arrayList=new ArrayList Girl for(int i=0;i 10;i+) Girl girl =newGirl(); arrayList.add(girl); 在与此类似的场景中利用泛型限定了集合中的输入类型,从而让编译器屏蔽了源程序中的非法数据输入,比如此时往 ArrayList 中 add 一个Boy 就无法通过编译器的编译泛型主要是给编译器看的;那么在编译完成之后生成的字节码里泛型会发生什么变化呢?来看个例子:private void testArraylistClass() Class claz

10、z1 = new ArrayList Integer ().getClass();Class clazz2 = new ArrayList String ().getClass(); boolean isEqual=(clazz1 = clazz2);System.out.println(“- isEqual=“ +isEqual);输出结果:- isEqual=true 带不同泛型的 ArrayList 在编译后生成的 Class 是相同的!也就是说,泛型在编译生成字节码文件时会被”擦除”;不管 ArrayList 带什么泛型,在编译后都是 ArrayList 所对应的字节码文件privat

11、e void testArraylistGeneric() try ArrayList Integer arrayList =new ArrayListInteger arrayList.add(9527); arrayList.add(9528); Methodmethod=arrayList.getClass().getMethod(“add”,Object.class);method.invoke(arrayList,”hello,java”); for (int i=0;i arrayList.size();i+)System.out.println(“- arrayList.get(

12、“+i+”)=“ + arrayList.get(i); catch (Exceptione) 输出结果如下图所示:看到了吧,之因此能把一个字符串 add 到该 ArrayList 中,究其原因还是因为泛型的擦除所致2.2 自定义泛型方法 public static T T genericMethod1(T t) return null;public K, VK genericMethod2(K k, V v) return null;public K, V String genericMethod3(K k, V v) return null;在自定义泛型方法时,请注意在方法的返回值之前声明

13、一个泛型,比如:这就表示该方法使用到了泛型 T。在此之后,在方法的输入参数中和方法体中均可以使用该泛型2.3 自定义泛型接口 public interface UserInfo T public void printUserInfo(Tt);private class UserInfoImpl T implements UserInfo T Override public voidprintUserInfo(T t) 在自定义泛型接口时,请注意在接口名之后声明一个泛型,比如:这就表示该接口使用到了泛型 T。在此之后,在接口定义方法时就可以使用该泛型了2.4 自定义泛型类 public clas

14、s Collection K, V private K key; private V value;private K getValue(K k) return null; private void printValue(V v) 自定义泛型类与自定义泛型接口非常类似,不再赘述3. 反射我们知道 Java 代码会被编译成字节码文件,当需要用一个类创建其对象的时候就会将其对应的字节码文件装载到内层,然后新建对象。也就是说,当一个类编译完成后,在生成的.class 文件中会产生一个 Class 对象,该对象用于表示这个类的信息,比如类的属性,字段,构造方法等等既然 Class 中包含了这么多有用的信

15、息,那么我们可以用什么方式获取 Class 呢?3.1 获取 Class /第一种方式 Class clazz = Girl.class; System.out.println(“- “ +clazz.getName(); /第二种方式 Girl girl = new Girl(); clazz = girl.getClass();System.out.println(“- “ + clazz.getName(); /第三种方式 clazz =Class.forName(“com.lizi.classloaderdemo.Girl”); System.out.println(“- “ +cla

16、zz.getName();三种方式:1.利用类名.class 获取 2.利用对象.getClass()获取 3.利用 Class.forName(“类名”)获取在获取到 Class 之后,就可以利用 newInstance()方法生成一个对象Object object = clazz.newInstance();其实,在调用 newInstance()方法时实际上是调用了该类的无参构造方法。当然,我们的目的不仅仅是利用 newInstance()生成一个对象,更重要的是要采用反射技术结合 Class 获取到该类的构造方法,属性,方法等信息在该类中有一些简单的属性,比如年龄,姓名,国家,城市,腰

17、围,胸围,臀围。还有一些简单的方法比如,构造方法 Girl(String name,Integer age),获取电话号码 getMobile();看到这里获取大家可能发现了:这些属性和方法有的是公有的,有的是私有的。访问属性的不同会带来哪些差异呢?带着这个小疑问,我们来看看常见的反射使用方法3.2 获取 构造方法 /* * 利用反射获取类的构造器 * * 1 getConstructors()获取类的构造器,但获取不到私有构造器 * 2 getDeclaredConstructors()获取类的所有构造器 * 3 getDeclaredConstructor()获取指定的构造器 */ pri

18、vate void testGetConstructor() try Class clazz = Class.forName(“com.lizi.classloaderdemo.Girl”); ConstructorConstructors = clazz.getConstructors(); for (Constructor constructor : Constructors) System.out.println(“- constructor=“ + constructor); System.out.println(“-”); Constructor declaredConstructo

19、rs = clazz.getDeclaredConstructors(); for(Constructor declaredConstructor : declaredConstructors) System.out.println(“-declaredConstructor=“ + declaredConstructor); System.out.println(“-2-”); Constructor constructor = clazz.getDeclaredConstructor(String.class, Integer.class);constructor.setAccessibl

20、e(true); Girl girl = (Girl) constructor.newInstance(“liuyan”,Integer.valueOf(22); System.out.println(“- girl=“ + girl); catch (Exception e) e.printStackTrace(); 获取类所有的构造器,这个没啥可说的。那么怎么获取指定的构造器呢?一个类可能有多个重载的构造方法,它们的方法名都是一样的;因此此时需要从构造器的输入参数入手,比如:clazz.getDeclaredConstructor(String.class, Integer.class);

21、就可以获取到如下的构造方法:private Girl(String name,Integer age) 但是请注意该构造方法是 private 的,因此需要将该方法的 accessible 标志设置为 true 表示取消语言访问检查。即:constructor.setAccessible(true);在获取构造方法后即可利用 newInstance()创建对象,即:Girl girl = (Girl) constructor.newInstance(“liuyan”,Integer.valueOf(22);3.3 利用反射获取字段/* * 利用反射操作类的字段 * 1 getFields()获

22、取类的字段,但是获取不到私有字段 * 2 getDeclaredFields()获取类的所有字段 * 3 获取指定的字段及其 type *4 获取指定对象的某个字段值 * 5 设置指定对象的某个字段值 */ private voidtestGetField() try Class clazz = Class.forName(“com.lizi.classloaderdemo.Girl”);Field fields = clazz.getFields(); for (Field field : fields) System.out.println(“- field=“+ field); Fiel

23、d declaredFields = clazz.getDeclaredFields(); for (Field declaredField :declaredFields) System.out.println(“- declaredField=“ + declaredField); /获取指定的字段及其 type Field field = clazz.getDeclaredField(“name”); Class type =field.getType(); System.out.println(“- field=“ + field + “,type=“ + type);System.o

24、ut.println(“- “); /获取指定对象的某个字段值 Girl girl = newGirl(“lucy”, 100, 100, 100, 18); Field field2 = clazz.getDeclaredField(“name”);field2.setAccessible(true); String name = (String) field2.get(girl); System.out.println(“-name=“ + name); /设置指定对象的某个字段值 Field field3 =clazz.getDeclaredField(“name”); field3.s

25、etAccessible(true); field3.set(girl, “hanmeimei”);System.out.println(“- girl=“ + girl); catch (Exception e) 3.4 利用反射获取类中的方法 /* * 利用反射获取类的方法 * 1 getMethods()获取该类及其父类的方法,但不能获取到私有方法 * 2 getDeclaredMethods()获取该类本身所声明的所有方法 * 3反射出类中的指定方法 */ private void testGetMethod() try Class clazz =Class.forName(“com.

26、lizi.classloaderdemo.Girl”); Object object = clazz.newInstance();Method methods = clazz.getMethods(); for (Method method : methods) System.out.println(“- method=“ + method); Method declaredMethods =clazz.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) System.out.println(“- declar

27、edMethod=“ + declaredMethod); Method method =clazz.getDeclaredMethod(“getMobile”, String.class); Class returnType =method.getReturnType(); System.out.println(“- method=“+method+”,returnType=“ +returnType); method.setAccessible(true); String mobile = (String) method.invoke(object,“678”); System.out.p

28、rintln(“- mobile=“ + mobile); catch (Exception e) 3.5 利用反射操作数组 /* * 利用反射操作数组 * 1 利用反射修改数组中的元素 * 2 利用反射获取数组中的每个元素 */private void testArrayClass() int intArray = newint5,7,9; Array.set(intArray,0,9527); Class clazz = intArray.getClass(); if(clazz.isArray() int length = Array.getLength(intArray); for (

29、int i = 0; i length; i+) Object object = Array.get(intArray, i); String className=object.getClass().getName();System.out.println(“- object=“ + object+”,className=“+className); 3.6 利用反射获取泛型的参数类型在许多框架中有这样的需求:根据不同的泛型参数响应不同的操作。一说到泛型参数类型,可能大家立马就想到了刚才说的泛型擦除,比如 ArrayList在编译后就变成了 ArrayList,它原本的泛型被”擦除”了。但是我们

30、有时确实需要知道泛型的参数类型,又该怎么来实现呢?按照刚才的那些思路恐怕是走不通了,得另辟蹊径了第一步: 定义 getGenericHelper()方法其输入参数为带泛型的参数,比如 ArrayListString,Integer第二步: 利用反射获取到该 getGenericHelper()方法,即: Methodmethod=getClass().getDeclaredMethod(“getGenericHelper”,HashMap.class);第三步: 获取到该方法的带泛型的输入参数,即: Type genericParameterTypes = method.getGenericParameterTypes(); 注意getGenericParameterTypes()方法返回的是一个数组,因为方法可能有多个参数,但是依据我们的需求这个数组中是仅有一个元素的4.2 ParameterizedTypeParameterizedType 称为参数化类型,比如 HashMap K,Integerprivate HashMap K, Integer hashMap = null;public void testParameterizedType()throws E

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1