美文网首页Android进阶之路Android开发Android开发经验谈
字节跳动的这几个Android开发面试题,你总会遇到!

字节跳动的这几个Android开发面试题,你总会遇到!

作者: Android进阶小麦 | 来源:发表于2020-08-18 22:15 被阅读0次

    如何把一个应用设置为系统应用

    • Android设置是Debug版本,且root,直接将该apk用adb工具push到system/app或system/priv-app
    • 如果是非root设备,需要编译后烧写镜像
    • 有些权限(如WRITE_SECURE_SETTINGS)不开放给第三方应用,只能在对应设备源码总编译然后作为系统app使用

    Activity,Window,View三者的联系和区别?

    • Activity像一个工匠(控制单元)
    • Window像窗户(承载模型)
    • View像窗花(显示视图)
    • LayoutInflater像剪刀
    • Xml配置像窗花图纸。

    Android两个应用能在同一个任务栈吗?

    可以

    Fragment是什么?你曾经遇到哪些有关Fragment的问题?

    • Fragment可以作为Activity界面的一部分组成出现
      • 其作用是:碎片整理,局部刷新。
    • 一个Activity中可以同时出现多个Fragment,并一个Fragment也可以在多个Activity中使用.
    • 在Activity中可以添加,删除,替换Fragment.Fragment可以响应自己的输入时间,并且有自己的生命周期,但其生命周期收Activity影响

    Fragment生命周期

    《Android初级、中级面试题收录(2)》

    如何实现Activity窗口快速变暗

    利用只读属性动画+WindowManager

     /*
      *@param from\>=0&&from\<=1.0f
      * @param to\>=0&&to\<=1.0f
      *
      * */
     private void dimBackground(final float from, final float to) {
     final Window window = getWindow();
     ValueAnimator valueAnimator = ValueAnimator.ofFloat(from, to);
     valueAnimator.setDuration(500);
     valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
     @Override
     public void onAnimationUpdate(ValueAnimator animation) {
     WindowManager.LayoutParams params = window.getAttributes();
     params.alpha = (Float) animation.getAnimatedValue();
     window.setAttributes(params);
     }
     });
     valueAnimator.start();
     }
    

    是否使用过本地广播,和全局广播有什么区别?

    本地广播在本应用范围内传播,不用担心隐私数据泄露,不用担心别的应用伪造广播.相比全局广播,本地广播更高效.

    注册广播的几种方法?

    • 1.静态注册:在清单文件中注册, 常见的有监听设备启动,常驻注册不会随程序生命周期改变
    • 2.动态注册:在代码中注册,随着程序的结束,也就停止接受广播了补充一点:有些广播只能通过动态方式注册,比如时间变化事件、屏幕亮灭事件、电量变更事件,因为这些事件触发频率通常很高,如果允许后台监听,会导致进程频繁创建和销毁,从而影响系统整体性能

    为什么Android引入广播机制?

    • a:从MVC的角度考虑(应用程序内) 其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。
      • android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构
      • 它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。
    • b:程序间互通消息(例如在自己的应用程序内监听系统来电)
    • c:效率上(参考UDP的广播协议在局域网的方便性)
    • d:设计模式上(反转控制的一种应用,类似监听者模式)

    了解IntentServices吗?

    • IntentService是Service的子类,是一个异步的,会自动停止的服务,很好解决了传统的Service中处理完耗时操作忘记停止并销毁Service的问题
    • 生成一个默认的且与线程相互独立的工作线程执行所有发送到onStartCommand()方法的Intent,可以在onHandleIntent()中处理.
    • 串行队列,每次只运行一个任务,不存在线程安全问题,所有任务执行完后自动停止服务,不需要自己手动调用stopSelf()来停止.

    如何提升Service进程优先级

    在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = “1000”这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。

    ContentProvider和sql的区别

    ContentProvider的主要还是用于数据共享,其可以对Sqlite,SharePreferences,File等进行数据操作用来共享数据。而sql的可以理解为数据库的一门语言,可以使用它完成CRUD等一系列的操作

    数据存储相关

    • 文件存储:通过Java.io.FileInputStream和java.io.FileOutputStream这两个类来实现对文件的读写,java.io.File类则用来构造一个具体指向某个文件或者文件夹的对象。
    • SharedPreferences:SharedPreferences是一种轻量级的数据存储机制,他将一些简单的数据类型的数据,包括boolean类型,int类型,float类型,long类型以及String类型的数据,以键值对的形式存储在应用程序的私有Preferences目录(/data/data/<包名>/shared_prefs/)中,这种Preferences机制广泛应用于存储应用程序中的配置信息。
    • SQLite数据库:当应用程序需要处理的数据量比较大时,为了更加合理地存储、管理、查询数据,我们往往使用关系数据库来存储数据。Android系统的很多用户数据,如联系人信息,通话记录,短信息等,都是存储在SQLite数据库当中的,所以利用操作SQLite数据库的API可以同样方便的访问和修改这些数据。
    • ContentProvider:主要用于在不同的应用程序之间实现数据共享的功能,不同于sharepreference和文件存储中的两种全局可读写操作模式,内容提供其可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险

    如何将打开res aw目录中的数据库文件?

    • 在Android中不能直接打开res aw目录中的数据库文件,而需要在程序第一次启动时将该文件复制到手机内存或SD卡的某个目录中,然后再打开该数据库文件。
    • 复制的基本方法是使用getResources().openRawResource方法获得res aw目录中资源的 InputStream对象,然后将该InputStream对象中的数据写入其他的目录中相应文件中。
    • 在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法来打开任意目录中的SQLite数据库文件。

    什么是aar?aar是jar有什么区别?

    “aar”包是 Android 的类库项目的二进制发行包。
    文件扩展名是.aar,maven 项目类型应该也是aar,但文件本身是带有以下各项的 zip 文件:

    • /AndroidManifest.xml (mandatory)
    • /classes.jar (mandatory)
    • /res/ (mandatory)
    • /R.txt (mandatory)
    • /assets/ (optional)
    • /libs/*.jar (optional)
    • /jni//*.so (optional)
    • /proguard.txt (optional)
    • /lint.jar (optional)

    这些条目是直接位于 zip 文件根目录的。 其中R.txt 文件是aapt带参数–output-text-symbols的输出结果。
    jar打包不能包含资源文件,比如一些drawable文件、xml资源文件之类的,aar可以。

    SQLite支持事务吗?添加删除如何提高性能?

    SQLite作为轻量级的数据库,比MySQL还小,但支持SQL语句查询,提高性能可以考虑通过原始经过优化的SQL查询语句方式处理

    如何将SQLite数据库(dictionary.db文件)与apk文件一起发布?

    可以将dictionary.db文件复制到Eclipse Android工程中的res aw目录中。所有在res aw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。可以将dictionary.db文件复制到res aw目录中

    Android中如何获得手机的唯一标示.

    • 1 首先尝试读取IMEI、Mac地址、CPU号等物理信息(有不少工具可以修改IMEI);
    • 2 如果均失败,可以自己生成UUID然后保存到文件(文件也可能被篡改或删除)

    参考:[blog.csdn.net/xushuaic/ar…]

    mipmap文件夹和drawable文件夹的区别

    它只是用来放启动图标的,好处就是,你只用放一个mipmap图标,它就会给你各种版本(比如平板,手机)的apk自动生成相应分辨率的图标,以节约空间。

    ListView卡顿的原因以及优化策略

    • 重用converView: 通过复用converview来减少不必要的view的创建,另外Infalte操作会把xml文件实例化成相应的View实例,属于IO操作,是耗时操作。
    • 减少findViewById()操作: 将xml文件中的元素封装成viewholder类,通过converview的setTag和getTag方法将view与相应的holder对象绑定在一起,避免不必要的findviewbyid操作
    • 避免在 getView 方法中做耗时的操作: 例如加载本地 Image 需要载入内存以及解析 Bitmap ,都是比较耗时的操作,如果用户快速滑动listview,会因为getview逻辑过于复杂耗时而造成滑动卡顿现象。用户滑动时候不要加载图片,待滑动完成再加载,可以使用这个第三方库glide
    • Item的布局层次结构尽量简单,避免布局太深或者不必要的重绘
    • 尽量能保证 Adapter 的 hasStableIds() 返回 true 这样在 notifyDataSetChanged() 的时候,如果item内容并没有变化,ListView 将不会重新绘制这个 View,达到优化的目的
    • 在一些场景中,ScollView内会包含多个ListView,可以把listview的高度写死固定下来。 由于ScollView在快速滑动过程中需要大量计算每一个listview的高度,阻塞了UI线程导致卡顿现象出现,如果我们每一个item的高度都是均匀的,可以通过计算把listview的高度确定下来,避免卡顿现象出现
    • 使用 RecycleView 代替listview: 每个item内容的变动,listview都需要去调用notifyDataSetChanged来更新全部的item,太浪费性能了。RecycleView可以实现当个item的局部刷新,并且引入了增加和删除的动态效果,在性能上和定制上都有很大的改善
    • ListView 中元素避免半透明: 半透明绘制需要大量乘法计算,在滑动时不停重绘会造成大量的计算,在比较差的机子上会比较卡。 在设计上能不半透明就不不半透明。实在要弄就把在滑动的时候把半透明设置成不透明,滑动完再重新设置成半透明。
    • 尽量开启硬件加速: 硬件加速提升巨大,避免使用一些不支持的函数导致含泪关闭某个地方的硬件加速。当然这一条不只是对 ListView。

    ViewHolder为什么要被声明成静态内部类

    这是个错误提问,ViewHolder主要分装了Adpter的View,如果设置成static的,那么View持有Context不会被回收,这样会造成内存泄露。

    Android中的动画有哪些?

    • 逐帧动画(Drawable Animation):加载一系列Drawable资源来创建动画,简单来说就是播放一系列的图片来实现动画效果,可以自定义每张图片的持续时间
    • 补间动画(Tween Animation):Tween可以对View对象实现一系列简单的动画效果,比如位移,缩放,旋转,透明度等等。但是它并不会改变View属性的值,只是改变了View的绘制的位置,比如,一个按钮在动画过后,不在原来的位置,但是触发点击事件的仍然是原来的坐标。
    • 属性动画(Property Animation):动画的对象除了传统的View对象,还可以是Object对象,动画结束后,Object对象的属性值被实实在在的改变了

    Android动画原理

    • Animation框架定义了透明度,旋转,缩放和位移几种常见的动画,而且控制的是整个View
    • 实现原理是每次绘制视图时View所在的ViewGroup中的drawChild函数获取该View的Animation的Transformation值
    • 然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧,如果动画没有完成,继续调用invalidate()函数,启动下次绘制来驱动动画
    • 动画过程中的帧之间间隙时间是绘制函数所消耗的时间,可能会导致动画消耗比较多的CPU资源,最重要的是,动画改变的只是显示,并不能相应事件

    View绘制相关

    SurfaceView和View的区别

    • SurfaceView中采用了双缓存技术,在单独的线程中更新界面
    • View在UI线程中更新界面

    介绍下自定义view的基本流程

    • 1、 明确需求,确定你想实现的效果
    • 2、确定是使用组合控件的形式还是全新自定义的形式,组合控件即使用多个系统控件来合成一个新控件,你比如titilebar,这种形式相对简单,参考
    • 3、如果是完全自定义一个view的话,你首先需要考虑继承哪个类,是View呢,还是ImageView等子类。
    • 4、根据需要去复写View#onDraw、View#onMeasure、View#onLayout方法
    • 5.根据需要去复写dispatchTouchEvent、onTouchEvent方法
    • 6、根据需要为你的自定义view提供自定义属性,即编写attr.xml,然后在代码中通过TypedArray等类获取到自定义属性值
    • 7、需要处理滑动冲突、像素转换等问题
      谈谈View的绘制流程

    谈谈View的绘制流程 《Android初级、中级面试题收录(2)》

    measure()方法,layout(),draw()三个方法主要存放了一些标识符,来判断每个View是否需要再重新测量,布局或者绘制,主要的绘制过程还是在onMeasure,onLayout,onDraw这个三个方法中

    • 1.onMesarue() 为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性: mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。
    • 2.onLayout() 为将整个根据子视图的大小以及布局参数将View树放到合适的位置上。
    • 3.onDraw() 开始绘制图像,绘制的流程如下
      • 首先绘制该View的背景
      • 调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法)
      • 如果该View是ViewGroup,调用dispatchDraw ()方法绘制子视图
        绘制滚动条

    自定义View执行invalidate()方法,为什么有时候不会回调onDraw()

    • 自定义一个view时,重写onDraw。调用view.invalidate(),会触发onDraw和computeScroll()。前提是该view被附加在当前窗口.
      view.postInvalidate(); //是在非UI线程上调用的
    • 自定义一个ViewGroup,重写onDraw。onDraw可能不会被调用,原因是需要先设置一个背景(颜色或图)。表示这个group有东西需要绘制了,才会触发draw,之后是onDraw。因此,一般直接重写dispatchDraw来绘制viewGroup.自定义一个ViewGroup,dispatchDraw会调用drawChild.

    收集、整理了一套面试题,涵盖各个大厂的面试真题。


    有需要可以点击我的【Github免费领取,里面还有【Android进阶学习全套手册】等等,都是免费分享的

    相关文章

      网友评论

        本文标题:字节跳动的这几个Android开发面试题,你总会遇到!

        本文链接:https://www.haomeiwen.com/subject/sbkljktx.html