准备

  一、Android 基础面试  https://www.jianshu.com/p/ffe7e0561c85?tdsourcetag=s_pcqq_aiomsg(还需要总结知识)

             https://blog.csdn.net/songzi1228/article/details/99975018  (多线程的总结)

              https://www.jianshu.com/p/90db19b4c98a   (大佬的博客园来观看使用)

  1.Activity异常的生命周期处理  

  @Override
  public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
  }
  异常或者系统内存不足会调用该方法

  2.Fragment的生命周期
 
 

      

             Fragment的生命周期

  3.SingleTask的启动模式

   

    可以将不同的APP的activity中设置为相同的taskAffinity,虽然在两个应用当中但是他们会被分配到同一个Task中

  4. View的事件分发机制

    

  

 

 

  二、异步消息处理机制

  1. 主线程中调用Loop,那么为什么没有造成阻塞呢?
   ActivityThread的Main方法里面有个Loop的消息队列,ActivityThread 有个 getHandler 方法,得到这个 handler 就可以发送消息,然后 loop 里就分发消息,然后就发给 handler,

   然后就执行到 H(Handler )里的对应代码。所以说ActivityThread的main方法主要就是做消息循环,一旦退出消息循环,那么你的程序也就可以退出了,所以这些代码就不会卡死。

  2. AsyncTask

    1). 组成:线程池+Handler

   2). Sting : 指的是doInBackgroud的参数类型  

    String : 指的是onProgressUpdate的参数类型

    Long : 指的是onPostExecute的方法的参数以及doInBackground的返回参数

  public class AsynctaskText extends AsyncTask<String , String , Long>{
  /**
  * 运行在UI线程中,在调用doInBackground之前运行的,可以做一些控件初始化
  */
  @Override
  protected void onPreExecute() {
  super.onPreExecute();
  }

  /**
  *后台运行的方法,运行在非ui线程中,可以执行耗时操作
  */

  @Override
  protected Long doInBackground(String... strings) {
  return null;
  }

 

  /**
  *doBackground里面会执行onProgressUpdate这个函数
  */

  @Override
  protected void onProgressUpdate(String... values) {
  super.onProgressUpdate(values);
  }


  /**
  *运行在ui线程,在doInBackground之后去执行的,
  */


  @Override
  protected void onPostExecute(Long integer) {
  super.onPostExecute(integer);
  }

  @Override
  protected void onCancelled() {
  super.onCancelled();
  }
 }

   execute和executeOnExecutor的区别

  execute :  Execute方法是串行执行,需要一个一个去执行

  executeOnExecutor  :  并行执行,需要添加线程池参数, 任务可以同步进行

  

 三、VIew绘制相关知识

  1. window、surface、decorview

   

   window :  是对我们Android系统当中窗口的一种抽象类,PhoneWindow是Window窗口的一个实现类。

   DecorView : 是我们应用窗口的一个根容器(本质上是一个FreamLayout),主要包含两个参数TitleView 和 ContentView

   surface :  是窗口独占一个surface的写实区域

   3. ListView滑动时候为什么不会发生OOM的原因(RecycleBin的机制) : 将离开屏幕外的view删除并且存放到RecycleBin这个类里面,当准备展示下一个view的时候,它会从RecycleBin里面取出一个scrapView,然后就将它设置为converVIew的参数进行判断是否已经设置过,从getView里面有这个方法从而到达view复用的作用

   4.ListView的性能优化5个优化点:

    1). converView

    2).viewHolder

    3).getVIew尽量少做耗时的操作(当滑动停止时候再去加载图片)

    4).ListVIew中的item元素避免半透明

    5).开启硬件加速

 

  四、 异常与性能

   1. 如何产生ANR

    a). View的按键或者触摸事件在5秒没有得到回应

    b). BroadcastReciver的onReceive()函数运行在了主线程中,在10秒内无法完成处理    

    c).Service的各个生命周期函数在20秒内无法完成处理

  2. 如何解决ANR

    a). 使用AsyncTask处理IO的耗时操作

    b). 使用Thread或者HandlerThread提供异步操作

    c). 使用Handler来处理工作线程的耗时操作

    d). Activity里面的所有生命周期都是在主线程中,避免写大量的耗时操作

  3. OOM容易混淆的概念

   内存溢出:我们申请的内存已经超出虚拟机的最大内存的限度就会抛出Out  Of  memory

   内存抖动 :  短时间大量的对象被创建然后就释放,触发的GC机制,严重占用内存区。

   内存泄露 :  我们要回收的对象无法进行GC的回收操作

  4. bitmap的讲解

   (1).Bitmap的模型: Android 2.3.3之前,Bitmap的像素数据存放在Native内存,而Bitmap对象本身则存放在Dalvik Heap中。而在Android3.0之后,Bitmap的像素数据也被放在了Dalvik Heap中。

   (2).在Android2.3.3之前推荐使用Bitmap.recycle()方法进行Bitmap的内存回收; 在Android3.0之后更注重对Bitmap的复用

   (3). recycle 的方法:  它既回收JAVA的内存也回收native的内存,这个对象以后就不会再被调用了。当你没有对象时候就会有GC去回收它,建议不要主动去调用它(快速截屏)

   (4).inBitmap参数的好处 : 前提是旧的inBitmap大小>=新的inBitmap的大小,否则不能复用。

   (5). LRU的算法 :  内部使用LinkedHashMap作为缓存, get和put完成添加和获取的操作,HashMap的remove方法来移除对象,当内部缓存满的时候,会调用trimToSize把较早或者使用最少的缓存对象移除出去,添加新的对象。

   (6). 三级缓存 :   网络->本地->内存

     原理:第一次打开app时候,图片首先从网络获得,然后再本地和内存各缓存一份,再去请求相同的url的时候,就会去本地或者内存去找  

   (7). 图片产生OOM的原因

     a.一个页面加载过多图片

       b. 加载图片没有进行对图片尺寸、质量进行压缩

     c.加载大量图片时候做图片缓存

     (8) . 图片的种类

     PNG : 无损压缩格式,支持透明通道

     JPEG : 有损压缩格式,不支持透明通道 

     WEBP : 既支持有损压缩也支持无损压缩,也支持透明通道

     GIF : 支持多帧动画

   (9). 超大图片加载方案
     可以使用BitMapRegionDecoder

  5. UI卡顿的讲解

    1). UI卡顿原因分析

     (1).在UI线程中做轻微的耗时操作,导致UI卡顿

     (2).布局Layout过于复杂,无法在16ms内完成渲染(从布局上),可以使用include、merage、view-stub这样标签作为处理,布局过于复杂使用自定义view

    (3).同一时间动画执行次数太多,导致CPU或GPU负载过重

    (4).View的过度绘制,导致某些像素在同一帧时间内过度绘制多次,从而让CPU或者GPU过重(从代码上) ----->自定义view使用clipRect来屏蔽被遮盖的view绘制

    (5).冗余的资源或者逻辑导致加载过慢

    (6).避免在onDraw里面执行对象的创建(这样会产生内存抖动)

    (7).图片显示(监听ListView滑动时候,就不要加载图片,当监听到停止时候,再去加载图片)

  6.常见内存泄露案例

   1.单例:长生命周期的对象(Application的对象)持有短生命周期的对象(是指Activity的对象)---->解决getApplicationContext()

   2. handler : 非静态内部类持有外部类的引用,导致于无法释放外部类的对象---->解决方法将handler至于为static的对象,然后将外部类改为弱引用来使用

   3.线程引起: AsyncTask和Runnable使用匿名内部类,因为非静态内部类持有外部类的引用,和handler类似

   4.文件的读写、数据库网络启用后没有关闭

   5.注册广播没有关闭广播

  7.内存管理

   (1).分配机制

   (2).回收机制

     五大进程:前台进程、可见进程服务进程、后台进程、空进程

   (3).内存优化

     当Service完成任务后,尽量停止它(可以使用IntentService)----->它是在异步线程中执行的,用完后它会自动释放对象的

    避免滥用Bitmap导致内存的浪费

    尽量少使用枚举常量,可以使用注解方法

    使用多进程来分担主内存耗时

  8.冷启动优化

   

 

  五、开源框架的学习

  1.AOP的切面编程(目前作为了解使用)

   (1).注解使用先关介绍

    @Before 前置通知,相当于BeforeAdvice

    @AfterReturning 后置通知,相当于AfterReturningAdvice

    @Around 环绕通知,相当于MethodInterceptor

    @AfterThrowing抛出通知,相当于ThrowAdvice

    @After 最终final通知,不管是否异常,该通知都会执行

    @DeclareParents 引介通知,相当于IntroductionInterceptor (了解)

   (2). JoinPoint 连接点对象可以获得参数讲解

目标对象:getTarget()

获得方法签名:getSignature()

获得方法名称:getSignature().getName()

获得实际参数:getArgs()

获得当前指定方法的类型:getKind()

案例1:性能监控

    @Aspect
   public class PerformanAop {
   @Around("call(* com.example.mi.okhttp.MainActivity.**(..))")
   public void getTime(ProceedingJoinPoint  joinPoint){
   Signature signature = joinPoint.getSignature();
   String name = signature.toShortString();
   long time = System.currentTimeMillis();
   try {
    joinPoint.proceed();             ----------------->执行该程序的方法
   } catch (Throwable throwable) {
    throwable.printStackTrace();
  }
    Log.d("ceshi", name + "=" + (System.currentTimeMillis() - time));
    }
  }  

 

2.MVC的架构的介绍

 

 C层 : 页面和数据交互,耦合程度高,不利于解耦

 

3.MVP的架构介绍

 

 MVP的特点:

 Presenter完全将ModelView解耦,主要逻辑处于Presenter中;Presenter和具体View没有直接关联,都是通过接口进行交互。

 View变更时候,可以保持Presenter不变,所以Model和View已经完全解耦

 MVP的优点:

 低耦合:Model、VIew层的变换不回影响到对方

 可重用性:Model层可用于多个View

 方便测试:可以单独多Model和VIew层单独测试

 MVP的缺点:

 当有一个很大的复杂页面,这样接口机会新增加很多接口,导致维护成本很大。

 解决方法:把一些通用的接口作为基类,其他接口去继承

 

4.MVC和MVP流程的大致区别

 

 

5.MVVM的数据模型

 

  

 MVVM的特点:

 ViewModel和Model/View进行双向绑定,View 发生改变时候,ViewModel会通知Model更新数据;Model数据更新时候,ViewModel会通知View更新显示

 

6.插件化模型(学习反射)主要解决

  (1).动态加载       DexClassLoader、PathClassLoader学习(动态加载app)

  (2).动态加载资源文件   AssetManager 动态加载资源文件

  (3).代码的加载

 

7.热修复模型

 (1).Android 类加载机制

  PathClassLoader  :  加载内存中已经安装的apk中的dex

 DexClassLoader :  加载sd卡中的apk/jar

 (2).热修复机制(通过向dexElements数组插入dex来完成热修复)

 dexElements数组、ClassLoader会遍历dexElements这个数组

 原理:dexElements数组会在基类的BaseClassLoader中创造好,DexClassLoader和PathClassLoade

 都是继承BaseClassLoader这个类的,通过ClassLoader去遍历dexElements数组,加载这个数组

 dex文件,如果BaseClassLoader加载到正确的dex文件后,就不会再去加载有crash的dex文件了,

 把正确的dex文件排在dexElements数组前面即可。

 

8.进程保活的实现

 (1).Android的进程优先级:前台优先级、可见进程、服务进程、后台进程、空进程(主要为了做缓存、缩短下次启动时间)

 (2).进程保活方案

     a.利用系统广播拉活 

    缺点:当只有在特定场景下才可以拉起保活,下次被杀死后,无法得到控制

     b.利用系统Service机制拉活 :  onStartCommand方法,返回START_STICKY

         缺点:在短时间内被多次杀死就不会被拉活、被root或者其他工具被stop也是无法拉活的

  c.通过native进程拉活(通过AMS的进程杀死)

  d.进程相互唤醒(打开一个app同时唤醒另一个app)

  e.提升Service进程优先级,比如改为前台进程   startForeground(1,notification)

  f.JobScheduler用来检测你自己的服务是否被杀掉,如果被杀掉了,你重启自己的服务   缺点:需要有自启动权限

 

  六、Java基础面试

   1.synchronized(悲观锁)和lock的区别

     synchronzied 同步代码块底层原理 :  monitorenter指向同步代码块的开始位置,monitorexit指向同步代码块的结束位置  

     线程执行到monitorenter指令时,该线程对象持有锁,即线程获得monitor持有权,count计数器+1,获得线程锁

     线程执行完毕后,执行monitorexit执行指令,count为0,释放锁。   注意:无论是正常结束还是异常结束,都会执行monitorexit指令

     synchronized 的同步方法的底层原理 :  ACC_SYNCHRONIZED的flag标记该方法是否是同步方法,从而执行相应的同步调用

   2.sleep和wait(notify)区别

     sleep是Thread的内部的一个静态方法,可以再任何地方调用;wait是Object成员方法,只能在synchroized代码中被调用,其他地方调用会非法监控异常

     在等待时候,wait是释放锁的,用于线程交互;sleep会一直持有锁,不会改变锁的状态,用于线程切换cpu的状态

   3.lock、synchronized 和 volatile的区别

    synchronized 和 volatile 的区别

    volatile只能在线程内存和主内存之间存一个变量值,synchronized可以修饰类、对象、方法等,但是synchronized很消耗内存

    volatile的理解:具有可见性、有序性,不具备原子性、禁止指令重排。 volatile修饰的变量会强制把数值写入主内存中

    synchronized 和 lock 的区别

    synchronized是Java的关键字,Lock是接口

    synchronized是自动释放锁,Lock需要手动释放锁,所以写到try catch中并且在finally中释放锁

    synchronized无法中断等待的锁,Lock可以中断,它可以在激烈的读写操作   

       

   4.线程池工作流程:

    (1).首先判断线程池是否已经满了

    (2).其次是判断工作队列是否已经满了

    (3).最后判断整个线程池是否满了

 

    五种线程池、四种拒绝策略、三种阻塞队列

    五种线程池 

    threadPool = Executors.newCachedThreadPool();               //有缓冲的线程池,线程数 JVM 控制
    threadPool = Executors.newFixedThreadPool(3);                 //固定大小的线程池,支持线程池并发
    threadPool = Executors.newScheduledThreadPool(2);       //固定大小的线程池,支持定时或者周期执行任务
    threadPool = Executors.newSingleThreadExecutor();          //单线程的线程池,只有一个线程在工作
    threadPool = new ThreadPoolExecutor();                               //默认线程池,可控制参数比较多     

    四种拒绝策略

    rejected = new ThreadPoolExecutor.AbortPolicy();                //默认,队列满了丢任务抛出异常
    rejected = new ThreadPoolExecutor.DiscardPolicy();            //队列满了丢任务不异常
    rejected = new ThreadPoolExecutor.DiscardOldestPolicy();   //将最早进入队列的任务删,之后再尝试加入队列
    rejected = new ThreadPoolExecutor.CallerRunsPolicy();          //如果添加到线程池失败,那么主线程会自己去执行该任务

    三种阻塞队列

    有限队列

     ArrayBlockingQueue<>(5);                             //基于数组的先进先出队列,有界
     SynchronousQueue<>();                                //无缓冲的等待队列,无界     适用于newCachedThreadPool线程池

    无限队列

    LinkedBlockingQueue<>();                            //基于链表的先进先出队列,无界     适用于newFixedThreadPool、newScheduledThreadPool

    参数讲解:

    * corePoolSize:核心线程池大小

    * maximumPoolSize:最多线程池大小

     * keepAliveTime:表示空闲线程的存活时间

     * unit:keepAliveTime时间单位

     * workQueue:阻塞任务队列

    * threadFactory:新建线程工厂

    * RejectedExecutionHandler:保护策略

   5.throw和throws的区别

    throw :  用在方法体内,跟的是对象名,throw抛出异常,一定会抛出某种异常

    throws :  用在方法后面,跟的是类名,它抛出的异常只是一种可能性,并不一定会抛出异常的

   6.final、finalize、finally的关键字的区别

    final :  修饰符,可以修饰类,不能再派生新的子类也不能作为父类被继承 ; 可以修饰变量,该变量的数值就不能修改

    finally :  try ... catch 语句中使用

    finalize :  在垃圾回收时候使用,被清理对象没有被引用的情况下调用的。

   7.注解相关介绍

   1.Retention : 定义注解保留的时间
       RetentionPolicy.SOURCE 注解只保留在源码,在编译器进行编译时会被忽略
          RetentionPolicy.CLASS 注解由编译器保存在class文件中,但不需要在运行时由VM保留,无法通过反射读取,这是默认的策略。
       RetentionPolicy.RUNTIME 注解由编译器保存在class文件中,并在运行时由VM保留,可以通过反射读取。

      2.Target  : 修饰对象的范围
         ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
         ElementType.FIELD:允许作用在属性字段上
               ElementType.METHOD:允许作用在方法上
               ElementType.PARAMETER:允许作用在方法参数上
               ElementType.CONSTRUCTOR:允许作用在构造器上
               ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
               ElementType.ANNOTATION_TYPE:允许作用在注解上
               ElementType.PACKAGE:允许作用在包上

   8.触发GC的条件

    (1). 当应用程序空闲时,即没有应用线程再运行时,GC会被调用的

    (2). JAVA内存不足的时候,GC会被调用

   9. 减少GC的开销措施

    (1). 不要显示调用System.gc()

    (2).尽量减少创建临时对象(相当于减少垃圾的产生,从而延长第二次GC的触发时间),对象不用时候最好显示设置为null(有利于GC收集器判定垃圾,从而提高垃圾回收)

    (3). 尽量使用StringBuffer,而不用String来增加字符串

    (4). 能使用基本变量就不用封装好的对象(比如int ---> Integer对象)

    (5). 尽量减少使用静态变量(静态变量属于全变量,不会被GC回收掉,他们也会一直占用内存,增加GC的次数)

  10.终止线程的方法

    1.while(boolean 变量值去终止) ------> 但是不会被立即终止线程

    2.while(!Thread.interrupted())---------->判断是否执行Thread.interrupted这个方法,执行之后一定在try..catch..中的catch方法中执行return,这样才可以真正中断该方法

    3. while(flag && ! Thread.interrupted()) ----->这两个方法去真正执行中断程序 

                     private volatile boolean flag = false

  11.多线程优化
    将非UI线程设置线程等级,一般下载线程Thread.setThreadPriority(Processs.THREAD_PRIORITY_BACKGROUND);

  七、网络相关的知识

   1.http和https的区别 

    HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
                 HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
                 HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
                 HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。

   2. http1.0、http1.1和http2.0区别

     http1.0  1.0+ :  支持版本号、请求头、代理连接

     http1.1 :  默认持久连接、支持缓存、支持管道方法发送多个请求 (一个TCP只能连接一个HTTP,不能复用;只能单向请求方式)

     http2.0 :  支持多路复用,可以设定请求的优先级;支持双向通信;去除不需要的HTTP请求头,减少网络带宽

   3.Http的请求方式

    

    常见以下四种:

    get :  获取资源

    post : 创建资源

    put :   更新资源

    delete : 删除资源

   4.get和post的区别

    url可见性 :  get的url可见(不安全)    post的url参数不可见(安全)

    数据传输上 :  get通过拼接url进行传递参数       post通过body体传输参数

    缓存性: get请求是可以缓存的     post请求不可以缓存

    后退页面的反应 : get请求页面后退时,不产生影响            post请求页面后退时,会重新提交请求 

    传输数据的大小 :  get一般传输数据大小不超过2k-4k      post请求传输数据的大小可以自己,也可以无限大

   5. cookie和session的区别

    存放位置不同:cookie存放在客户端,session存放在服务端的

    存取方式不同 : cookie用键值对,session可以保存任何内容

    安全性 : cookie保存在客户端,所以安全性比session低

    有限期不同 : cookie可以设置时间,session则不能

          set-cookie:[expires过期、到期)=new.Date(Date.now() +10 *1000)]   10S后过期,如果不设置默认是关闭浏览器立即失效

    对服务器压力不同 : 处于高并发情况下,cookie比session要高,因为它是保存在客户端的

   6.输入URL后HTTP请求返回完整的过程

    

   7.网络模式

    

   8.三次握手的过程

    

       SYN(synchronous建立联机)    ACK(acknowledgement 确认)    Sequence number(顺序号码)

         第一次握手:主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;
      第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包;
      第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。
    4.四次挥手

     

         FIN  (希望断开连接)    ACK(acknowledgement 确认)    Sequence number(顺序号码)  

    5.三次握手和四次挥手的面试点

     为什么不能用两次握手进行连接    

     三次握手是为了确保双方都已经进入准备好的状态,可以进行通信,而两次握手的创建可能造成死锁 

     假如:当C给S发一个连接请求,然后把C一个应答,这时候S已经认为创建成功了,但是C认为还没有创建成功,将忽略S那边发来的数据,还在等待应答中,S发出的分组超时后,

        再次发送请求,这样就会形成死锁

      如果已经建立了连接,但是客户端突然出现故障了怎么办?

    TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,

    时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,

    服务器就认为客户端出了故障,接着就关闭连接。

 

   6.TCP和UDP的区别

       a.基于连接与无连接;
          b.对系统资源的要求(TCP较多,UDP少);
          c.UDP程序结构较简单;
          d.流模式与数据报模式 ;

     e.TCP保证数据正确性,UDP容易丢包;TCP保护数据的顺序,UDP不行   UDP应用于IP电话和实时视频会议

  7.Http请求协议的讲解

  1. Accept : 代表接受文本和html格式
    text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
  2. Accept-Encoding : 支持什么样子的编码
    gzip, deflate, br
  3. Accept-Language : 中国语言
    zh-CN,zh;q=0.9
  4. Cache-Control : 支持缓存类型
    max-age=0
  5. Connection :  长连接服务
    keep-alive
  6. Cookie :  服务器给客户端标识的认证
    IMCDNS=1
  7. Host :
    www.imooc.com
  8. User-Agent :  请求主机的类型
    Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.35 Safari/537.36

  8.请求头的常见属性详解

   User-Agent : 向服务器请求的操作系统以及版本号等

   Referer :  你当前网页的上一个地址

   Cache-Control :  缓存

   Connection :  连接的类型(长连接)

   Range :  多线程取舍时候,截取某一个字段

   If-Match :  

   If-Modified-Since : 

   If-None-Match : 

  9.响应头的讲解

   Cache-Control : 缓存

   Content-Encoding : gzip  编码格式: 压缩

   Content-Type : text/html  直接的文本、html类型

   响应码 : 100-199     信息提示

       200-299     成功

       300-399     重定向

       400-499     客户端错误

       500-599     服务端错误

 

  八、自定义注解的学习

    @Retention:注解的保留位置         

    @Retention(RetentionPolicy.SOURCE)   //注解仅存在于源码中,在class字节码文件中不包含

    @Retention(RetentionPolicy.CLASS)     // 默认的保留策略,注解会在class字节码文件中存在,但运行时或者反射都无法获得,

    @Retention(RetentionPolicy.RUNTIME)  // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

  

    @Target:注解的作用目标        

    @Target(ElementType.TYPE)   //接口、类、枚举、注解

    @Target(ElementType.FIELD) //字段、枚举的常量

    @Target(ElementType.METHOD) //方法

    @Target(ElementType.PARAMETER) //方法参数

    @Target(ElementType.CONSTRUCTOR)  //构造函数

    @Target(ElementType.LOCAL_VARIABLE)//局部变量

    @Target(ElementType.ANNOTATION_TYPE)//注解

    @Target(ElementType.PACKAGE) ///包   

 

         @Document:说明该注解将被包含在javadoc中

     @Inherited:说明子类可以继承父类中的该注解

    案例:

    @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Xml {
      String[] layouts();
    }

    @Xml(layouts = "activity_main")

------------------------回家需要再调试看看---------------------------------

  

 

 

 

 

 

 

   

2.Activity之间的通信
  Intent/Bundle

         

  3.Activity向Fragment传递数据

   1).Bundle之间通信

    fragment.setArguments------>Activity与Fragment之间的通信桥梁

    

         getArguments()---->获得Bundle对象,还是key-value的模式

    

   2).直接在Activity之间定义

    

    

    在onAttach绑定时候,强制转换Acitivity的对象获得真实对象

   4.Fragment向Activity对象传递数据

    调用流程:

    

    

    

    

  5.Activity与Service之间通信

   1).绑定服务,利用ServiceConnection之间的通信

    Activity写的代码:

    

    Service写的代码:

    

   2).利用Intent之间的通信

    

    

   3).定义一个callback接口来监听服务中进程的变化

    Service定义接口

     

    Activity进行数据的调用

    

 

  7.service和IntentService的区别

   onHandleIntent在IntentService是抽象类,需要继承去实现的

  

   相比与Service它使用好处是不用你去手动释放,当你执行完onHandleIntent就会释放service,

   其次就是他可以通过执行HandlerThread执行异步操作

  8.service的启动和绑定的讲解

    service的绑定:

   

     

  启动服务比绑定服务的优先级高

  先绑定服务后启动服务:  绑定服务会转为启动服务运行状态,如果绑定的activity销毁,服务会继续运行

  先启动服务后绑定服务:  服务不会转为绑定服务状态,会和Activity绑定,但是activity销毁,会按启动服务生命周期走

  startService : 让服务长期运行在后台,但是无法与服务进行通讯

  bindServcie : 可以与服务进行通讯,但是无法长期运行在后台

 

 9.parcelable和serializable区别学习

  组件之间存储数据一般用parcelable,serializable将对象写到磁盘中

  序列化:  内存中的对象----->磁盘

  反序列化: 磁盘中的对象---->内存

  parcelable的实现步骤:

  1)implements Parcelable

  2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从 Parcel容器获取数据

  3)重写describeContents方法,内容接口描述,默认返回0就可以

  4)实例化静态内部对象CREATOR实现接口Parcelable.Creator

  public class MyParcelable implements Parcelable
 {
     private int mData;

     public int describeContents()
     {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags)
     {
         out.writeInt(mData);
     }

     public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>()
     {
         public MyParcelable createFromParcel(Parcel in)
         {
             return new MyParcelable(in);
         }

         public MyParcelable[] newArray(int size)
         {
             return new MyParcelable[size];
         }
     };
     
     private MyParcelable(Parcel in)
     {
         mData = in.readInt();
     }
 }

  简而言之: 通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象

 10.AIDL的使用

    

 11.WebView面试讲解

   1).webview在布局文件中的使用: webview写在其他容器中时(webview完全销毁的办法,否则会内存泄漏)

   2).webviewClient.onPageFinished-------->WebChromeClent.onProgressChanged() : 页面跳转时候调用这个函数


 

 

   

 

   

   

   

         

          

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  


posted on 2019-09-15 20:28  zhang11111wei  阅读(353)  评论(0编辑  收藏  举报

导航