【Android论文栏目提醒】:以下是网学会员为您推荐的Android论文-安卓游戏开发--Android-教程精华-摘要-开发-面试-免费708286611 - 产品手册,希望本篇文章对您学习有所帮助。
ANDROID 复习摘要1、什么是 ANR 如何避免它ANR 定义 在
Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application NotResponding)对话框。
用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。
因此,在程序里对响应性能的设计很重要,这样,系统不会显示 ANR 给用户。
如何避免:考虑上面的 ANR 定义,让我们来研究一下为什么它会在
Android 应用程序里发生和如何最佳构建应用程序来避免 ANR。
Android 应用程序通常是运行在一个单独的线程(例如,main)里。
这意味着你的应用程序所做的事情如果在主线程里占用了太长的时间的话,就会引发 ANR 对话框,因为你的应用程序并没有给自己机会来处理输入事件或者 Intent 广播。
因此,运行在主线程里的任何方法都尽可能少做事情。
特别是,Activity 应该在它的关键生命周期方法(如 onCreate和 onResume)里尽可能少的去做创建操作。
潜在的耗时操作,例如网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者以数据库操作为例,通过异步请求的方式)来完成。
然而,不是说你的主线程阻塞在那里等待子线程的完成——也不是调用Thread.wait或是 Thread.sleep。
替代的方法是,主线程应该为子线程提供一个 Handler,以便完成时能够提交给主线程。
以这种方式设计你的应用程序,将能保证你的主线程保持对输入的响应性并能避免由于 5 秒输入事件的超时引发的 ANR 对话框。
这种做法应该在其它显示 UI 的线程里效仿,因为它们都受相同的超时影响。
IntentReceiver 执行时间的特殊限制意味着它应该做:在后台里做小的、琐碎的工作如保存设定或者注册一个 Notification。
和在主线程里调用的其它方法一样,应用程序应该避免在 BroadcastReceiver 里做耗时的操作或计算。
但不再是在子线程里做这些任务(因为 BroadcastReceiver 的生命周期短) ,替代的是,如果响应 Intent 广播需要执行一个耗时的动作的话,应用程序应该启动一个Service。
顺便提及一句,你也应该避免在 Intent Receiver 里启动一个 Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。
如果你的应用程序在响应 Intent 广播时需要向用户展示什么,你应该使用Notification Manager 来实现。
一般来说,在应用程序里,100 到 200ms 是用户能感知阻滞的时间阈值。
因此,这里有一些额外的技巧来避免 ANR,并有助于让你的应用程序看起来有响应性。
如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度(ProgressBar 和 ProgressDialog 对这种情况来说很有用)。
特别是游戏,在子线程里做移动的计算。
若你的应用程序有一个耗时的初始化过程的话,考虑可以显示一个 SplashScreen 或者快速显示主画面并异步来填充这些信息。
在这两种情况下,你都应该显示正在进行的进度,以免用户认为应用程序被冻结了。
本文来自 CSDN 博客,转载请标明出处:http://blog.csdn.net/Zengyangtech/archive/2010/11/21/6025671.aspx2、什么情况会导致 Force Close ?如何避免?能否捕获导致其的异常?3、
Android 本身的 api 并未声明会抛出异常,则其在运行时有无可能抛出 runtime异常,你遇到过吗?诺有的话会导致什么问题?如何解决?4、简要解释一下 activity、 intent 、intent filter、service、Broadcast、BroadcaseReceiverActivityAndroid 中,Activity 是所有程序的根本,所有程序的流程都运行在 Activity 之中,Activity 具有自己的生命周期由系统控制生命周期,程序无法改变,但可以用 onSaveInstanceState 保存其状态) 。
对于 Activity,关键是其生命周期的把握(如那张经典的生命周期图.) ,其次就是状态的保存和恢复(onSaveInstanceState onRestoreInstanceState) ,以及 Activity 之间的跳转和数据传输(intent) 。
Activity 中常用的函数有 SetContentView findViewById finishstartActivity,其生命周期涉及的函数有:void onCreateBundle savedInstanceStatevoid onStartvoid onRestartvoid onResumevoid onPausevoid onStopvoid onDestroy注意的是,Activity 的使用需要在 Manifest 文件中添加相应的ltActivitygt,并设置其属性和 intent-filter。
IntentAndroid 中提供了 Intent 机制来协助应用间的交互与通讯,Intent 负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,
Android 则根据此 Intent的描述,负责找到对应的组件,将 Intent 传递给调用的组件,并完成组件的调用。
Intent 不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service 之间的交互。
因此,Intent 在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。
在 SDK中给出了 Intent 作用的表现形式为: 通过 Context.startActivity orActivity.startActivityForResult 启动一个 Activity; 通过 Context.startService 启动一个服务,或者通过Context.bindService 和后台服务交互; 通过广播方法比如 Context.sendBroadcastContext.sendOrderedBroadcast Context.sendStickyBroadcast 发给 broadcast receivers。
Intent 属性的设置,包括以下几点: (以下为 XML 中定义,当然也可以通过Intent 类的方法来获取和设置)(1)Action,也就是要执行的动作SDk 中定义了一些标准的动作,包括onstant Target component ActionACTION_CALL activity Initiate a phone call.ACTION_EDIT activity Display data for the user to edit.ACTION_MAIN activity Start up as the initial activity of a task with no data input and noreturned output.ACTION_SYNC activity Synchronize data on a server with data on the mobile device.ACTION_BATTERY_LOW broadcast receiver A warning that the battery is low.ACTION_HEADSET_PLUG broadcast receiver A headset has been plugged into the device or unplugged from it.ACTION_SCREEN_ON broadcast receiver The screen has been turned on.ACTION_TIMEZONE_CHANGED broadcast receiver The setting for the time zone has changed.当然,也可以自定义动作(自定义的动作在使用时,需要加上包名作为前缀,如 )quotcom.example.project.SHOW_COLOR”,并可定义相应的 Activity 来处理我们的自定义动作。
(2)Data,也就是执行动作要操作的数据
Android 中采用指向数据的一个 URI 来表示,如在联系人应用中,一个指向某联系人的 URI 可能为:content://contacts/1。
对于不同的动作,其 URI 数据的类型是不同的(可以设置 type 属性指定特定类型数据) ,如 ACTION_EDIT 指定 Data 为文件 URI,打电话为 tel:URI,访问网络为 http:URI,而由 content provider 提供的数据则为 content: URIs。
(3)type(数据类型) ,显式指定 Intent 的数据类型(MIME) 。
一般 Intent 的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。
(4)category(类别) ,被执行动作的附加信息。
例如 LAUNCHER_CATEGORY 表示 Intent 的接受者应该在 Launcher 中作为顶级应用出现;而ALTERNATIVE_CATEGORY 表示当前的 Intent 是一系列的可选动作中的一个,这些动作可以在同一块数据上执行。
还有其他的为Constant MeaningCATEGORY_BROWSABLE The target activity can be safely invoked by the browser to displaydata referenced by a link — for example an image or an e-mailmessage.CATEGORY_GADGET The activity can be embedded inside of another activity that hostsgadgets.CATEGORY_HOME The activity displays the home screen the first screen the user seeswhen the device is turned on or when the HOME key is pressed.CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed inthe top-level application launcher.CATEGORY_PREFERENCE The target activity is a preference panel.(5)component(组件) ,指定 Intent 的的目标组件的类名称。
通常
Android 会根据 Intent 中包含的其它属性的信息,比如 action、data/type、category 进行查找,最终找到一个与之匹配的目标组件。
但是,如果 component 这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。
指定了这个属性以后,Intent 的其它所有属性都是可选的。
(6)extras(附加信息) ,是其它所有附加信息的集合。
使用 extras 可以为组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以将电子邮件的标题、正文等保存在 extras 里,传给电子邮件发送组件。
理解 Intent 的关键之一是理解清楚 Intent 的两种基本用法:一种是显式的 Intent,即在构造 Intent 对象时就指定接收者;另一种是隐式的 Intent,即 Intent 的发送者在构造 Intent 对象时,并不知道也不关心接收者是谁,有利于降低发送者和接收者之间的耦合。
对于显式 Intent,
Android 不需要去做解析,因为目标组件已经很明确,
Android需要解析的是那些隐式 Intent,通过解析,将 Intent 映射给可以处理此 Intent的 Activity、IntentReceiver 或 Service。
Intent 解析机制主要是通过查找已注册在 AndroidManifest.xml 中的所有IntentFilter 及其中定义的 Intent,最终找到匹配的 Intent。
在这个解析过程中,
Android 是通过 Intent 的 action、type、category 这三个属性来进行判断的,判断方法如下: 如果 Intent 指明定了 action,则目标组件的 IntentFilter 的 action 列表中就必须包含有这个 action,否则不能匹配; 如果 Intent 没有提供 type,系统将从 data 中得到数据类型。
和 action 一样,目标组件的数据类型列表中必须包含 Intent 的数据类型,否则不能匹配。
如果 Intent 中的数据不是 content: 类型的 URI,而且 Intent 也没有明确指定它的 type,将根据 Intent 中数据的 scheme (比如 http: 或者 mailto:) 进行匹配。
同上,Intent 的 scheme 必须出现在目标组件的 scheme 列表中。
如果 Intent 指定了一个或多个 category,这些类别必须全部出现在组建的类别列表中。
比如 Intent 中包含了两个类别:LAUNCHER_CATEGORY 和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。
Intent-Filter 的定义一些属性设置的例子: ltaction
android:namequotcom.example.project.SHOW_CURRENTquot /gt ltcategory
android:namequotandroid.intent.category.DEFAULTquot /gt ltdata
android:mimeTypequotvideo/mpegquot
android:schemequothttpquot . . . /gt ltdata
android:mimeTypequotimage/quot /gt ltdata
android:schemequothttpquot
android:typequotvideo/quot /gt完整的实例ltactivity
android:namequotNotesListquotandroid:labelquotstring/title_notes_listquotgt ltintent-filtergt ltactionandroid:namequotandroid.intent.action.MAINquot/gt ltcategoryandroid:namequotandroid.intent.category.LAUNCHERquot/gt lt/intent-filtergt ltintent-filtergt ltactionandroid:namequotandroid.intent.action.VIEWquot/gt ltactionandroid:namequotandroid.intent.action.EDITquot/gt ltactionandroid:namequotandroid.intent.action.PICKquot/gt ltcategoryandroid:namequotandroid.intent.category.DEFAULTquot/gt ltdataandroid:mimeTypequotvnd.
android.cursor.dir/vnd.google.notequot/gt lt/intent-filtergt ltintent-filtergt ltactionandroid:namequotandroid.intent.action.GET_CONTENTquot/gt ltcategoryandroid:namequotandroid.intent.category.DEFAULTquot/gt ltdataandroid:mimeTypequotvnd.
android.cursor.item/vnd.google.notequot/gt lt/intent-filtergtlt/activitygtIntent 用法实例1.无参数 Activity 跳转 Intent it new IntentActivity.Main.this Activity2.class startActivityit2.向下一个 Activity 传递数据(使用 Bundle 和 Intent.putExtras) Intent it new IntentActivity.Main.this Activity2.class Bundle bundlenew Bundle bundle.putStringquotnamequot quotThis is from MainActivityquot it.putExtrasbundle // it.putExtra“test” quotshuju” startActivityit // startActivityForResultitREQUEST_CODE对于数据的获取可以采用: Bundle bundlegetIntent.getExtrasStringnamebundle.getStringquotnamequot3.向上一个 Activity 返回结果(使用 setResult,针对 startActivityForResultitREQUEST_CODE启动的 Activity) Intent intentgetIntent Bundle bundle2new Bundle bundle2.putStringquotnamequot quotThis is from ShowMsgquot intent.putExtrasbundle2 setResultRESULT_OK intent4.回调上一个 Activity 的结果处理函数(onActivityResult)Override protected void onActivityResultint requestCode intresultCode Intent data // TODO Auto-generated method stub super.onActivityResultrequestCode resultCode data if requestCodeREQUEST_CODE ifresultCodeRESULT_CANCELED setTitlequotcanclequot else if resultCodeRESULT_OK String tempnull Bundle bundledata.getExtras ifbundlenull tempbundle.getStringquotnamequot setTitletemp 下面是转载来的其他的一些 Intent 用法实例(转自 javaeye)显示网页 1. Uri uri Uri.parsequothttp://google.comquot 2. Intent it new IntentIntent.ACTION_VIEW uri 3. startActivityit显示地图 1. Uri uri Uri.parsequotgeo:38.899533-77.036476quot 2. Intent it new IntentIntent.ACTION_VIEW uri 3. startActivityit 4. //其他 geo URI 范例 5. //geo:latitudelongitude 6. //geo:latitudelongitudezzoom 7. //geo:00qmystreetaddress 8. //geo:00qbusinessnearcity 9.//google.streetview:cblllatlngampcbp1yawpitchzoomampmzmapZoom路径规划 1. Uri uri Uri.parsequothttp://maps.google.com/mapsfdampsaddrstartLat20startLngampdaddrendLat20endLngamphlenquot 2. Intent it new IntentIntent.ACTION_VIEW uri 3. startActivityit 4. //where startLat startLng endLat endLng are a long with 6decimals like: 50.123456打电话 1. //叫出拨号程序 2. Uri uri Uri.parsequottel:0800000123quot 3. Intent it new IntentIntent.ACTION_DIAL uri 4. startActivityit 1. //直接打电话出去 2. Uri uri Uri.parsequottel:0800000123quot 3. Intent it new IntentIntent.ACTION_CALL uri 4. startActivityit 5. //用这个,要在 AndroidManifest.xml 中,加上 6. //ltuses-permission idquotandroid.permission.CALL_PHONEquot /gt传送 SMS/MMS 1. //调用短信程序 2. Intent it new IntentIntent.ACTION_VIEW uri 3. it.putExtraquotsms_bodyquot quotThe SMS textquot 4. it.setTypequotvnd.
android-dir/mms-smsquot 5. startActivityit 1. //传送消息 2. Uri uri Uri.parsequotsmsto://0800000123quot 3. Intent it new IntentIntent.ACTION_SENDTO uri 4. it.putExtraquotsms_bodyquot quotThe SMS textquot 5. startActivityit 1. //传送 MMS 2. Uri uri Uri.parsequotcontent://media/external/images/media/23quot 3. Intent it new IntentIntent.ACTION_SEND 4. it.putExtraquotsms_bodyquot quotsome textquot 5. it.putExtraIntent.EXTRA_STREAM uri 6. it.setTypequotimage/pngquot 7. startActivityit传送 Email 1. Uri uri Uri.parsequotmailto:xxxabc.comquot 2. Intent it new IntentIntent.ACTION_SENDTO uri 3. startActivityit 1. Intent it new IntentIntent.ACTION_SEND 2. it.putExtraIntent.EXTRA_EMAIL quotmeabc.comquot 3. it.putExtraIntent.EXTRA_TEXT quotThe email body textquot 4. it.setTypequottext/plainquot 5. startActivityIntent.createChooserit quotChoose Email Clientquot 1. Intent itnew IntentIntent.ACTION_SEND 2. String tosquotmeabc.comquot 3. String ccsquotyouabc.comquot 4. it.putExtraIntent.EXTRA_EMAIL tos 5. it.putExtraIntent.EXTRA_CC ccs 6. it.putExtraIntent.EXTRA_TEXT quotThe email body textquot 7. it.putExtraIntent.EXTRA_SUBJECT quotThe email subject textquot 8. it.setTypequotmessage/rfc822quot 9. startActivityIntent.createChooserit quotChoose Email Clientquot 1. //传送附件 2. Intent it new IntentIntent.ACTION_SEND 3. it.putExtraIntent.EXTRA_SUBJECT quotThe email subject textquot 4. it.putExtraIntent.EXTRA_STREAM quotfile:///sdcard/mysong.mp3quot 5. sendIntent.setTypequotaudio/mp3quot 6. startActivityIntent.createChooserit quotChoose Email Clientquot播放多媒体 Uri uri Uri.parsequotfile:///sdcard/song.mp3quot Intent it new IntentIntent.ACTION_VIEW uri it.setTypequotaudio/mp3quot startActivityit Uri uri Uri.withAppendedPathMediaStore.Audio.Media.INTERNAL_CONTENT_URI quot1quot Intent it new IntentIntent.ACTION_VIEW uri startActivityitMarket 相关1. //寻找某个应用2. Uri uri Uri.parsequotmarket://searchqpname:pkg_namequot3. Intent it new IntentIntent.ACTION_VIEW uri4. startActivityit5. //where pkg_name is the full package path for an application1. //显示某个应用的相关信息2. Uri uri Uri.parsequotmarket://detailsidapp_idquot3. Intent it new IntentIntent.ACTION_VIEW uri4. startActivityit5. //where app_id is the application ID find the ID6. //by clicking on your application on Market home7. //page and notice the ID from the address barUninstall 应用程序1. Uri uri Uri.fromPartsquotpackagequot strPackageName null2. Intent it new IntentIntent.ACTION_DELETE uri3. startActivityitserviceservice 是没有界面的长生命周期的代码。
一个很好的例子是媒体播放器从列表中播放歌曲。
在一个媒体播放器程序中,大概要有一个或多个活动(activity)来供用户选择歌曲并播放它。
然而,音乐的回放就不能使用活动(activity)了,因为用户希望他导航到其他界面时音乐继续播放。
这种情况下,媒体播放器活动(activity)要用 Context.startService启动一个服务来在后台运行保持音乐的播放。
系统将保持这个音乐回放服务的运行直到它结束。
注意一下,你要用Context.bindService方法连接服务(如果它没有运行,要先启动它)。
当连接到服务后,你可以通过服务暴露的一个接口和它通信。
.