大多数操作系l,在应用程序所寄存的可执行E序映像Q如Windowspȝ里的.exeQ、它所q行的进E以及和用户交互的图标和应用之间有一U严格的1?关系。在Androidpȝ里,q些兌要松散得多。ƈ且重要的是要理解各种概念怎么L成整体?/p>
׃Android应用固有的灵zL,当实现这些不同方面的时候有一些基本术语需要加以理解:
一个Android?Q?apkQ文Ӟ其中包含一个应用程序的代码和资源。这是应用程序分发和下蝲的文Ӟ用户用来安装该应用程序在他们的设备上?
一个Q务一般而言是指用户视ؓ的一个可启动应用E序Q通常d在桌面(home screenQ有一个可讉K的图标,且可以被切换到前台?
一个进E是一个运行着应用E序代码的底层核心过E。通常所?apk里的代码q行在一个专有的q程里。不q,q程标记也可以用来限定代码运行位|,或者ؓ整个.apk或者ؓ个别的活动activityQ接收者receiverQ服务或提供者providerQ组件?
d
q里的一个关键点是:当用LC?#8220;应用”Ӟ他们实际上在和Q务打交道。如果您刚刚创徏一个包含若q活动的.apkQ其中之一是顶层入口点Q?q动作android.intent.action.MAIN的意图过滤器intent-filter和类?android.intent.category.LAUNCHERQ,那么q事实上ؓ您的.apk创徏一个Q务,q且您从那儿起动的Q何活动都作?那个d的一部分q行?/p>
一个Q务,那么Q从用户的角度来看是您的应用E序;而从应用E序开发者的角度来看Q它是一个或多个用户在那个Q务中已经l历q且未关闭的zdQ或?说是一个活动栈。一个新的Q务通过以Intent.FLAG_ACTIVITY_NEW_TASK标志起动一个活动意图来创徏;q一意图被用来作ؓd 的根意图Q定义Q务是什么。Q何不以这个标志v动的zd和起动它的zd在相同的d中运行(除非该活动已h特别启动模式Q稍后会讨论Q。Q务可以被?新安排:如果您用FLAG_ACTIVITY_NEW_TASK标志但已l有一个Q务以q个意图q行Q则当前d的活动栈被切换到前台而不是开始一?新的d?/p>
FLAG_ACTIVITY_NEW_TASK必须谨慎使用Q用它意味着Q在用户看来Q一个新的应用程序由此v动。如果这不是你所期望的行为,?׃该去创徏一个新的Q务。另外,仅在用户可以从桌面返回到他原来的地方和以一个新d启动相同意图的情况下Q你才应该用新的Q务标记。否则,如果用户 在你已经启动的Q务里按桌面(HOMEQ键Q而不是返回(BACKQ键Q你的Q务及其活动将被放|到桌面后面Q没有办法再切换回去?/p>
dq性Affinity
在某些情况下QAndroid需要知道一个活动属于哪个Q务即使它没有被启动到一个具体的d里。这是通过dq性(AffinitiesQ完?的。Q务共用性(AffinitiesQؓq个q行一个或多个zd的Q务提供了一个独特的静态名Uͼ默认的一个活动的dq性(AffinityQ是?C该活动的.apk包的名字。这提供了预期的标准Ҏ,x有在一个特定的.apk包里的活动是单个用户应用E序的一部分?/p>
当开始一个没有Intent.FLAG_ACTIVITY_NEW_TASK标志的活动时QQ务共用性affinities不会影响会q行该新z?动的d:它Lq行在启动它的Q务里。但是,如果使用了NEW_TASK标志Q那么共用性(affinityQ将被用来判断是否已l存在一个有相同q 性(affinityQ的d。如果是q样Q这Q务将被切换到前面而新的活动会启动于这个Q务的层?/p>
q种Ҏ在您必M用NEW_TASK标志的情况下最有用Q尤其是从状态栏通知或桌面快h式启动活动时。结果是Q当用户用这U方式启动您的应用程序时Q它的当前Q务将被切换到前台Q而且惌查看的活动被攑֜最上面?/p>
你可以在E序清单QManifestQ文件的应用E序application标签中ؓ.apk包中所有的zd分配你自qdq性AffinitesQ或者在zd标记中ؓ各个zdq行分配。一些说明其如何使用的例子如下:
如果您的.apk包含多个用户可以启动的高层应用程序,那么您可能需要对用户看到的每个活动指定不同的affinities。一个不错的命名惯例?以附加一个以冒号分隔的字W串来扩展您?apk包名。例如,“ com.android.contacts ”.apk可以有affinities:“com.android.contactsQDialer”?#8220; com.android.contactsQContactsList”?
如果您正在替换一个通知Q快h式,或其他可以从外部发v的应用程??#8220;内部”zdQ你可能需要明设定您替代zd的taskAffinity和您准备替代的应用程序一栗例如,如果您想替换contacts详细信息视图 Q用户可以创建ƈ调用快捷方式Q,你得把taskAffinity讄?#8220;com.android.contacts”?
启动模式和启动标?/p>
您控制活动和d交互的主要途径是通过zd的launchMode 属性和意图相关的标志flags。这两个参数可以以各U方式合作来控制zd启动的结果,正如它们相关文档中描q的那样。在q里Q我们将看看一些常见的用例和参数组合?/p>
你将使用的最常见的启动模式(除了默认的standard模式Q是singleTop。这q不影响d;它只是避免多ơ在一个堆栈顶部v动同一zd?/p>
singleTask启动模式对Q务有重大的媄响:它ɋzd始终是开始于一Ҏ的Q务(或其现有的Q务被带到前台Q?。用这U模式需要}慎对待你如何与系l其他部分进行交互,因ؓq媄响到q个zd中的每一个\径。它应当仅在zd处于应用E序前台时用(也就是支?MAIN动作和LAUNCHERcdQ?/p>
singleInstance启动模式更是专业Qƈ应仅用于整个是被实Cؓ一个活动的应用E序中?/p>
有一U你会经帔R到的情况是当另一个实体(如SearchManager 或NotificationManagerQ开始您的一个活动。在q种情况下,必须使用Intent.FLAG_ACTIVITY_NEW_TASK 标签Q因Ҏ动是在Q务之外v动的Q而且应用/d可能Ҏ不存在)。正如前面所qͼq种情况下的标准行ؓ是把匚w新活动affinity的Q务带?前台和在此之上v动新的活动。不q,也有其他您可以实施的行ؓcd?/p>
其中一U常见的做法是,q可以用Intent.FLAG_ACTIVITY_CLEAR_TOP 国旗与NEW_TASK 。通过q样做,如果你的d已经q行Q那么将提请前景Q所有的zdQ其堆栈清除除根pL力和根系zd的onNewIntent Q意图) 所谓的意图正在开始。请注意Q该zdq常怋用singleTop 或singleTask 发射模式Ӟ使用q种ҎQ因此,目前的情冉|׃新的意图而不需要将它摧毁,一个新的实例开始?/p>
一U通常的办法是和NEW_TASK联合h使用Intent.FLAG_ACTIVITY_CLEAR_TOP标志。这P如果您的d已经q?行,那么它将会被带到前台Q除Ҏ动外其它所有堆栈中的活动都被清除,而且q个Ҏ动的ҎonNewIntent(Intent)会在该意图v动时被调 用。注意这个活动用这个方法时l常使用singleTop或者singleTask起动模式Q这样当前实例被赋予新的意图而不是需要销毁它然后重新起动 一个新的实例?/p>
您能采取的另外的Ҏ是设|通知zd的Q务affinity为空字符?#8220;”Q表C没有affinityQ,q设|?finishOnBackground属性。这U方法是有用的如果你希望q个通知把用户带C个单独的描述它的zd中,而不是返回到应用E序的Q务。通过 指定q个属性,该活动将被结束不用户通过BACKq是HOMEd?如果q个属性没有指定,按首将Dq个zd及其d仍保留在pȝ里,且可能没?办法q回它?/p>
请务必阅d于launchMode属性和Intent标志的文档以获取q些选项的详l说明?/p>
q程
在Android里,q程完全是应用的实现l节Q而不是用户通常了解的那栗其主要用途就是:
通过安置不受信Q的或不稳定的代码到另一个进E来提高E_性或安全性?
通过在同一q程里运行多?apks的代码来减少开销?
通过把重量代码攑֜单独的进E中来帮助系l管理资源,该进E可以在不媄响应用程序其他部分的情况下被l止?
正如前面所qͼq个q程属性用来控制运行着特定应用E序lg的进E,注意Q此属性不能用于违反系l安全性:如果有两个不׃n相同用户ID?apks试q行在同一q程中,q将不会被允许,相反会ؓ它们每一个创Z同的q程?/p>
参见安全 文档以获取更多关于安全限制方面的信息?/p>
Android相关内容:
U程
每个q程包含一个或多个U程。多数情况下QAndroid避免在进E里创徏额外的线E,以保持应用程序单U程Q除非它创徏自己的线E。一个重要的l?果就是所有对zdActivityQ广播接收器BroadcastReceiver以及服务Service实例的调用都是由q个q程的主U程创徏的?/p>
注意新的U程q不会ؓ每个zdQ广播接收器Q服务或者内Ҏ供器QContentProviderQ实例而创建:q些应用E序的组件在q程里被实例 化(除非另有说明Q都在同一个进E处理)Q实际上是进E的ȝE。这说明当被pȝ调用时没有哪个组Ӟ包括服务Q会q行q程或者阻塞操作(像|络调用?者计@环)Q因阻止进E中的所有其他组件。你可以使用标准的线E类Thread或者Android的HandlerThread便捷cd对其它线 E执行远E操作?/p>
q里有一些关于这个线E规则的重要的例外:
?对IBinder或者IBinder实现的接口的调用p用线E或本地q程的线E池Q如果该呼叫来自其他q程Q分发,而不是它们的q程的主U程。特D情?下,一个服务的IBinder可以q样调用。(管调用服务里的Ҏ已经在主U程里完成。)q意味着IBinder接口的实现必要有一U线E安全的?法,q样LU程才能同时讉K它?br />
?对ContentProvider主要Ҏ的调用由调用U程或者主U程分发,如同IBinder一栗被指定的方法在内容提供器的c里有记录。这意味着实现q些Ҏ必须要有一U线E安全的模式Q这样Q意其它线E可以同时访问它?br />
?视图及其子类中的调用由正在运行着视图的线E生。通常情况下,q会被作E的ȝE,如果你创Z个线Eƈ昄一个窗口,那么l承的窗口视囑ְ从那个线E里启动?/p>
看下错误描述Q是
import com.android.phone.CallLogAsync;
import com.android.phone.HapticFeedback;
~失q两个引用,呵呵Q明白了Q导入电话编译生成的Jar?
out\target\common\obj\APPS\Phone_intermediates\classes.jar
OKQ就q么~译通过了,好了Q下周一可以开始和同事一起阅读该代码?nbsp;记录下来Q希望对别的朋友能有一点点帮助