美文网首页
Android笔记

Android笔记

作者: 提起裙摆做女王i | 来源:发表于2023-07-25 20:23 被阅读0次

    1,AIDL每次传输数据大小,应小于()
    答:受限于Android本身对AIDL的设计,利用AIDL传输的数据大小不得大于1MB,否则会报TransactionTooLargeException。

    2,屏幕事件的分发,可以通过()方法,返回()拦截此次事件,拦截后此次事件不再向子View传递
    答:事件分发中科院用过onInterceptTouchEvent方法,返回为true拦截此次事件,不再向子view传递

    3,git pull命令相当于get fetch与git()命令的组合
    答:git merge

    4,为了灵活搭配参数,可以使用()设计模式
    答: 建造者模式

    5,一个未启动的serviceA,先通过startService启动,再通过bindservice启动,生命周期函数调用执行顺序如下()
    答:onCreate-->onStartCommand-->onStart-->onBind-->(onServiceConnected)

    6,进程间数据交互有哪些方法()
    答:使用Bundle,使用AIDL,使用ContentProvider

    7,Android自动化测试框架是(至少两种)()
    答:Monkey,MonkeyRunner,UIAutomator,Robotium,Appium,Instrumentation,Espresso,Selendroid

    8,Android中常见的TweenAnimation-补间动画,有哪些?至少答出两种
    答:平移动画:<translate> TranslateAnimation
    缩放动画:<scale> ScaleAnimation
    旋转动画:<rotate> RotateAnimation
    透明度动画:<alpha> AlphaAnimation

    9,MMKV和SharedPreference类似都是一种()存储
    答:轻量级

    10,在自定义动画中,一般采用()来控制动画变化的速率
    答:动画插值器,Timelnterpolator

    11,一个线程最多有()个looper和()个messageQueue
    答:一个线程可以有多个Handler,只有一个Looper,只有一个MessageQueue。多个Handler共用一个Looper和MessageQueue。

    12,使用SharePreference保存数据,调用()接口可以做到同步存储数据
    答:commit()方法可以同步保存数据
    apply()方法为异步保存数据

    13,ARGB_4444每个像素占用()内存
    答:理论上图片占用内存计算:图片占用内存=宽度像素高度像素单个像素占的字节数。
    Android中的四个色彩模式:
    ALPHA_8:每个像素占用1byte内存
    ARGB_4444:每个像素占用2byte内存
    ARGB_8888:每个像素占用4byte内存
    RGB_565:每个像素占用2byte内存

    14,通过adb链接设备后,可以通过什么指令来查看包名com.mxnavi.sampie应用的详细内存信息()
    答:adb shell dumpsys meminfo com.mxnavi.sampie

    15,主线程出现ANR异常,出现anr之后,由()会输出一个trace文件到()目录。
    答:出现ANR系统会输出一个trace.txt文件,目录在/data/anr中

    16,在ActivityA中启动一个未启动过的ActivityB执行生命周期函数的顺序应该为()
    答:a. A-onCreate()
    b. A-onStart()
    c. A-onResume()
    ----启动B----
    d. A-onPause()
    e. B-onCreate()
    f. B-onStart()
    g. B-onResume()
    h. A-onStop()

    17,为了防止横竖屏切换时,Activity不重新创建,需要在AndroidManifest()属性中,增加()配置
    答:需要在manifest中配置 android:configChanges="orientation|keyboardHidden"属性,当然在api>13的时候,需要额外添加一个参数,就是 screenSize ,不添加这个,在api 13以上的手机是不会生效的。

    18,当我们要制作一个可以横向滚动的超屏布局时,需要使用()布局View来实现
    答:HorizontalScrollView 和 ScrollView 都是由 FrameLayout 派生出来的。它们就是一个用于为普通组件添加滚动条的组件。且 HorizontalScrollView 和 ScrollView 里面最多只能包含一个组件(当然组件里面还可以嵌套组件)。它们不同的是 HorizontalScrollView 用于添加水平滚动,而 ScrollView 用于添加垂直滚动。

    19,如何通过git命令合并两次提交,要求change id 不变()
    答:区分两个场景

    • 第二次commit之前提交,当第一次push之后
      step1.vi new_add.txt添加新的文件
      step2.git add new_add.txt
      step3.git commit --amend把文件和上一次提交合并
      step4.git pus origin HEAD:refs/for/$branch
    • 第二次commit之后提交,当第二次提交已经执行了push之后,发现生成了两个change-Id
      step1.查看提交历史记录,git log
      step2.选择要合并的commit,“2”代表要合并最新的3条commit
      git rebase -i HEAD~2
      step3.修改要保留的commit和要合并的commit
      pick代表选择这个commit,squash代表合并这个commit或者用s也可以
      step4.修改commit的文字描述。不需要的commit描述也注释掉
      step5.git push origin xxxx -f

    20,自定义View可以通过重写()方法获得Canvas
    答:重写onDraw()

    问答题
    21,写一个简单的线程池,(不适用线程池API),包括线程管理,任务管理,线程池大小可设置。

    /**
     * 自定义简单线程池
     */
    public class MyThreadPool{
        /**存放线程的集合*/
        private ArrayList<MyThead> threads;
        /**任务队列*/
        private ArrayBlockingQueue<Runnable> taskQueue;
        /**线程池初始限定大小*/
        private int threadNum;
        /**已经工作的线程数目*/
        private int workThreadNum;
        
        private final ReentrantLock mainLock = new ReentrantLock();
        
        public MyThreadPool(int initPoolNum) {
            threadNum = initPoolNum;
            threads = new ArrayList<>(initPoolNum);
            //任务队列初始化为线程池线程数的四倍
            taskQueue = new ArrayBlockingQueue<>(initPoolNum*4);
            
            threadNum = initPoolNum;
            workThreadNum = 0;
        }
        
        public void execute(Runnable runnable) {
            try {
                mainLock.lock();
                //线程池未满,每加入一个任务则开启一个线程
                if(workThreadNum < threadNum) {
                    MyThead myThead = new MyThead(runnable);
                    myThead.start();
                    threads.add(myThead);
                    workThreadNum++;
                }
                //线程池已满,放入任务队列,等待有空闲线程时执行
                else {
                    //队列已满,无法添加时,拒绝任务
                    if(!taskQueue.offer(runnable)) {
                        rejectTask();
                    }
                }
    
    

    22,简述SurfaceView双缓冲机制
    答:SurfaceView的双缓冲机制是为了防止闪烁和卡顿现象。在绘制过程中,通常会发生不可避免的计算机IO延迟,这可能会导致屏幕绘制停顿。
    如果没有双缓冲机制,在主线程更新UI的同时,绘制的结果也将立即呈现在前台界面上,这可能导致视觉上的不连续性和闪烁。
    双缓冲机制会维护两个Surface对象,一个在前台,呈现在屏幕上,另一个在后台,后台绘制,在绘制之前,将要绘制的内容先绘制到后台Surface上,然后前后交换两个Surface,这样前台Surface就显示了最新的绘制结果。
    整个缓冲机制的过程如下:

    • 创建两个Surface对象,分别是前台和后台surface
    • 获取后台surface上的canvas对象
    • 在canvas对象上绘制要显示的内容
    • 将后台surface上的内容复制到前台surface
    • 显示前台surface上的内容

    23,在自定义View中,除了构造函数需要重写的方法有哪三个,分别的作用是什么?
    答:测量:onMeasure(),作用决定了View的大小
    布局:onLayout(),作用决定View在ViewGruop中的位置
    绘制:onDraw(),作用决定绘制View

    24,AIDL是什么?工作原理是什么?如何优化多模块都使用AIDL的情况?
    答:AIDL是android提供的接口定义语言,Android Interface Definition Language。简化Binder的使用,轻松地实现IPC进程间通信机制,AIDL生成一个对象的代理类,通过它客户端可以实现间接调用服务端对象的方法。
    如果优化多模块都使用AIDL:
    每个业务模块创建自己的AIDL接口并创建Stub的实现类,向服务端提供自己的唯一标识和实现类。服务端只需要一个Service,创建Binder连接池接口,根据业务模块的特征来返回相应的Binder对象。客户端调用时通过Binder连接池,即将每个业务模块的Binder请求统一转发到一个远程Service中执行,从而避免重复创建Service。
    工作原理:
    客户端AIDLActivity和服务器端AIDLService是同过BookManager这个aidl接口文件来实现通信的,从用户角度看,是AIDLService和AIDLActivity在进行通信,实际上是客户端的本地代理Proxy在和服务器端的Stub类通过transact和onTransact进行通信;
    梳理一下Stud-Proxy的工作流程:
    (1)AIDLService中的IBinder对象mBookManager是Stub的具体实现,在AIDLService和AIDLActivity绑定的时候被返回;
    (2)被返回的mBookManager最终作为客户端onServiceConnected中的参数;
    (3)客户端AIDLActivity会通过本地代理Proxy调用Stub中的静态方法asInterface,mServiceBinder作为参数,最后拿到接口对象mBookManager;
    在asInterface方法中,有如下判断流程:
    (1)判断Binder是否处于当前进程,若不在,则构建Proxy并返回,构建Proxy时,把mBookManager赋值给mRemote;
    (2)Proxy在实现的接口getInformation会调用mRemote的transact方法,而Binder的通信是靠transact和onTransact实现的;
    (3)最后会走到Stub的onTransact,完成对mServiceBinder的调用;

    25,dispatchTouchEvent return false,return true,return super.dispatchTouchEvent
    onInterceptTouchEvent return false, retur true, return super.onInterceptTouchEvent
    onTouchEvent return false ,return true,return super.onTouchEvent
    描述一下以上三个方法的三种不同return的含义?
    答: dispatchTouchEvent 的三个返回值代表含义

    • true 表示这个事件被当前的View消费,会传递给当前View的onInterceptTouchEvent方法处理。
    • false 表示这个事件不会再往上(内)层的View传递,而是直接交给下(外)层View的onTouchEvent方法去处理
    • super.ondispatchToucEvent() 表示会将此事件传递给上(内)层View的dispatchOnTouchEvent方法去处理。
      答:onInterceptTouchEvent的三个返回值代表含义
      (注:View没有onInterceptTouchEvent方法,ViewGroup才有)
    • true 按下去的drown事件被onInterceptTouchEvent处理完后返回true,之后的move,up等方法就不会交由onInterceptTouchEvent处理,而是全部(包括drown事件)全部交给改层的onTouchEvent去处理。这样,目标View接收不到任何事件。
    • false 按下去的down事件被onInterceptTouchEvent处理完之后返回false,之后的move,up等方法会继续交由onInterceptTouchEvent处理,然后全部(包括down事件)往下传递,直到交由目标View的onTouchEvent去处理。
    • super.onInterceptTouchEvent 和返回false是一样的。
      答:onTouchEvent()的三个返回值:
    • false 如果最终需要处理事件的View的onTouchEvent()返回的是false,那么该事件将被传递至上一层的view的onTouchEvent处理。
    • true 如果最终需要处理事件的View的onTouchEvent()返回的是true,那么后续事件将可以继续传递给该View的onTouchEvent()处理。
    • super.onTouchEvent()与返回true一样。

    相关文章

      网友评论

          本文标题:Android笔记

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