为了复用Activity,我将项目里所有的Activity在启动时加上了FLAG_ACTIVITY_REORDER_TO_FRONT,后来由于美观的需求,将所有Activity的Theme加上了<item name="android:windowIsTranslucent">true</item>,结果惊讶地发现FLAG_ACTIVITY_REORDER_TO_FRONT失效了。
当我用FLAG_ACTIVITY_REORDER_TO_FRONT reoder一个Activity到栈顶的时候,发现该Activity的onResume的确调用了,但是就是没有显示在屏幕上。
我对FLAG_ACTIVITY_REORDER_TO_FRONT的理解是这样的:
/** * Intent.FLAG_ACTIVITY_REORDER_TO_FRONT这个标志表示: * 如果这个activity已经启动了,就不产生新的activity, * 而只是把这个activity实例加到栈顶来就可以了。 * 会触发onResume事件 */
后来一番Google,发现还真有人跟我遇到了一样的问题,StackOverflow上的同僚把它称为Bug:http://stackoverflow.com/questions/9309479/bug-theme-translucent-flag-activity-reorder-to-front 。从这里我知道去掉android:windowIsTranslucent之后的确一切正常,但是这很明显不是我想要的结果。
在StackOverflow上面的回复中,有人提到将launchMode设为singleInstance即可解决问题。我测试了一下,的确如此,既可以单例又可以透明。然而singleInstance的意思是一个Activity独占一个Task,这也未免太浪费了,于是我改为了singleTask,这样可以节省一些开销。
附录一份launchMode和FLAG的说明复习备用:
我们都知道,通过Intent启动Activity有两种形式:
显式的指向某个Activity
Intent intent = new Intent(this, Activity1.class); startActivity(intent);隐式的通过设置Intent的动作启动Activity
Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.google.com")); startActivity(intent);Activty是Android四大组件中负责与用户交互的部件,Activity承担了大量的显示和交互工作,从某种角度上将,我们看见的应用程序就是许多个Activity的组合。
Task Stack
为了让这许多Activity协同工作而不至于产生混乱,Android平台设计了一种堆栈机制用于管理Activity,其遵循先进后出的原则,系统总是显示位于栈顶的Activity,从逻辑上将,位于栈顶的Activity也就是最后打开的Activity,这也是符合逻辑的。这个栈也可以叫做Task Stack,因为一个Task Stack里的Activity是可以属于不同的Application的。例如:你想在发送短信时,拍一张照并作为彩信发出去,这时你首先停留在短信应用程序的的Acitivity上,然后跳转到Camera应用程序的Activity上,当完成拍照功能后,再返回到短信应用程序的Activity。这实际上是两个Android Application协同合作后完成的工作,但为了更好的用户体验,Android平台加入了Task这么一种机制,让用户没有感觉到应用的中断,让用户感觉在一“应用程序”里就完成了想完成的工作。
值得注意点的时候,一个系统里可以有很多的Task Stack,当后台的Task过多的时候,系统可能会去除栈底的Activity,释放多余的内存。
保存Activity状态
当Task Stack中的Activity返回前台的时候,可能已经是被系统释放点重新创建的,为了用户的操纵信息得到保留,我们最好重写onSaveInstanceState
方法。 Managing Tasks
我们在平常写程序的时候,Activity的启动方式保持默认就已经够用了。但是遇到特定场合,我们可以通过对启动方式的更改来修改Activity在Task中的运行状态。
Activity的启动状态我们可以在AndroidManifest.XML中定义,抑或直接通过Intent传相应的数值对。
操作manifest文件,Activity状态设置是其节点launchMode属性定义,共有四种形式:
“standard”
默认方式,Activity可以创建多次,分布在不同的Task Stack中,有相应不同的实体。“singleTop”
通过此方法启动的Activity如果在栈顶的话,当再次收到启动的Intent,将不会再创建新实例,而是直接执行onNewIntent方法。Activity可以有多个实例,在每个Task Stack中除非不在栈顶,在接受到启动的Intent的时候都不会创建新实例。
比如一个Task Stack:A->B->C->D,如果是Standard模式,当收到D的启动Intent时,Stack:A->B->C->D->D,如果是SingleTop模式,Stack:A->B->C->D。而当收到的是B的启动Itent时,Stack:A->B->C->D->B,因为B不在栈顶。“singleTask”
这种模式下,Activity只能存在一个实例,当再次收到启动的Intent时,直接执行onNewIntent方法。 “singleInstance”
类似于singleTask,不同的地方是,Activity只能有一个实例,而且该实例的Task Stack只能有这个Activity,也就是说通过该模式启动的Activity在Task Stack中即是栈顶也是栈底。Intent通过setFlags或者addFlags方法添加数值对,默认方式是不用做任何操作的,除此之外还有三种形式:
FLAG_ACTIVITY_NEW_TASK
启动一个新的Task Stack,当包括Activity的Task已经存在的时候,这个Task将会直接在前台显示,类似与singleTask。FLAG_ACTIVITY_SINGLE_TOP
当这个Intent启动的前台的Activity,将不会创建新实例,而是直接执行onNewIntent,类似于singleTop。 FLAG_ACTIVITY_CLEAR_TOP
如果启动的Activity在Task Stack中,其余的Activity都会被弹出释放,不会创建新实例,而是执行onNewIntent。
知识共享署名-非商业性使用-相同方式共享:码农场 » 解决Theme.Translucent 下 FLAG_ACTIVITY_REORDER_TO_FRONT 的问题