android面试宝典

一.基础篇java

1.activity生命周期android

主要场景验证:ios

1.A启动跳转到B,B返回A。
控制台打印结果算法

进入A
A=====onCreate()
A=====onStart()
A=====onResume()
A跳转到B
A=====onPause()
B=====onCreate()
B=====onStart()
B=====onResume()
A=====onStop()
B返回A
B=====onPause()
A=====onStart()
A=====onResume()
B=====onStop()
B=====onDestroy()数据库

2.A启动,App进入后台,App返回前台
控制台打印结果设计模式

进入A
A=====onCreate()
A=====onStart()
A=====onResume()
app进入后台
A=====onPause()
A=====onStop()
app返回前台
A=====onStart()
A=====onResume()
--------------------- 缓存

2.Android的多线程模型有哪几种?网络

Android提供了四种经常使用的操做多线程的方式,分别是: 
1. Handler+Thread 
2. AsyncTask 
3. ThreadPoolExecutor 
4. IntentService 多线程

3.ScrollView是否能够和listView混合使用?如何能够,说明混合使用的方式,若是不行,说明缘由。 
能够,计算整个ListView的高度,填充数据后从新设置ListView高度,重写onMeasure和onInterceptTouchEvent方法并发

4.在建立fragment时如何传递初始化参数?

public static MyFragment newInstance(Bundle args) {
    MyFragment f = new MyFragment();
    f.setArguments(args);
    return f;
}
调用fragment:

Bundle args = new Bundle();
args.putString("text","Hello");
MyFragment f = MyFragment.newInstance(args)

5.如何规避oom? 

1.使用更小的图片

在设计给到资源图片的时候,咱们须要特别留意这张图片是否存在能够压缩的空间,是否可使用一张更小的图片。

2.资源文件须要选择合适的文件夹进行存放

咱们知道hdpi/xhdpi/xxhdpi等等不一样dpi的文件夹下的图片在不一样的设备上会通过scale的处理。例如咱们只在hdpi的目录下放置了一张100100的图片,那么根据换算关系,xxhdpi的手机去引用那张图片就会被拉伸到200200。须要注意到在这种状况下,内存占用是会显著提升的。对于不但愿被拉伸的图片,须要放到assets或者nodpi的目录下。

3.谨慎使用static对象

由于static的生命周期过长,和应用的进程保持一致,使用不当极可能致使对象泄漏,在Android中应该谨慎使用static对象。

4.注意Bitmap复用以及对象的及时回收

5.避免在onDraw方法里面执行对象的建立

相似onDraw等频繁调用的方法,必定须要注意避免在这里作建立对象的操做,由于他会迅速增长内存的使用,并且很容易引发频繁的gc,甚至是内存抖动。

六、 Android的四大组件是哪些,它们的做用?

答:Activity:Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它须要为保持各界面的状态,作不少持久化的事情,妥善管理生命周期以及一些跳转逻辑

service:后台服务于Activity,封装有一个完整的功能逻辑实现,接受上层指令,完成相关的事物,定义好须要接受的Intent提供同步和异步的接口

Content Provider:是Android提供的第三方应用数据的访问方案,能够派生Content Provider类,对外提供数据,能够像数据库同样进行选择排序,屏蔽内部数据的存储细节,向外提供统一的借口模型,大大简化上层应用,对数据的整合提供了更方便的途径

BroadCast Receiver:接受一种或者多种Intent做触发事件,接受相关消息,作一些简单处理,转换成一条Notification,统一了Android的事件广播模型

七、 android中的动画有哪几类,它们的特色和区别是什么 

答:两种,一种是Tween动画、还有一种是Frame动画。Tween动画,这种实现方式可使视图组件移动、放大、缩小以及产生透明度的变化;另外一种Frame动画,传统的动画方法,经过顺序的播放排列好的图片来实现,相似电影。

八、 请介绍下Android的数据存储方式。

答:使用SharedPreferences存储数据;文件存储数据;SQLite数据库存储数据;使用ContentProvider存储数据;网络存储数据;

九、 如何启用Service,如何停用Service。

服务的开发比较简单,以下:

第一步:继承Service类

1

public class SMSService extends Service {}

第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:<service android:name=".SMSService" />

服务不能本身运行,须要经过调用Context.startService()或Context.bindService()方法启动服务。这两个方法均可以启动Service,可是它们的使用场合有所不一样。使用startService()方法启用服务,调用者与服务之间没有关连,即便调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一块儿,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特色。

若是打算采用Context.startService()方法启动服务,在服务未被建立时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。若是调用startService()方法前服务已经被建立,屡次调用startService()方法并不会致使屡次建立服务,但会致使屡次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

若是打算采用Context.bindService()方法启动服务,在服务未被建立时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一块儿,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。若是调用bindService()方法前服务已经被绑定,屡次调用bindService()方法并不会致使屡次建立服务及绑定(也就是说onCreate()和onBind()方法并不会被屡次调用)。若是调用者但愿与正在绑定的服务解除绑定,能够调用unbindService()方法,调用该方法也会致使系统调用服务的onUnbind()-->onDestroy()方法。

服务经常使用生命周期回调方法以下:

onCreate() 该方法在服务被建立时调用,该方法只会被调用一次,不管调用多少次startService()或bindService()方法,服务也只被建立一次。

onDestroy()该方法在服务被终止时调用。

与采用Context.startService()方法启动服务有关的生命周期方法

onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。屡次调用startService()方法尽管不会屡次建立服务,但onStart() 方法会被屡次调用。

与采用Context.bindService()方法启动服务有关的生命周期方法

onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,屡次调用Context.bindService()方法并不会致使该方法被屡次调用。

onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用

十、 注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意。

答:首先写一个类要继承BroadcastReceiver

第一种:在清单文件中声明,添加

<receive android:name=".IncomingSMSReceiver " >

<intent-filter>

<action android:name="android.provider.Telephony.SMS_RECEIVED")

<intent-filter>

<receiver>

第二种使用代码进行注册如:

IntentFilter filter =  new IntentFilter("android.provider.Telephony.SMS_RECEIVED");

IncomingSMSReceiver receiver = new IncomgSMSReceiver();

registerReceiver(receiver.filter);

两种注册类型的区别是:

1)第一种不是常驻型广播,也就是说广播跟随程序的生命周期。

2)第二种是常驻型,也就是说当应用程序关闭后,若是有信息广播来,程序也会被系统调用自动运行。

十一、 简要解释一下activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver

答:一个activity呈现了一个用户能够操做的可视化用户界面;一个service不包含可见的用户界面,而是在后台运行,能够与一个activity绑定,经过绑定暴露出来接口并与其进行通讯;一个broadcast receiver是一个接收广播消息并作出回应的component,broadcast receiver没有界面;一个intent是一个Intent对象,它保存了消息的内容。对于activity和service来讲,它指定了请求的操做名称和待操做数据的URI,Intent对象能够显式的指定一个目标component。若是这样的话,android会找到这个component(基于manifest文件中的声明)并激活它。但若是一个目标不是显式指定的,android必须找到响应intent的最佳component。它是经过将Intent对象和目标的intent filter相比较来完成这一工做的;一个component的intent filter告诉android该component能处理的intent。intent filter也是在manifest文件中声明的。

十二、 若是后台的Activity因为某缘由被系统回收了,如何在被系统回收以前保存当前状态?

答:重写onSaveInstanceState()方法,在此方法中保存须要保存的数据,该方法将会在activity被回收以前调用。经过重写onRestoreInstanceState()方法能够从中提取保存好的数据

1三、 如何将一个Activity设置成窗口的样式。

答:<activity>中配置:android :theme="@android:style/Theme.Dialog"

另外android:theme="@android:style/Theme.Translucent" 是设置透明

1四、Service生命周期?

service 启动方式有两种,一种是经过startService()方式进行启动,另外一种是经过bindService()方式进行启动。不一样的启动方式他们的生命周期是不同.

经过startService()这种方式启动的service,生命周期是这样:调用startService() --> onCreate()--> onStartConmon()--> onDestroy()。这种方式启动的话,须要注意一下几个问题,第一:当咱们经过startService被调用之后,屡次在调用startService(),onCreate()方法也只会被调用一次,而onStartConmon()会被屡次调用当咱们调用stopService()的时候,onDestroy()就会被调用,从而销毁服务。第二:当咱们经过startService启动时候,经过intent传值,在onStartConmon()方法中获取值的时候,必定要先判断intent是否为null。

经过bindService()方式进行绑定,这种方式绑定service,生命周期走法:bindService-->onCreate()-->onBind()-->unBind()-->onDestroy()  bingservice 这种方式进行启动service好处是更加便利activity中操做service,好比加入service中有几个方法,a,b ,若是要在activity中调用,在须要在activity获取ServiceConnection对象,经过ServiceConnection来获取service中内部类的类对象,而后经过这个类对象就能够调用类中的方法,固然这个类须要继承Binder对象

1五、Broadcast注册方式与区别 

此处延伸:什么状况下用动态注册

 

Broadcast广播,注册方式主要有两种.

第一种是静态注册,也可成为常驻型广播,这种广播须要在Androidmanifest.xml中进行注册,这中方式注册的广播,不受页面生命周期的影响,即便退出了页面,也能够收到广播这种广播通常用于想开机自启动啊等等,因为这种注册的方式的广播是常驻型广播,因此会占用CPU的资源。

 

第二种是动态注册,而动态注册的话,是在代码中注册的,这种注册方式也叫很是驻型广播,收到生命周期的影响,退出页面后,就不会收到广播,咱们一般运用在更新UI方面。这种注册方式优先级较高。最后须要解绑,否会会内存泄露

广播是分为有序广播和无序广播。

1六、View的绘制流程

自定义控件:

一、组合控件。这种自定义控件不须要咱们本身绘制,而是使用原生控件组合成的新控件。如标题栏。

二、继承原有的控件。这种自定义控件在原生控件提供的方法外,能够本身添加一些方法。如制做圆角,圆形图片。

三、彻底自定义控件:这个View上所展示的内容所有都是咱们本身绘制出来的。好比说制做水波纹进度条。

 

View的绘制流程:OnMeasure()——>OnLayout()——>OnDraw()

 

第一步:OnMeasure():测量视图大小。从顶层父View到子View递归调用measure方法,measure方法又回调OnMeasure。

 

第二步:OnLayout():肯定View位置,进行页面布局。从顶层父View向子View的递归调用view.layout方法的过程,即父View根据上一步measure子View所获得的布局大小和布局参数,将子View放在合适的位置上。

 

第三步:OnDraw():绘制视图。ViewRoot建立一个Canvas对象,而后调用OnDraw()。六个步骤:①、绘制视图的背景;②、保存画布的图层(Layer);③、绘制View的内容;④、绘制View子视图,若是没有就不用;

⑤、还原图层(Layer);⑥、绘制滚动条。

 

1七、View,ViewGroup事件分发

1. Touch事件分发中只有两个主角:ViewGroup和View。ViewGroup包含onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent三个相关事件。View包含dispatchTouchEvent、onTouchEvent两个相关事件。其中ViewGroup又继承于View。

2.ViewGroup和View组成了一个树状结构,根节点为Activity内部包含的一个ViwGroup。

3.触摸事件由Action_Down、Action_Move、Aciton_UP组成,其中一次完整的触摸事件中,Down和Up都只有一个,Move有若干个,能够为0个。

4.当Acitivty接收到Touch事件时,将遍历子View进行Down事件的分发。ViewGroup的遍历能够当作是递归的。分发的目的是为了找到真正要处理本次完整触摸事件的View,这个View会在onTouchuEvent结果返回true。

5.当某个子View返回true时,会停止Down事件的分发,同时在ViewGroup中记录该子View。接下去的Move和Up事件将由该子View直接进行处理。因为子View是保存在ViewGroup中的,多层ViewGroup的节点结构时,上级ViewGroup保存的会是真实处理事件的View所在的ViewGroup对象:如ViewGroup0-ViewGroup1-TextView的结构中,TextView返回了true,它将被保存在ViewGroup1中,而ViewGroup1也会返回true,被保存在ViewGroup0中。当Move和UP事件来时,会先从ViewGroup0传递至ViewGroup1,再由ViewGroup1传递至TextView。

6.当ViewGroup中全部子View都不捕获Down事件时,将触发ViewGroup自身的onTouch事件。触发的方式是调用super.dispatchTouchEvent函数,即父类View的dispatchTouchEvent方法。在全部子View都不处理的状况下,触发Acitivity的onTouchEvent方法。

7.onInterceptTouchEvent有两个做用:1.拦截Down事件的分发。2.停止Up和Move事件向目标View传递,使得目标View所在的ViewGroup捕获Up和Move事件。

 

1八、Android UI适配

字体使用sp,使用dp,多使用match_parent,wrap_content,weight

图片资源,不一样图片的的分辨率,放在相应的文件夹下可以使用百分比代替。

1九、HybridApp WebView和JS交互

Android与JS经过WebView互相调用方法,其实是:

Android去调用JS的代码

1. 经过WebView的loadUrl(),使用该方法比较简洁,方便。可是效率比较低,获取返回值比较困难。

2. 经过WebView的evaluateJavascript(),该方法效率高,可是4.4以上的版本才支持,4.4如下版本不支持。因此建议二者混合使用。

JS去调用Android的代码

1. 经过WebView的addJavascriptInterface()进行对象映射 ,该方法使用简单,仅将Android对象和JS对象映射便可,可是存在比较大的漏洞。

 

漏洞产生缘由是:当JS拿到Android这个对象后,就能够调用这个Android对象中全部的方法,包括系统类(java.lang.Runtime 类),从而进行任意代码执行。

解决方式:

(1)Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击。

(2)在Android 4.2版本以前采用拦截prompt()进行漏洞修复。

 

2. 经过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url 。这种方式的优势:不存在方式1的漏洞;缺点:JS获取Android方法的返回值复杂。(ios主要用的是这个方式)

 

(1)Android经过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url

(2)解析该 url 的协议

(3)若是检测到是预先约定好的协议,就调用相应方法

 

3. 经过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

这种方式的优势:不存在方式1的漏洞;缺点:JS获取Android方法的返回值复杂。

20、设计模式

此处延伸:Double Check的写法被要求写出来。

单例模式:分为恶汉式和懒汉式

恶汉式:

public class Singleton 

    private static Singleton instance = new Singleton(); 

    public static Singleton getInstance() 

    { 

        return instance ; 

    } 

}

 

懒汉式:

 

public class Singleton02 

    private static Singleton02 instance; 

 

    public static Singleton02 getInstance() 

    { 

        if (instance == null) 

        { 

            synchronized (Singleton02.class) 

            { 

                if (instance == null) 

                { 

                    instance = new Singleton02(); 

                } 

            } 

        } 

        return instance; 

    } 

}

 

2一、RecyclerView和ListView的区别

RecyclerView能够完成ListView,GridView的效果,还能够完成瀑布流的效果。同时还能够设置列表的滚动方向(垂直或者水平);

RecyclerView中view的复用不须要开发者本身写代码,系统已经帮封装完成了。

RecyclerView能够进行局部刷新。

RecyclerView提供了API来实现item的动画效果。

在性能上:

若是须要频繁的刷新数据,须要添加动画,则RecyclerView有较大的优点。

若是只是做为列表展现,则二者区别并非很大。

 

2二、Universal-ImageLoader,Picasso,Fresco,Glide对比

Fresco 是 Facebook 推出的开源图片缓存工具,主要特色包括:两个内存缓存加上 Native 缓存构成了三级缓存,

优势:

1. 图片存储在安卓系统的匿名共享内存, 而不是虚拟机的堆内存中, 图片的中间缓冲数据也存放在本地堆内存, 因此, 应用程序有更多的内存使用, 不会由于图片加载而致使oom, 同时也减小垃圾回收器频繁调用回收 Bitmap 致使的界面卡顿, 性能更高。

 

2. 渐进式加载 JPEG 图片, 支持图片从模糊到清晰加载。

 

3. 图片能够以任意的中心点显示在 ImageView, 而不只仅是图片的中心。

 

4. JPEG 图片改变大小也是在 native 进行的, 不是在虚拟机的堆内存, 一样减小 OOM。

 

5. 很好的支持 GIF 图片的显示。

 

缺点:

1. 框架较大, 影响 Apk 体积

2. 使用较繁琐

 

Universal-ImageLoader:(估计因为HttpClient被Google放弃,做者就放弃维护这个框架)

优势:

1.支持下载进度监听

2.能够在 View 滚动中暂停图片加载,经过 PauseOnScrollListener 接口能够在 View 滚动中暂停图片加载。

3.默认实现多种内存缓存算法 这几个图片缓存均可以配置缓存算法,不过 ImageLoader 默认实现了较多缓存算法,如 Size 最大先删除、使用最少先删除、最近最少使用、先进先删除、时间最长先删除等。

4.支持本地缓存文件名规则定义

     

Picasso 优势

1. 自带统计监控功能。支持图片缓存使用的监控,包括缓存命中率、已使用内存大小、节省的流量等。

 

2.支持优先级处理。每次任务调度前会选择优先级高的任务,好比 App 页面中 Banner 的优先级高于 Icon 时就很适用。

 

3.支持延迟到图片尺寸计算完成加载

 

4.支持飞行模式、并发线程数根据网络类型而变。 手机切换到飞行模式或网络类型变换时会自动调整线程池最大并发数,好比 wifi 最大并发为 4,4g 为 3,3g 为 2。  这里 Picasso 根据网络类型来决定最大并发数,而不是 CPU 核数。

 

5.“无”本地缓存。无”本地缓存,不是说没有本地缓存,而是 Picasso 本身没有实现,交给了 Square 的另一个网络库 okhttp 去实现,这样的好处是能够经过请求 Response Header 中的 Cache-Control 及 Expired 控制图片的过时时间。

 

 Glide 优势

1. 不只仅能够进行图片缓存还能够缓存媒体文件。Glide 不只是一个图片缓存,它支持 Gif、WebP、缩略图。甚至是 Video,因此更该当作一个媒体缓存。

 

2. 支持优先级处理。

 

 

3. 与 Activity/Fragment 生命周期一致,支持 trimMemory。Glide 对每一个 context 都保持一个 RequestManager,经过 FragmentTransaction 保持与 Activity/Fragment 生命周期一致,而且有对应的 trimMemory 接口实现可供调用。

 

4. 支持 okhttp、Volley。Glide 默认经过 UrlConnection 获取数据,能够配合 okhttp 或是 Volley 使用。实际 ImageLoader、Picasso 也都支持 okhttp、Volley。

 

 

5. 内存友好。Glide 的内存缓存有个 active 的设计,从内存缓存中取数据时,不像通常的实现用 get,而是用 remove,再将这个缓存数据放到一个 value 为软引用的 activeResources map 中,并计数引用数,在图片加载完成后进行判断,若是引用计数为空则回收掉。内存缓存更小图片,Glide 以 url、view_width、view_height、屏幕的分辨率等作为联合 key,将处理后的图片缓存在内存缓存中,而不是原始图片以节省大小与 Activity/Fragment 生命周期一致,支持 trimMemory。图片默认使用默认 RGB_565 而不是 ARGB_888,虽然清晰度差些,但图片更小,也可配置到 ARGB_888。

 

6.Glide 能够经过 signature 或不使用本地缓存支持 url 过时

相关文章
相关标签/搜索