Android面试总结

Activity生命周期(7个方法)


Android面试总结_第1张图片

Fragment (生命周期11个方法)


Android面试总结_第2张图片

Fragment 执行hide、show生命周期执行:

        当使用hide、show方法来控制Fragment使用时,Fragment生命周期将不执行,在onResume以及onPause方法处理的事情将由onHiddenChange进行管理,当Fragment调用hide隐藏时,

   该方法会被调用,传入参数为true,表示该Fragment被隐藏了,当Fragment调用了show方法后,该方法传入的参数为false,表示该Fragment正在显示。

        onHiddenChange 回调时机:

         当使用add()+show()、hide()跳转到新的Fragment时,旧的Fragment回调 onHiddenChanged(),不会回调onStop()等生命周期方法,而新的Fragment在创建时是不会回调onHiddenChanged()。

https://www.cnblogs.com/zty-Love/p/8656151.html

Activity启动模式(4种)

Service (2)和BroadCast

Service 两种启动模式


Android面试总结_第3张图片
Android面试总结_第4张图片

Android APP 启动流程

Activity启动流程

Q:Activity的启动过程?

技术点:Activity启动、ActivityManagerServie、ApplicationThread

思路:可大致介绍Activity启动过程涉及到的类,尤其是ActivityManagerServie、ApplicationThread从中发挥的作用。

调用startActivity()后经过重重方法会转移到ActivityManagerService的startActivity(),并通过一个IPC回到ActivityThread的内部类ApplicationThread中,并调用其scheduleLaunchActivity()将启动Activity的消息发送并交由Handler H处理。Handler H对消息的处理会调用handleLaunchActivity()->performLaunchActivity()得以完成Activity对象的创建和启动。

Android事件分发机制 详解攻略,您值得拥有

首先你需要知道一点,只要你触摸到了任何一个控件,就一定会调用该控件的dispatchTouchEvent方法。那当我们去点击按钮的时候,就会去调用Button类里的dispatchTouchEvent方法,可是你会发现Button类里并没有这个方法,那么就到它的父类TextView里去找一找,你会发现TextView里也没有这个方法,那没办法了,只好继续在TextView的父类View里找一找,这个时候你终于在View里找到了这个方法。

[https://blog.csdn.net/carson_ho/article/details/54136311](https://blog.csdn.net/carson_ho/article/details/54136311)

事件传递机制 (同时执行几个方法 on touch

on touch event

    up (on click )

on long click

ACTION_DOWN:主要包括了setPressed和checkForLongClick两个操作:

setPressed用于设置按下状态,此时PFLAG_PRESSED标志位被设置。

checkForLongClick用于检查LongClick是否可以触发,以及发送延迟消息来响应长按事件。

view绘制流程

Handler Loop 机制

IPC

Bindle 机制

多线程

jvm

    jmm

okhttp

retrofit

glide

rxjava

volley 请问volley为什么不适合传输大数据

volley中为了提高请求处理的速度,采用了ByteArrayPool进行内存中的数据存储的,如果下载大量的数据,这个存储空间就会溢出,所以不适合大量的数据,但是由于他的这个存储空间是内存中分配的,当存储的时候优是从ByteArrayPool中取出一块已经分配的内存区域, 不必每次存数据都要进行内存分配,而是先查找缓冲池中有无适合的内存区域,如果有,直接拿来用,从而减少内存分配的次数 ,所以他比较适合大量的数据量少的网络数据交互情况。

HttpClient和HttpURLConnection区别

1、HttpURLConnection是java的标准类,没有做封装,用起来比较原始

2、HttpClient是开源框架,封装了访问HTTP的请求头、参数、内容体、响应等;HttpURLConnection中的输入输出流操作,在这个接口中被统一封装成了HttpPost(HttpGet)和HttpResponse。这样,减少了操作的繁琐性。

性能方面:

HttpURLConnection的访问速度比HttpClient要快。

哪一种方式是最好的?

HttpClient 在 Android 2.2 之前拥有比较少的 bug,因此选择它是最好的选择。

在 Android 2.3 及以后,HttpURLConnection 是最好的选择。它那简单的 API 以及小尺寸使其非常适合 Android。透明的压缩和响应缓存减少了网络的使用,提高速度以及节省电量。新的应用程序中应使用 HttpURLConnection。我们未来也会将更多的精力花在优化 HttpURLConnection 上面。

sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。初始5000条记录也就是要5000次读写磁盘操作, 将会重复的打开关闭数据库文件5000次,所以速度当然会很慢。而且不能保证所有数据都能同时插入。

解决方法:

添加事务处理,把5000条插入作为一个事务

我们使用SQLite的事务进行控制:

db.beginTransaction();  //手动设置开始事务

try{

//批量处理操作

for(Collection c:colls){

insert(db, c);

}

db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交。

//在setTransactionSuccessful和endTransaction之间不进行任何数据库操作

}catch(Exception e){

MyLog.printStackTraceString(e);

}finally{

db.endTransaction(); //处理完成

}

Android广播机制

广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver便是Android四大组件之一。

BroadcastReceiver分为两类:

静态广播接收者:通过AndroidManifest.xml的标签来申明的BroadcastReceiver。

动态广播接收者:通过AMS.registerReceiver()方式注册的BroadcastReceiver,动态注册更为灵活,可在不需要时通过unregisterReceiver()取消注册。

从广播发送方式可分为三类:

普通广播:通过Context.sendBroadcast()发送,可并行处理

有序广播:通过Context.sendOrderedBroadcast()发送,串行处理

Sticky广播:通过Context.sendStickyBroadcast()发送,发出的广播会一直滞留(等待),以便有人注册这则广播消息后能尽快的收到这条广播。

Android 中的 Broadcast 实际底层使用Binder机制。


Q:获取Bitmap对象并计算它所占用的内存大小

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.size);

int size = bitmap.getByteCount();

getByteCount()源码:

public final int getByteCount() {

    return getRowBytes() * getHeight();

}

getHeight():图片的高度(单位为px), getRowBytes方法返回的是图片的像素宽度与色彩深度的乘积。

所以getByteCount()是这样计算的:像素宽 * 像素高 * 色彩深度,其中色彩深度与Bitmap的色彩格式有关,默认为ARGB_8888.

### 这里补充一个小知识点吧!

ARGB_4444: 2bytes 每个像素占据2 个字节:A(Alpha)占4位的精度,R(Red)占4位的精度,G(Green)占4位的精度,B(Blue)占4位的精度,加起来一共是16位的精度,折合是2个字节,也就是一个像素占两个字节的内存,同时存储位图的透明度和颜色信息。

ARGB_8888 : 4bytes 每个像素占据4 个字节:这个类型的跟ARGB_4444的原理是一样的,只是A,R,G,B各占8个位的精度,所以一个像素占4个字节的内存。由于该类型的位图质量较好,官方特别推荐使用。但是,如果一个480*800的位图设置了此类型,那个它占用的内存空间是:480*800*4/(1024*1024)=1.5M

RGB_565 : 2bytes 每个像素占据2 个字节:R占5位精度,G占6位精度,B占5位精度,一共是16位精度,折合两个字节。这里注意的时,这个类型存储的只是颜色信息,没有透明度信息

Q:为什么不能在子线程中更新UI ?

一般我们在项目中,进行联网请求后,这里我们就用子线程来表示联网请求,开了线程后获取到我们服务器返回的数据后,需要去更新UI,在这里我们就需要去调用setText()、setImageView()、setVisibility()等等等等,不管你调用的什么方法,它都会去调用 ViewRootImpl 中的 checkThread(),所以关键在于checkThread()这个方法

checkThread()方法分析:

1>:checkThread()方法作用是用来检测线程,源码如下:

void checkThread() {        if (mThread != Thread.currentThread()) {            throw new CalledFromWrongThreadException(                    "Only the original thread that created a view hierarchy can touch its views.");        }    }

2>:if (mThread != Thread.currentThread()) 中的 Thread.currentThread()是子线程,而mThread是在构造方法中初始化的 是主线程 [ MainThread ]

如果两个不相等,那么那么左边就是主线程、右边就是子线程;

如果两个相等,那么就是主线程

由上边源码可知:

如果两个相等,就说明两个都是在主线程中,那么就不会调用下边的异常;

如果两个不相等,就说明是在子线程中更新UI,那么就会调用checkThread()方法,就会抛出下边的异常Only the original thread that created a view hierarchy can touch its views.

这个只解释了如果在子线程更新UI为什么会抛异常;真正不能再自在子线程更新UI的原因是:UI控件非线程安全,在多线程中并发访问可能会导致UI控件处于不可预期的状态。而不对UI控件的访问加上锁机制的原因有:

上锁会让UI控件变得复杂和低效

上锁后会阻塞某些进程的执行


2018 最新 Android 面试题总结(一)

2018最新 Android 面试题总结(二)

2018最新 Android 面试题总结(三)

2018最新 算法面试题总结(一)

2018最新 计算机 网络面试题总结(一)

2018最新 java 面试题总结(一)

https://www.jianshu.com/p/399ca1b4e0c3

你可能感兴趣的:(Android面试总结)