北京大型网站优化,购物小程序开发公司,线上推广宣传方式有哪些,桂林漓江景区介绍Thanks to:http://www.cnblogs.com/SteveMing/archive/2012/04/24/2459575.html 【原】Activity的LaunchMode和taskAffinity 做项目到现在都一直没有理解LaunchMode有什么用#xff0c;或许根本就没真正花心思去看#xff0c;所以今天把这部分整理下。 设置Activity的Launc… Thanks to:http://www.cnblogs.com/SteveMing/archive/2012/04/24/2459575.html 【原】Activity的LaunchMode和taskAffinity 做项目到现在都一直没有理解LaunchMode有什么用或许根本就没真正花心思去看所以今天把这部分整理下。 设置Activity的LaunchMode属性可以决定这个Activity是和当前Task保持关联还是说每次运行这个Activity是新建一个实例还是保持单例。 Task和Back Stack简介 task是一组Activities的集合一组Activities被Stackback stack所管理。 在一个应用中有3个activities分别是activity1activity2activity3首先activity1被start此时如果应用没有创建task则创建并把activity1压入栈顶activity1触发onCreate-onStart-onResume。 接着activity1转向到activity2时activity1先触发onPause,activity2触发onCreate-onStart-onResume然后activity1触发onPause-onStopactivity2压入栈顶。 以此类推activity2转向activity3也是一样的步骤。那么当前栈顶是activity3。 当我们按下手机上的返回键时栈顶的activity3触发onPauseactivity2需要从状态stop到pause所以触发了onPause-onStart-onResumeactivity3触发onStop-onDestory因为activity3从栈顶弹出所以触发onDestory此时activity2在栈顶。 如果继续按返回键当前栈顶的activity弹出并被destory直到home界面。当所有的activity都弹出了这个task也就消亡了。 当开始一个新的task时前一个task被设置为后台在后台所有的activity都处理stop状态但是back stack保留了所有后台activity的状态信息只是丢失了焦点。 反复的在两个activity之间切换activity会产生多个独立的实例。 查阅有关Activity生命周期更多说明。 两种方式设置LaunchMode属性 1. 在 manifest文件中设置 activity android:name.activity.ActivityAandroid:launchModestandardintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity 2. 使用Intent flags设置 Intent intent new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(ActivityA.this, ActivityB.class);
startActivity(intent); 四种LaunchMode说明 standard 不做任何设置默认模式就是standardactivity在每次start时都会有一个新的实例被task管理。下面看下代码实例。 //ActivityA.java
Intent intent new Intent();
intent.setClass(ActivityA.this, ActivityB.class);
startActivity(intent);//ActivityB.java
Intent intent new Intent();
intent.setClass(ActivityB.this, ActivityA.class);
startActivity(intent); 操作1在ActivityA(蓝)和ActivityB(绿)之间重复切换按返回键推到home界面。 可以发现(蓝色86和绿色79的taskID)ActivityA和ActivityB都在同一个task并且每次resume的实例都是不一样的。这说明在一个activity可以有多个实例在同一个task中。 在按返回按键时将依次弹出stack。 singleTop 和standard一样可以多次实例但如果处于当前栈顶并且接受到一个与当前activity一样类型的intent那么不会创建一个新实例而是触发onNewIntent()事件。 //ActivityA.java
Intent intent new Intent();
intent.setClass(ActivityA.this, ActivityA.class);
startActivity(intent);Override
protected void onNewIntent(Intent intent) {logger.d(onNewIntent this.hashCode() taskID this.getTaskId());super.onNewIntent(intent);
} activity android:name.activity.ActivityA android:labelActivityAandroid:launchModesingleTopintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity 操作1点击ActivityA上的按钮 发现当点击按钮是ActivityA-onPause-onNewIntent-onResume没有新建新的实例(蓝62)。 这个模式在这个场景下比较有用比如如果有一个其他的应用想启动你的Activity(launch mode为singleTop)而你当前的Activity正好在栈顶那么就会调用到onNewIntent方法。原文贴上If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its onNewIntent() method。 singleTask 系统会创建一个新task(如果没有启动应用)和一个activity新实例在新task根部然后如果activity实例已经存在单独的task中系统会调用已经存在activity的 onNewIntent()方法而不是存在新实例仅有一个activity实例同时存在。运用实例浏览器主界面。不管跳转多少页面主界面只启动一次其余都走onNewIntent并清空主界面上的其他页面。 activity android:name.activity.ActivityA android:labelActivityA android:launchModestandardintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity
activity android:name.activity.ActivityB android:labelActivityB android:launchModesingleTaskintent-filteraction android:nameandroid.intent.action.MAIN //intent-filter
/activity
activity android:name.activity.ActivityC android:labelActivityC android:launchModestandardintent-filteraction android:nameandroid.intent.action.MAIN //intent-filter
/activity 操作1ActivityA-ActivityB-ActivityC-ActivityA-ActivityB-ActivityC 可以看到当再次进入ActivityB时没有onCreate而是onNewIntent(绿55)。 这里我们也可以发现一个现象当在调用到ActivityB的onNewIntent时之前的ActivityA和ActivityC都调用了onDestory。也就是说系统发现栈中存在ActivityB的实例时ActivityA和ActivityB都弹栈了。 列出Log日志(这里设ActivityA的LaunchMode为singleTask)ActivityB和ActivityC都在onNewIntent前后调用了onDestory。 singleInstance 和singleTask相似除了系统不会让其他的activities运行在所有持有的task实例中这个activity是独立的并且task中的成员只有它任何其他activities运行这个activity都将打开一个独立的task。实例运用适合与程序分离的页面如闹铃提醒。 activity android:name.activity.ActivityA android:launchModesingleTaskintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity
activity android:name.activity.ActivityB android:launchModesingleInstanceintent-filteraction android:nameandroid.intent.action.MAIN //intent-filter
/activity
activity android:name.activity.ActivityCintent-filteraction android:nameandroid.intent.action.MAIN //intent-filter
/activity 操作1ActivityA-ActivityB-ActivityA 可以发现两个Activity是在不同的Task中其次当调用到onNewIntent时ActivityB没有被Destory互不干涉。 操作2ActivityA-ActivityB-ActivityC按返回键 图解 刚进入应用创建TaskAActivityA为栈顶从ActivityA到ActivityBActivityB进入TaskB(如果再次进入ActivityB则不创建Task调用onNewIntent)此时TaskB中的ActivityB为栈顶从ActitivyB到ActivityCActivityC为栈顶。 一直按返回键先从TaskA中依次将Activity弹出然后再从TaskB中将ActiviyB弹出。ActiviyC-ActivityA-ActivityB。 这里分析一个问题浏览器的LaunchMode为singleTask所以如果当你点击一个连接下载文件时(由一个activity来处理下载launchmode为standard)如果再次进入浏览器那么下载页面就被Destory了那么这里我们可以把下载页面LaunchMode设置为singleInstance可以解决这个问题。 Affinity定义 Affinity更像是表明了activity属于哪个task默认情况下应用所有的activities都有相同的affinity所以都是在相同的task中。然后你可以编辑默认的affinity。Activities定义在不同的应用可以共享一个affinity或者activities定义在相同的应用中可以被不同的affinities所关联。 你可以编辑在activity元素中activity的taskAffinity属性。 先看看两种不同的情况下affinity的表现 当运行一个activity包含了FLAG_ACTIVITY_NEW_TASK标记 //ActivityA.java
Intent intent new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(ActivityA.this, ActivityB.class);
startActivity(intent); activity android:name.activity.ActivityA android:taskAffinitycom.android.demo.affinity1intent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity
activity android:name.activity.ActivityB android:taskAffinitycom.android.demo.affinity2intent-filteraction android:nameandroid.intent.action.MAIN //intent-filter
/activity 操作1不同的affinity值ActivityA-ActivityB 如果已经存在相同affinity那么新activity运行在这个task中否则系统创建新task。 操作2相同的affinity值ActivityA-ActivityB activity android:name.activity.ActivityA android:taskAffinitycom.android.demo.affinity1intent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity
activity android:name.activity.ActivityB android:taskAffinitycom.android.demo.affinity2intent-filteraction android:nameandroid.intent.action.MAIN //intent-filter
/activity 可以看出ActivityA和ActivityB都运行在同一个task中。 当Activity的allowTaskReparenting的属性设为true 使用来表示是否允许activity重新附属其他Task还是举例说明吧。 有两个应用Demo1和Demo2Demo1中有2个Activity(ActivityAActivityC)ActivityA可以转向到ActivityCDemo2中有一个Activity(ActivityB)也可以转向到ActivityC。 操作1设置ActivityC的allowTaskReparenting属性为true。 运行Demo2转向到ActivityC在ActivityC中打印信息返回到HOME界面运行Demo1。 //Demo1
//ActivityA.java
Intent intent new Intent();
intent.setClass(ActivityA.this, ActivityC.class);
startActivity(intent);//ActivityC.java
tv.setText(ActivityC.this.toString());//Demo2
//ActivityB.java
Intent intent new Intent();
intent.setClassName(com.android.demo,com.android.demo.activity.ActivityC);
ActivityB.this.startActivity(intent); //Demo1
activity android:name.activity.ActivityAintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity
activity android:name.activity.ActivityC android:allowTaskReparentingtrueintent-filteraction android:nameandroid.intent.action.MAIN //intent-filter/activity
//Demo2
activity android:name.ActivityBintent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter/activity 运行结果(黄色Demo1绿色Demo2) ActivityB转向到ActivityC此时ActivityC就关联到Demo2的Task中TaskID都为231。在运行Demo1时看到是ActivityC而不是ActivityA。当再次进入Demo2时就看不到ActivityC了。 操作2将ActivityC的taskAffinity设置为com.android.demo.activityc。 运行Demo2转向到ActivityC在ActivityC中打印信息返回到HOME界面运行Demo1。 //Demo1
activity android:name.activity.ActivityCandroid:taskAffinitycom.android.demo.activitycandroid:allowTaskReparentingtrueintent-filteraction android:nameandroid.intent.action.MAIN //intent-filter/activity 运行结果 从结果中可以看出Demo1和Demo2都拥有ActivityC也就是说有2个Task里存在ActivityC分别被Demo1和Demo2所使用。 操作3将ActivityC和ActivityB的taskAffinity都设为com.android.demo.activityc。 运行Demo2转向到ActivityC在ActivityC中打印信息返回到HOME界面运行Demo1。 //Demo2
activity android:name.ActivityB android:taskAffinitycom.android.demo.activitycintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter
/activity//Demo1
activity android:name.activity.ActivityCandroid:taskAffinitycom.android.demo.activitycandroid:allowTaskReparentingtrueintent-filteraction android:nameandroid.intent.action.MAIN //intent-filter
/activity 运行结果 和操作1相反再进入Demo2时看到是ActivityC进入Demo1都是看到ActivityA。 写到最后越来越崩溃了如果有什么地方写的不对或不清楚请指明。 转帖请说明原文出处http://www.cnblogs.com/SteveMing/archive/2012/04/24/2459575.html 另一篇 图文并茂 http://www.androidchina.net/3173.html 两种设置方式 1) XML activity android:name.ActivitySubandroid:launchModesingleInstance
/activity2)在java代码中设置intent.setFlags() Intent intent new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(this,ActivitySub.ckass);
startActivity(intent);