Android面试题总结

1.MVP与MVP
    MVC:    
    M-model javaBean类 用于保存实例对象 
    V-View 用于UI界面的展示
    C-Controller 用于更新UI和数据的实例    
    MVP
    M:做工作具体业务逻辑的处理和实现
    V:用于界面展示和用户交互的
    P-Presenter:用来处理程序各种逻辑的分发
    优点:
     1.易于维护
     2.易于测试
     3.松耦合度
     4.复用性高
     5.健壮稳定
2.Handele和异步任务的运行机制
3.自定义View的实现-
    

    1.自定义属性的声明和获取
        分析需要的自定义属性
        在res/values/attrs.xml定义声明
        在layout文件中进行使用
        在View的构造方法中进行获取
    2.测量onMeasure
    3.布局onLayout(ViewGroup)
    4.绘制onDraw
    5.onTouchEvent
    6.onInterceptTouchEvent(ViewGroup)
    7.状态的恢复与保存
    自定义实现方式:
    ①.将几种已有的控件组合在一起,形成一种新的效果;--->伪自定义的方式.
        ProgressBar+TextView:自定义的进度条效果.
          优点:写起来简单,好理解;
           缺点:后期修改维护和使用的都比较麻烦,不够灵活;

    ②.继承一个已有的控件,给它添加它没有的功能.
           ImageView.


    ③.继承View,造出一种全新的控件.通过复写onDraw(),onMeasure();
           先测量--->(可能会有一个布局的过程)--->最后绘制.
           onMeasure()--->onDraw().

           测量:要记得把测量出来的范围和大小给记录下来.
           setMeasuredDimension(width,height);

           onDraw():系统只会默认调用一次.要想让视图"动起来",得需要不停地调用onDraw()方法;
           invalidate():让当前视图失效的方法.

           onTouchEvent():往往在自定义View的时候,都需要处理事件.

        ④.继承ViewGroup,一般也会复写onDraw(),必须复写onLayout();
   
           onMeasure()--->onLayout()--->onDraw().

4.Android常用性能优化
    1.合理管理内存
        1.节制的使用Service
        如果应用程序需要使用Service来执行后台任务的话,只有当任务正在执行的时候才应该让Service运行起来。当启动一个Service时,系统会倾向于将这个Service所依赖的进程进行保留,系统可以在LRUcache当中缓存的进程数量也会减少,导致切换程序的时候耗费更多性能。我们可以使用IntentService,当后台任务执行结束后会自动停止,避免了Service的内存泄漏。
        2.当界面不可见时释放内存
        重写Activity的onTrimMemory()方法
        3.当内存紧张时释放内存
        4.避免在Bitmap上浪费内存
        5.是有优化过的数据集合
         SparseArray、SparseBooleanArray、LongSparseArray
        6.知晓内存的开支情况    
            1.使用枚举通常会比使用静态常量消耗两倍以上的内存,尽可能不使用枚举
            2.任何一个Java类,包括匿名类、内部类,都要占用大概500字节的内存空间
            3.任何一个类的实例要消耗12-16字节的内存开支,因此频繁创建实例也是会在一定程序上影响内存的
            3.使用HashMap时,即使你只设置了一个基本数据类型的键,比如说int,但是也会按照对象的大小来分配内存,大概是32字节,而不是4字节,因此最好使用优化后的数据集合
        7.谨慎使用抽象编程
        8.尽量避免使用依赖注入框架
    2.分析内存的使用情况
        1.Android的GC操作
        2.Android中内存泄漏
    3.高性能编码优化
        1.避免创建不必要的对象
        2.静态优于抽象
    4.布局优化技巧
        1.重用布局文件
        2.仅在需要时才加载布局
5.事件分发机制
    事件分发分外3部分
    1.事件分发
        返回值 true:自己处理 不会向下传递
               false:分为两种情况
                       1.如果当前View来自Activity那么交给Activity的onTouchEvent进行处理
                       2.如果当前View来自父控件,那么就交给父View的onTouchEvent进行处理
               默认返回值.交给当前View的onInterceptTouchEvent方法去处理
    2.事件拦截
        返回值 true:表示拦截当前事件,交给当前View的onTouchEvent处理
               false:交给子View的dispatchTouchEvent处理
               默认值:如果当前View是最小的View 默认拦截,交给当前ViewD的onTouchEvent进行处理
    3.事件处理(响应)
        返回值 true:接收并消费该事件
               false:返回上一层的onTouchEvent处理 如果还是默认值,继续返回 如果还是不处理 ,那么该事件就会消失,并且在也接收不到这个消息啦

6.第三方库
7.5.0出新的新布局
    1.协调布局(CoordinatorLayout)
    2.NestedScrollView
    3.CardView(卡片视图)
    4.SnackBar(升级的吐司)
    5.TextInputLayout(TextInputLayout不能单独使用,需要包裹EditView组件。)TextInputEditText:
    6.NavigationView(与DrawerLayout结合使用)
    7.AppBarLayout
    8.CollapsingToolbarLayout
8.动画:动画.

    一.补间(View)动画Tween Animation:(透明,旋转,缩放,平移,动画集合).
    创建方式2种.
    <1>.java代码:
   //fromXType:
   //Animation.RELATIVE_TO_SELF:0.5f--->控件自身x轴的起点值+0.5*自身的宽度
   //Animation.RELATIVE_TO_PARENT,0.5f--->自身起点的值+0.5*控件父窗体的宽度
   RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 1f, Animation.RELATIVE_TO_SELF, 1f);
   ra.setDuration(3000);
   ra.setRepeatCount(2);
   ra.setRepeatMode(Animation.REVERSE);
   ra.setFillAfter(true);
   ivHouzi.startAnimation(ra);

  动画集合:
   //参数:是否共用同一个插值器效果.
   AnimationSet set = new AnimationSet(true);
   set.addAnimation(ta);

<2>.xml文件:
    在res目录下建立一个anim文件夹,然后建立对应的xml文件.
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="2000"
           android:fromXDelta="0"
           android:fromYDelta="0"
           android:repeatCount="2"
           android:interpolator="@android:anim/anticipate_overshoot_interpolator"
           android:toXDelta="200"
           android:toYDelta="200">
    </translate>
   
   然后在代码中:
   //补间动画资源引用的方式:
   Animation ta = AnimationUtils.loadAnimation(this, R.anim.trans_animation);
   ivHouzi.startAnimation(ta);

二.帧动画Frame Animation:
步骤:
①.建立一个drawable-hdpi文件夹,放置多张图片;
②.在drawable目录,建立一个xml文件,该文件的根节点,animation-list.
   在这个文件中,写多个item:drawable和duration.
③.把这个xml文件作为某个控件的background.
④.在java代码中,AnimationDrawable drawable=(AnimationDrawable)iv.getBackground();   
   drawable.start();

三.属性动画(Property Animation):
   通过改变控件自身的属性,来使得该控件动起来.

使用方法:
<1>.java代码创建:
    ObjectAnimator alpha = ObjectAnimator.ofFloat(ivShow, "alpha", 0, 0.2f, 0, 0.4f, 0, 0.8f, 1);
    alpha.setRepeatCount(2);
    alpha.setDuration(3000);
    alpha.start();

<2>.xml文件创建:
 在res/文件夹下,创建一个animator文件夹,然后创建一个根节点是objectAnimator的xml文件.

 //加载一个动画资源
 Animator animator = AnimatorInflater.loadAnimator(this, R.animator.trans_animator);
 //动画的执行目标
 animator.setTarget(ivShow);
 //2秒后开始执行
 //animator.setStartDelay(2000);
 animator.start();

9.视频直播问题
    1.视频的编码格式
        1.图像的处理是采用H.264
        2.音频和AAC
    2.直播协议
        rtmp 传输的延迟1-3秒 采用TCP长链接(手机直播常见)
        rtsp
        hls 传输延迟大于10秒 采用HTTP短链接 传输内容包括2部分 1是M3U8 2.是TS媒体文件
        http-flv 传输延迟1-3秒 采用HTTP长链接 
    3.
        ffmpeg市面上90%以上的播放器
        哔哩哔哩开源
        金山
10.Android各种数据存储方式
    第一种: 使用SharedPreferences存储数据
    第二种: 文件存储数据
    第三种:SQLite存储数据
    使用ContentProvider存储数据;
     网络存储数据;
11.图片上传压缩
12.handlerthread
13.内部存储路径和外部存储路径
14.service传值
15.打包数据库到APK中
15.自定义View
16.OkHttp
    一.OkHttp:
1.概念:Square公司提供的第三方网络访问框架;

2.优点:
  ①.支持Http/Https等网络访问协议;
  ②.内部采用Connection Pooling连接池策略,可以减少网络延迟时间;
  ③.采用Gzip压缩,可以大大的减少网络传输数据的大小,从而提高传输速率;
  ④.采用Response Cache响应缓存机制,可以减少重复的网络请求次数.
   概括起来说OkHttp是一款优秀的HTTP框架,它支持get请求和post请求,支持基于Http的文件上传和下载,支持加载图片,
支持下载文件透明的GZIP压缩,支持响应缓存避免重复的网络请求,支持使用连接池来降低响应延迟问题。

3.用法:
  get请求和post请求.

4.原理(为什么这么用?):  
  OkHttp网络访问的流程:
  主要是通过Diapatcher不断从RequestQueue中取出请求(Call),根据是否已缓存调用Cache或Network这两类数据获取接口之一,
从内存缓存或是服务器取得请求的数据。该HttpEngine引擎有同步和异步请求,同步请求通过Call.execute()直接返回当前的Response,
而异步请求会把当前的请求Call.enqueue添加(AsyncCall)到请求队列中,并通过回调(Callback)的方式来获取最后结果.

  分析OkHttp里面的几个重点类:
  Route.java;//请求地址封装类
  Platform.java;//用来处理平台适应类
  Connnection.java;//连接类
  ConnnectionPool.java;//连接池
  Request.java;//请求队列
  Response.java;//响应请求队列
  Call.java;//请求类
  Dispatcher.java;//派发器
  HttpEngine.java;//网络请求
  Cache.java;//响应缓存
  OkHttpClient.java;//

17.Picasso
    1.简介:
Picasso是Square公司开源的一个Android图形缓存库。可以实现图片下载和缓存功能。

2.特点:
  ①.加载载网络或本地图片并自动缓存处理;
  ②.链式调用;
  ③.图形转换操作,如变换大小,旋转等,提供了接口来让用户可以自定义转换操作;
  ④.在Adapter中回收和取消当前的下载功能;

3.与Universal-ImageLoader(UIL)库对比:
  ①.都有高效的网络图片下载和缓存性能;
  ②.Universal-ImageLoader功能多,灵活使用配置;
  ③.Picasso使用复杂的图片压缩转换来尽可能的减少内存消耗;
  ④.在Adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题;

4.用法:
  ①.图片转换:转换图片以适应布局大小并减少内存占用
    Picasso.with(context).load(url).resize(50, 50) .centerCrop() .into(imageView);
  ②.Adapter 中的下载:Adapter的重用会被自动检测到,Picasso会取消上次的加载;
  ③.空白或者错误占位图片设置方法及本地资源文件的加载方法;
  ④.Picasso采用链式调用加载和处理图片方式;
  ⑤.除了加载网络图片,picasso还支持加载Resources, assets, files, contentproviders中的本地资源文件;

5.原理及源码解析:
  ①.Cache,8缓存类:
      LruCache,主要是get和set方法,存储的结构采用了LinkedHashMap,这种map内部实现了LRU算法(Least Recently Used 近期最少使用算法),链表结构。
  ②.Request,操作封装类:
      所有对图形的操作都会记录在这里,供之后图形的创建使用,如重新计算大小,旋转角度,也可以自定义变换,只需要实现Transformation,一个bitmap转换的接口
  ③.Action:
      Action代表了一个具体的加载任务,主要用于图片加载后的结果回调,有两个抽象方法,complete和error,
也就是当图片解析为bitmap后用户希望做什么。最简单的就是将bitmap设置给imageview,失败了就将错误通过回调通知到上层
  ④.BitmapHunter:"图片猎人".
     获取(下载/加载)图片及解码图片的核心类.该类中最核心的方法有2个:hunt()和decode();Bitmap result=hunt():"捕猎"--->加载图片的方法.
     解码图片的方法:decode();
     BitmapHunter是一个Runnable,其中有一个decode的抽象方法,用于子类实现不同类型资源的解析。
  ⑤.Dispatcher任务调度器:
     在bitmaphunter成功得到bitmap后,就是通过dispatcher将结果传递出去的,当然让bitmaphunter执行也要通过Dispatcher。
Dispatcher内有一个HandlerThread,所有的请求都会通过这个thread转换,也就是请求也是异步的,这样应该是为了Ui线程更加流畅,
同时保证请求的顺序,因为handler的消息队列,外部调用的是dispatchXXX方法,然后通过handler将请求转换到对应的performXXX方法。     
18.Glide
    1.简介.

2.Glide对比Picasso--->优点.
①.不但可以用context,还可以用Activity,Fragment以及FragmentActivity;
   图片加载会和Activity/Fragment的生命周期保持一致,比如 Paused状态在暂停加载,在Resumed的时候又自动重新加载
②.支持Gif图片,前提是该图片真的是Gif图片.
③.支持自定义动画;
④.可以加载一个视频的缩略图,thumbnail()方法.
⑤.加载同一张图片,Glide占得内存会更小(RGB-565),缺点是质量相对差一些.
⑥.Glide加载图片的速度相对于Picasso要快一点;

3.使用.
    //跳过内存缓存.
    //skipMemoryCache(true)
    //磁盘缓存策略.
    //DiskCacheStrategy.NONE-->不进行磁盘缓存
    //DiskCacheStrategy.RESULT-->缓存的是压缩后的图片;
    //DiskCacheStrategy.SOURCE-->缓存的是原图.
    //DiskCacheStrategy.ALL-->会缓存两个图片,缓存后的和原图.
Glide.with(this).load(url).centerCrop().error(R.mipmap.ic_launcher).placeholder(R.mipmap.ic_launcher).override(400, 400).priority(Priority.HIGH).diskCacheStrategy(DiskCacheStrategy.RESULT).into(ivShow);

4.原理和源码:
19、handler的消息机制,looper对象什么时候创建

    class LooperThread extends Thread {

                               public Handler mHandler;

                               public void run() {

                                               Looper.prepare();

                                               mHandler = new Handler() {

                                                               public void handleMessage(Message msg) {

                                                                              // process incoming messages here

                                                               }

                                               };

                                               Looper.loop();

                               }

                }

在创建Handler之前,为该线程准备好一个Looper(Looper.prepare),然后让这个Looper跑起来(Looper.loop),抽取Message,这样,Handler才能正常工作。

20、方法重写、方法重载、方法重构的区别?

1、方法重写:即覆盖,指对父类的方法进行修改,要求必须继承父类

2、方法重载:指方法重载,方法名相同,但参数类型及个数必须有所不同。

3、重构:重构指对代码结构重新构造,优化软件结构,提升代码质量

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值