面试题-Android

1. Activity与Fragment的生命周期。

Activity生命周期:
Activity生命周期

Fragment生命周期:
Fragment生命周期

Activity与Fragment生命周期关系:

2. Acitivty的四中启动模式与特点。
1 Standard 标准模式:
说明: Android创建Activity时的默认模式,假设没有为Activity设置启动模式的话,默觉得标准模式。每次启动一个Activity都会又一次创建一个新的实例入栈,无论这个实例是否存在。

生命周期:如上所看到的,每次被创建的实例Activity 的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。

举例:此时Activity 栈中以此有A、B、C三个Activity,此时C处于栈顶,启动模式为Standard 模式。

若在C Activity中加入点击事件,须要跳转到还有一个同类型的C Activity。结果是还有一个C Activity进入栈中,成为栈顶。
2 SingleTop 栈顶复用模式
说明:分两种处理情况:须要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。

生命周期:若情况一中栈顶的Activity被直接复用时,它的onCreate、onStart不会被系统调用,由于它并没有发生改变。可是一个新的方法 onNewIntent会被回调(Activity被正常创建时不会回调此方法)。

举例:此时Activity 栈中以此有A、B、C三个Activity,此时C处于栈顶,启动模式为SingleTop 模式。情况一:在C Activity中加入点击事件,须要跳转到还有一个同类型的C Activity。

结果是直接复用栈顶的C Activity。

情况二:在C Activity中加入点击事件,须要跳转到还有一个A Activity。结果是创建一个新的Activity入栈。成为栈顶。

3 SingleTask 栈内复用模式
说明:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上面的其他Activity所有销毁,使它成为栈顶。

生命周期:同SingleTop 模式中的情况一同样。仅仅会又一次回调Activity中的 onNewIntent方法

举例:此时Activity 栈中以此有A、B、C三个Activity。此时C处于栈顶,启动模式为SingleTask 模式。

情况一:在C Activity中加入点击事件,须要跳转到还有一个同类型的C Activity。结果是直接用栈顶的C Activity。情况二:在C Activity中加入点击事件,须要跳转到还有一个A Activity。

结果是将A Activity上面的B、C所有销毁,使A Activity成为栈顶。

4 SingleInstance 单实例模式
说明: SingleInstance比較特殊,是全局单例模式,是一种加强的SingleTask模式。它除了具有它所有特性外,还加强了一点:具有此模式的Activity仅仅能单独位于一个任务栈中。

这个经常使用于系统中的应用,比如Launch、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。了解就可以。

举例:比方 A Activity是该模式,启动A后。系统会为它创建一个单独的任务栈,由于栈内复用的特性。兴许的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁。

3. Activity缓存方法。
onSaveInstanceState()回调方法会保存临时的数据和状态,这个方法一定会在activity回收之前调用。方法中有一个Bundle参数,putString()、putInt()等方法需要传入两个参数,一个键一个值。数据保存之后会在onCreate中会恢复,onCreate也有一个Bundle类型的参数。除非这个activity是被用户主动销毁的,例如用户按BACK键时。
以下几种情况:1.当用户按下HOME键时 2.长按HOME键,选择运行其他的程序时 3.按下电源按键(关闭屏幕显示)时 4.从一个activity A中启动一个新的activity时 5.屏幕方向切换时,l例如从竖屏切换到横屏时。(如果不指定configchange属性)在屏幕切换之前,系统会销毁activity A,在切换之后系统又会自动地创建activity A,所以onSavaInstanceState一定会被执行
注意:1. 布局中的每一个view默认实现了onSaveInstanceState()方法,这样的话,这个UI的任何改变都会自动的存储和在activity重新创建的时候自动恢复。但是这个情况只有你为这个UI提供了唯一的ID之后才会起作用,如果没有ID,则不会存储它的状态 2. 由于默认的onSaveInstanceState()方法实现了帮助UI存储它的状态,所以如果你需要覆盖这个方法去存储额外的状态信息时,你应该在执行任何代码之前都调用父类的onSaveInstanceState()方法,(super.onSaveInstanceState). 3. 由于onSaveInstanceState()方法调用的不可确定性,你应该只使用这个方法去记录activity的瞬间状态(UI的状态),不应该用这个方法去存储持久化数据。当用户离开这个activity的时候应该在onPause()方法中存储持久化数据(例如应该被存储到数据库中的数据) 4. onSaveInstanceState()如果被调用,这个方法会在onStop()前被触发,但是系统并不保证是否在onPause()之前或者是之后触发

onRestoreInstanceState(Bundle outState) 用来恢复数据,不一定和save成对出现(如果activity没有被销毁)

需要调用super,save在最后调用super,restore在最前调用super

4. Service的生命周期,两种启动方法,有什么区别。

1:startService
Service的生命周期:onCreate() –> onStart() -> onDestroy()

停止服务:service.stopService()
2:bindService
Service的生命周期 onCreate() –> onBind() –> onUnBind() –> onDestroy()

停止服务:UnbindService()再StopService()

区别:使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止

5. 怎么保证service不被杀死。
1 Service设置成START_STICKY(onStartCommand方法中),kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样
2 通过 startForeground将进程设置为前台进程,做前台服务,优先级和前台应用一个级别​,除非在系统内存非常缺,否则此进程不会被 kill.具体实现方式为在service中创建一个notification,再调用void android.app.Service.startForeground(int id,Notificationnotification)方法运行在前台即可。
3 双进程Service:让2个进程互相保护,其中一个Service被清理后,另外没被清理的进程可以立即重启进程
4 AlarmManager不断启动service。该方式原理是通过定时警报来不断启动service,这样就算service被杀死,也能再启动。同时也可以监听网络切换、开锁屏等广播来启动service。AlarmManager.setRepeating()
5 QQ黑科技:在应用退到后台后,另起一个只有 1 像素的页面停留在桌面上,让自己保持前台状态,保护自己不被后台清理工具杀死

6. 广播的两种注册方法,有什么区别。

一种是在代码当中注册,注册的方法是registerReceiver(receiver,filter)(用Activity的实例来调用),取消注册的方法:unregisterReceiver(receiver),如果一个BroadcastReceiver用于更新UI(UserInterface),那么通常会使用这种方法进行注册,在Activity启动的时候进行注册,在Activity不可见后取消注册;
另一种就是在AndroidManifest当中进行注册。

区别: 在AndroidManifest中进行注册后,不管改应用程序是否处于活动状态,都会进行监听,比如某个程序时监听 内存的使用情况的,当在手机上安装好后,不管改应用程序是处于什么状态,都会执行改监听方法中的内容。
在代码中进行注册后,当应用程序关闭后,就不再进行监听。我们读知道,应用程序是否省电,决定了该应用程序的受欢迎程度,所以,对于那些没必要在程序关闭后仍然进行监听的Receiver,在代码中进行注册,无疑是一个明智的选择。

7. Intent的使用方法,可以传递哪些数据类型。

使用方法:
1.activity跳转 2.activity传值 3.捆绑传值,使用Bundle 4.
数据类型:
1. Serializable,将对象序列化成二进制数据传递。保存对象的属性到本地文件,数据库,网络流等方便数据传输,也可程序之间传递。

  1. charsequence: 主要用来传递String,char等

  2. parcelable: 这个android提供的一种新的类型,用来封装数据的容器,和Serializable相似,但是序列化的方式不同。为了解决Serializable效率不高的问题,内存开销小。但是不能持久化。

4.Bundle: Bundle是将数据传递到另一个上下文中或保存,或者回复自己状态的数据存储方式,数据不是持久化状态。

8. ContentProvider使用方法。
当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。ContentProvider为存储和获取数据提供了统一的接口。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。

query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder)
通过Uri进行查询,返回一个Cursor

insert(Uri url, ContentValues values)
将一组数据插入到Uri 指定的地方

update(Uri uri, ContentValues values, String where, String[] selectionArgs)
更新Uri指定位置的数据

delete(Uri url, String where, String[] selectionArgs)
删除指定Uri并且符合一定条件的数据

9. Thread、AsycTask、IntentService的使用场景与特点。

Thread:
当一个 Activity 被 finish 之后 ,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。

IntentService:
Serivce+handler的结合产物,可以在onHandleIntent直接处理耗时操作。

而本地service和远程service不能在onStart方法中执行耗时操作,只能放在子线程中进行处理,当有新的intent请求过来都会调用onStartCommond先将其入队列。

当第一个耗时操作结束后,就会处理下一个耗时操作(此时调用onHandleIntent),都执行完了自动执行onDestory销毁IntentService服务。

AsyncTask:
thread池+handler的结合产物,减少程序中线程过多开销过大,操作和管理更加方便。

AsyncTask实例必须在UI Thread中创建,execute方法必须在UI Thread中调用,不能手动调用onPreExcute(),onPostExcute(Result)。

task只能被执行一次,否则将出现异常。

数据简单可使用AsyncTask。

AsyncTask用的是线程池机制,容量是128,最多同时运行5个core线程,剩下的排队。

10. 五种布局: FrameLayout 、 LinearLayout 、 AbsoluteLayout 、 RelativeLayout 、TableLayout 各自特点及绘制效率对比。

FrameLayoout:整个界面被当成一块空白备用区域,所有的子元素都不能被指定放置的位置,它们统统放于这块区域的左上角,并且后面的子元素直接覆盖在前面的子元素之上,将前面的子元素部分和全部遮挡。

Linearlayout:LinearLayout按照垂直或者水平的顺序依次排列子元素,每一个子元素都位于前一个元素之后。

AbsoluteLayout:是绝对位置布局。在此布局中的子元素的android:layout_x和android:layout_y属性将生效,用于描述该子元素的坐标位置。

RelativeLayout:按照各子元素之间的位置关系完成布局。在此布局中的子元素里与位置相关的属性将生效。例如android:layout_below, android:layout_above等。

TableLayout:表格布局,适用于N行N列的布局格式。一个TableLayout由许多TableRow组成,一个TableRow就代表TableLayout中的一行。

11. Android的数据存储形式。
https://www.cnblogs.com/ITtangtang/p/3920916.html
http://blog.youkuaiyun.com/amazing7/article/details/51437435

1 使用SharedPreferences存储数据
适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型、基本类型的值。比如应用程序的各种配置信息(如是否打开音效、是否使用震动效果、小游戏的玩家积分等),解锁口 令密码等
核心原理:保存基于XML文件存储的key-value键值对数据,通常用来存储一些简单的配置信息。通过DDMS的File Explorer面板,展开文件浏览树,很明显SharedPreferences数据总是存储在/data/data//shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.edit()获取的内部接口Editor对象实现。 SharedPreferences本身是一 个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(String name, int mode)方法来获取SharedPreferences实例,该方法中name表示要操作的xml文件名,第二个参数:
MODE_PRIVATE,MODE_WORLD_READABLE, MODE_WRITEABLE

2 文件存储数据
核心原理: Context提供了两个方法来打开数据文件里的文件IO流 FileInputStream openFileInput(String name); FileOutputStream(String name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。
FileInputStream.read openFileInput byte[]

读写SD卡:添加权限,Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED),Environment.getExternalStorageDirectory(),使用IO流操作SD卡上的文件

3 SQLite数据库存储数据
db.executeSQL(String sql);
insert,delete,update
4 使用ContentProvider存储数据

5 网络存储数据
HttpURLConnection:
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(GET);
conn.setConnectTimeout(5000);
conn.setRequestProperty(User-Agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0));

HttpClient:
1、 创建HttpClient对象

2、创建HttpGet对象,指定请求地址(带参数)

3、使用HttpClient的execute(),方法执行HttpGet请求,得到HttpResponse对象

4、调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

5、调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

12. Sqlite的基本操作。

13. Android中的MVC模式。
这里写图片描述

1 模型对象存储着应用的数据和业务逻辑,为存储和管理应用数据。
2 控制器是视图对象和模型对象的联系纽带,管理着模型对象和视图对象的数据流动,控制着诸如触发事件之类的响应事件。
3 视图对象就是用户感受到的界面逻辑。

14. Merge、ViewStub的作用。
Merge:(替换FrameLayout或替换重复主从布局)
使用merge标签可以达到减少布局层级的作用,特别在配合include标签进行使用的时候,通过减少布局的层级数,可以优化APP在加载布局文件时的资源消耗,从而达到提高APP性能的效果。
ViewStub:(需要使用时才会展现的布局标签)
采用先绘制,再控制的话,在Inflate布局的时候,即使那些还没有要展示的布局也会被实例化,但是使用轻量级的ViewStub标签的话,一开始Inflate的时候,系统会自动忽视掉它们,直到后面你代码中采用代码的方式手动进行Inflate操作时,才会使用到。
注意:ViewStub中的layout布局不能使用merge标签,否则会报错;
ViewStub的inflate只能执行一次,显示了之后,就不能再使用ViewStub控制它了。

15. Json有什么优劣势。
优点:非冗长性,传输效率高
缺点:没有命名空间,属性的差异,创建和验证比xml麻烦

16. 动画有哪两类,各有什么特点?
补间动画:
对View进行移动、缩放、旋转和淡入淡出,非View的对象不能操作,改变显示效果没有真正改变view的属性。
属性动画:

ofFloat()透明度,旋转,移动缩放
使用xml,可重用

17. Handler、Loop消息队列模型,各部分的作用。
这里写图片描述
18. 怎样退出终止App。
ActivityManager任务管理器。
intent.setAction(GlobalVarable.EXIT_ACTION),
19. Asset目录与res目录的区别。
assets目录与res下的raw、drawable目录一样,也可用来存放资源文件,但它们三者有区别,对比总结如下表:

assets  res/raw res/drawable

获取资源方式: 文件路径+文件名 R.raw.xxx R.drawable.xxx
是否被压缩: NO NO YES(失真压缩)
能否获取子目录下的资源: YES NO NO

20. Android怎么加速启动Activity。

21. Android内存优化方法:ListView优化,及时关闭资源,图片缓存等等。

22. Android中弱引用与软引用的应用场景。

23. Bitmap的四中属性,与每种属性队形的大小。

24. View与View Group分类。自定义View过程:onMeasure()、onLayout()、onDraw()。

25. Touch事件分发机制。

26. Android长连接,怎么处理心跳机制。

27. Zygote的启动过程。

28. Android IPC:Binder原理。

29. 你用过什么框架,是否看过源码,是否知道底层原理。

30. Android5.0、6.0新特性。
31. Android四大组件

http://blog.youkuaiyun.com/shenggaofei/article/details/52450668
1、activity

(1)一个Activity通常就是一个单独的屏幕(窗口)。

(2)Activity之间通过Intent进行通信。

(3)android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明,否则系统将不识别也不执行该Activity。

2、service

(1)service用于在后台完成用户指定的操作。service分为两种:

(a)started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。

(b)bound(绑定):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。
3、content provider

(1)android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。其他应用可以通过ContentResolver类从该内容提供者中获取或存入数据。

(2)只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。

(3)ContentProvider实现数据共享。ContentProvider用于保存和获取数据,并使其对所有应用程序可见。这是不同应用程序间共享数据的唯一方式,因为android没有提供所有应用共同访问的公共存储区。

(4)开发人员不会直接使用ContentProvider类的对象,大多数是通过ContentResolver对象实现对ContentProvider的操作。

(5)ContentProvider使用URI来唯一标识其数据集,这里的URI以content://作为前缀,表示该数据由ContentProvider来管理。

4、broadcast receiver

(1)你的应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件(如当电话呼入时,或者数据网络可用时)进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个activity或serice来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。

(2)广播接收者的注册有两种方法,分别是程序动态注册和AndroidManifest文件中进行静态注册。

(3)动态注册广播接收器特点是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。

32. 六大布局
六大界面布局方式包括: 线性布局(LinearLayout)、框架布局(FrameLayout)、表格布局(TableLayout)、相对布局(RelativeLayout)、绝对布局(AbsoluteLayout)和网格布局(GridLayout) 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值