安卓面试基础知识总结.docx
- 文档编号:10786553
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:42
- 大小:158.71KB
安卓面试基础知识总结.docx
《安卓面试基础知识总结.docx》由会员分享,可在线阅读,更多相关《安卓面试基础知识总结.docx(42页珍藏版)》请在冰豆网上搜索。
安卓面试基础知识总结
1Activity
1.1Activity的概念
是Android应用层开发的四大组件之一,主要负责和用户交互部分,有自己的生命周期,在其上可以布置按钮,文本框等各种控件,简单来说就是Android的UI部分。
1.2Activity与View的区别
1)Activity是四大组件中唯一一个用来和用户进行交互的组件。
可以说Activity就是android的视图层。
2)如果再细化,Activity相当于视图层中的控制层,是用来控制和管理View的,真正用来显示和处理事件的实际上是View。
3)每个Activity内部都有一个Window对象,Window对象包含了一个DecorView(实际上就是FrameLayout),我们通过setContentView给Activity设置显示的View实际上都是加到了DecorView中。
1.3Activity生命周期
1.3.1生命周期主干
方法
描述
可被杀死
下一个
onCreate()
在Activity第一次被创建的时候被调用。
这里是你做所有初始化设置的地方—创建视图、绑定数据至列表等。
如果曾经有状态记录(参阅后述Saving Activity State。
),则调用此方法时会传入一个包含着此activity以前状态的包对象做为参数
否
onStart()
onStart()
在Activity正要变得为用户所见时被调用。
数据刷新时候调用!
!
!
当Activity转向前台时接着调用onResume()
在Activity变为隐藏时接着知行onStop()
否
onResume()
onStop()
onResume()
在Activity开始与用户进行交互之前被调用。
此时Activity位于堆栈顶部,并接收用户输入。
否
onPause()
Activityrun……
Activity开始运行……………………
onPasue()
当系统将要启动另一个Activity时调用。
此方法主要用来将未保存的变化进行持久化,停止类似动画这样耗费CPU的动作等。
这一切动作应该在短时间内完成,因为下一个Activity必须等到此方法返回后才会继续。
当Activity重新回到前台会执行onResume()【弹出对话框】。
当Activity变为用户不可见时会执行onStop()。
是
onResume()
onStop()
onStop()
当Activity不再为用户可见时调用此方法。
这可能发生在它被销毁或者另一个Activity(可能是现存的或者是新的)回到运行状态并覆盖了它。
如果Activity再次回到前台跟用户交互则执行onRestart().
如果关闭Activity则执行onDestroy()
是
onRestart()
onDestroy()
onDestroy()
在Activity销毁前调用。
这是Activity接收的最后一个调用。
这可能发生在Activity结束(调用了它的finish()方法)或因为系统需要空间所以临时的销毁了此Activity的实例时。
可以用isFinishing()方法来区分这两种情况。
是
已经完蛋了,还调用毛线!
!
!
1.3.2其他中转方法
onRestart()
在Activity停止后,在再次启动之前被调用。
之后执行onStart().
否
onStart()
1.4Activity启动模式
1.4.1四种启动模式
standard
默认模式,可以不用写配置。
在这个模式下,都会默认创建一个新的实例。
因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。
singleTop
可以有多个实例,但是不允许多个相同Activity叠加。
即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。
singleTask
只有一个实例。
在同一个应用程序中启动它的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activitydestory掉并调用它的onNewIntent方法。
如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。
singleInstance
只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。
1.4.2配置样例
name="com.example.mobilesafe.WatchDogActivity" android: launchMode="singleInstance"/> 1.5Activity启动方法 1)在一个Activity中调用startActivity()方法。 直接启动Activity,不带请求码。 2)在一个Activity中调用startActivityForResult()方法。 带请求码启动Activity。 1.6请求码与响应码 请求码(RequestCode) 在一个业务中可能在两个按钮被单击事件中打开同一个Activity,但我们在onActivityResult事件中如何判断是哪个按钮打开了新的Activity? 请求码就是为解决这个问题的,那么我们打开新的Activity时应该使用startActivityForResult(intent,1);。 其中的第二个参数就是请求码。 结果码(ResultCode) 在一个业务中可能要打开多个不同的Activity,那关闭Activity时在onActivityResult事件中我们如何知道关闭的是哪一个Activity呢? 结果码就是为解决这个问题的,那么我们打开新的Activity时应该使用setResult(2,intent);或在关闭Activity前调用ActivityObj.setResult (2);。 其中的第一个参数就是结果码。 在onActivityResult事件中,通过判断resultCode更可知道是哪个Activity被关闭了。 2BroadcastReceiver 2.1概念 BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。 2.2应用场景 在Android系统中,广播体现在方方面面: eg: 1.当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能; 2.当锁屏或者点亮屏幕时就会产生一条广播,接收这条广播就可以实现一些暂停或者开启一些耗电进程的功能。 3.当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作; 4.当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度; 2.3注册 2.3.1静态注册 2.3.1.1概念 静态注册是在AndroidManifest.xml文件中配置的。 2.3.2动态注册 2.3.2.1概念 动态注册需要在代码中动态的指定广播地址并注册。 2.3.2.2需要注意的事项 RegisterReceiver是android.content.ContextWrapper类中的方法,Activity和Service都继承了ContextWrapper,所以可以直接调用。 在实际应用中,我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。 所以,需要在特定的地方执行解除注册操作: 生命周期的onDestroy()。 有部分广播接受者,涉及到用户的敏感内容,需要在权限文件中声明。 如开机完成的广播,用户电量变化的广播,用户网络状态发生改变的广播 2.3.3生命周期 1.广播接收者的生命周期是非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁 2.广播接收者中不要做一些耗时的工作,否则会弹出ApplicationNoResponse错误对话框 3.最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉 4.耗时的较长的工作最好放在服务中完成 3Service 3.1概念 服务是看不到界面的,,就是一个没有界面的Activity,并且长期在后台运行的一个组件.。 3.2为什么用服务? 进程优先级,回收时是从5~1,从低到高 Foregroundprocess前台进程 Visibleprocess可视进程 Serviceprocess服务进程 Backgroundprocess后台进程 Emptyprocess空进程 回收的优先级: 先回收空进程,一个一个回收的,当内存够用时,不再回收空进程.如果空进程回收完毕后,内存还是不够用时,继续向上一个一个的回收后台进程.依次类推. 当系统内存不够用时,需要回收服务进程时,当系统内存又够用时,会重新启动服务.当用户去手动的把服务关闭时,服务不会再重启了 3.3作用 由于ANR对Activity和BroadcastReceiver响应时间的限制(Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒),使得在其中都不适合执行较耗时操作,这样像网络、数据库、复杂计算这类耗时操作的执行就需要一个组件来承担。 Service作为Android四大组件之一,其功能之一就是耗时操作的执行,主要功能如下: a.执行需要长时间运行的操作,这个操作不与用户进行交互,如网络下载、大文件I/O、复杂计算、监听手机状态。 b.应用内或应用间数据通信,Android每个应用程序都在自己的dalvik虚拟机中运行,一个应用是不允许访问其他应用的内存信息的,为此Android引入了ContentProvider在不同应用间共享数据,BroadcastReceiver广播信息给不同应用程序,但ContentProvider更多用于数据的共享,BroadcastReceiver广播的信息会被所有应用接收较耗费系统资源,对于两个应用间动态的进行交互还需要通过Service来完成。 3.4启动方式 3.4.1直接启动 Activity开启完服务后就不管服务了.Activity和服务没有关系.startService开启的服务, 只有stopService可以关闭 3.4.2绑定启动 绑定服务,生命周期方法会执行: onUnbind->onDestory服务销毁了. 在activity中调用service中的方法. 步骤: 调用bindService方法绑定服务 1.在Activity中定义一个连接桥的内部类,会在bindService方法传递给service. 2.在service服务中onBind方法中返回一个IBinder接口对象. 3.在service类中定义一个IBinder的内部实现类,在onBind方法返回. 4.当onBinder方法返回完对象后,activity中连接桥里的onServiceConnected会被调用,其中形参IBinderservice就是service类中onBind返回的对象. 5.activity得到了service中的内部类对象,点击按钮是调用内部类中的forwardBuyTicket方法,此方法会转调服务中buyTicket方法. 3.5生命周期 Service的生命周期 (适用于2.1及以上) 1. 被startService的 无论是否有任何活动绑定到该Service,都在后台运行。 onCreate(若需要)->onStart(intid,Bundleargs). 多次startService,则onStart调用多次,但不会创建多个Service实例,只需要一次stop。 该Service一直后台运行,直到stopService或者自己的stopSelf()或者资源不足由平台结束。 2. 被bindService的 调用bindService绑定,连接建立服务一直运行。 未被startService只是BindService,则onCreate()执行,onStart(int,Bund,le)不被调用;这种情况下绑定被解除,平台就可以清除该Service(连接销毁后,会导致解除,解除后就会销毁)。 3. 被启动又被绑定 类似startService的生命周期,onCreateonStart都会调用。 4. 停止服务时 stopService时显式onDestroy()。 或不再有绑定(没有启动时)时隐式调用。 有bind情况下stopService()不起作用。 4ContentProvider 4.1ContentProvider 数据库在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据。 不能将数据库设为WORLD_READABLE,每个数据库都只能创建它的包访问, 这意味着只有由创建数据库的进程可访问它。 如果需要在进程间传递数据, 则可以使用AIDL/Binder或创建一个ContentProvider,但是不能跨越进程/包边界直接来使用数据库。 一个ContentProvider类实现了一组标准的方法接口,从而能够让其他的应用保存或读取此ContentProvider的各种数据类型。 也就是说,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据暴露出去。 外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要, 重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以删除程序的数据, 当然,中间也会涉及一些权限的问题。 下边列举一些较常见的接口,这些接口如下所示。 ·query(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder): 通过Uri进行查询,返回一个Cursor。 ·insert(Uriurl,ContentValuesvalues): 将一组数据插入到Uri指定的地方。 ·update(Uriuri,ContentValuesvalues,Stringwhere,String[]selectionArgs): 更新Uri指定位置的数据。 ·delete(Uriurl,Stringwhere,String[]selectionArgs): 删除指定Uri并且符合一定条件的数据。 4.2ContentResolver 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的ContentResolver实例。 ContentResolver提供的接口和ContentProvider中需要实现的接口对应,主要有以下几个。 Øquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder): 通过Uri进行查询,返回一个Cursor。 Øinsert(Uriurl,ContentValuesvalues): 将一组数据插入到Uri指定的地方。 Øupdate(Uriuri,ContentValuesvalues,Stringwhere,String[]selectionArgs): 更新Uri指定位置的数据。 Ødelete(Uriurl,Stringwhere,String[]selectionArgs): 删除指定Uri并且符合一定条件的数据。 4.3ContentObserver 在注册,翻译成中文就是内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理。 ContentObserver一般和系统或第三方程序提供的Provider一起使用,这些Provider一般情况下会有一个Uri,然后ContentObserver就去监听这些Uri数据的变化,然后做出相应的处理。 4.4ContentProvider和ContentResolver中用到的Uri 在ContentProvider和ContentResolver当中用到了Uri的形式通常有两种,一种是指定全部数据,另一种是指定某个ID的数据。 我们看下面的例子。 ·content: //contacts/people/这个Uri指定的就是全部的联系人数据。 ·content: //contacts/people/1这个Uri指定的是ID为1的联系人的数据。 在上边两个类中用到的Uri一般由3部分组成。 ·第一部分是方案: "content: //"这部分永远不变 ·第二部分是授权: "contacts" ·第二部分是路径: "people/","people/1"(如果没有指定ID,那么表示返回全部)。 由于URI通常比较长,而且有时候容易出错,且难以理解。 所以,在Android当中定义了一些辅助类,并且定义了一些常量来代替这些长字符串的使用,例如下边的代码: Contacts.People.CONTENT_URI(联系人的URI)。 在我们的实例MyProvider中是如下定义的: publicstaticfinalStringAUTHORITY="com.teleca.PeopleProvider"; publicstaticfinalStringPATH_SINGLE="people/#"; publicstaticfinalStringPATH_MULTIPLE="people"; publicstaticfinalUricontent_URI=Uri.parse("content: //"+AUTHORITY+"/"+PATH_MULTIPLE); 5Service如何向Activity传递数据 一个Android程序可以由多个Activity和Servier组成,在这些程序组件之间传递数据的方法有以下几种,每种方法都有其特定的使用途径。 5.1原始数据类型 在Activity/Servier之间传递临时性的原始数据,可以使用Intent的putExtras方法来传递数据。 若传递的数据需要长久保存,则使用SharedPreference类来完成。 5.2传递对象 当在Activity/Servier之间传递不需要长久保存的对象时,可以使用以下几种途径: (1)通过Application类,每个Android应用程序都有一个Application类。 当你在程序的AndroidManifest.xml中给Application设定一个名字时,你的程序中就必须有一个Application的子类。 这个Application子类会被Android自动实例化,并且是一个全局性的类,它的生命周期和程序的生命周期相同,你可以把一些全局性的对象保存在Application类中。 Application类可以通过getApplication()获得。 (2)通过HashMapofWeakReferences传递对象。 当一个Activity需要向另外一个Activity传递对象时,可以使用一个关键字把对象存在一个HashMap中,并把这个关键字通过Internt的Extras发给目标Activity,目标Activity接到该关键字后使用该关键字把对象从HashMap中取出。 5.3在Activity/Service之间传递需要长久保存的对象时,可以使用以下的方式 1.ApplicationPreferences 2.Files 3.contentProviders 4.SQLiteDB 6AsyncTask 6.1底层处理 底层使用本地线程池机制: 1.核心线程数: 线程池中保存的线程数,包括空闲线程,默认为5个 2.线程池中允许的最大线程数,固定为128个+10个阻塞线程 3.当线程数大于核心线程数时,如果线程池中中线程数大于核心线程数5超过一秒事,终止多余的线程,保留五个核心线程数。 4.执行前用于保持任务的队列,此队列仅保持execute方法提交的Runnable任务,固定容量为10 5.执行程序创建新线程时使用的工厂 6.2AsyncTask介绍 Android的AsyncTask比Handler更轻量级一些(只是代码上轻量一些,而实际上要比handler更耗资源),适用于简单的异步处理。 首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。 Android为了降低这个开发难度,提供了AsyncTask。 AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。 AsyncTask直接继承于Object类,位置为android.os.AsyncTask。 要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。 AsyncTask定义了三种泛型类型Params,Progress和Result。 Params启动任务执行的输入参数,比如HTTP请求的URL。 Progress后台任务执行的百分比。 Result后台执行任务最终返回的结果,比如String。 使用过AsyncTask的同学都知道一个异步加载数据最少要重写以下这两个方法: doInBackground(Params…)后台执行,比较耗时的操作都可以放在这里。 注意这里不能直接操作UI。 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。 在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。 onPostExecute(Result)相当于Handler处理UI的方式,在这里面可以使用在doInBackground得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回 有必要的话你还得重写以下这三个方法,但不是必须的: onProgressUpdate(Progress…)可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。 onPreExecu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面试 基础知识 总结