详解Activity之singletast启动模式及如何使用intent传值
activity的四种启动模式:
1. standard
模式启动模式,每次激活activity时都会创建activity,并放入任务栈中。
2. singletop
如果在任务的栈顶正好存在该activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在该activity实例,只要不在栈顶,都会创建实例)。
3. singletask
如果在栈中已经有该activity的实例,就重用该实例(会调用实例的onnewintent())。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移除栈。如果栈中不存在该实例,将会创建新的实例放入栈中。
4. singleinstance
在一个新栈中创建该activity实例,并让多个应用共享改栈中的该activity实例。一旦改模式的activity的实例存在于某个栈中,任何应用再激活改activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该activity都会进入同一个应用中。
因为项目中,有一个消息推送的功能,每次推送一个消息,就会开启functionactivity,那么为了避免重复开启它,在退后的时候,多次出现该activity,就将该activity的启动模式变为singletask。
这样在之后的多次启动该activity,便会调用onnewintent(intent intent)方法。
activity通过intent传递数据的时候,如果activity未启动,那么 在这个刚启动的activity里通过getintent()会获取到这个intent的数据.如果要启动的activity是已经存在的,这时候通过 getinten()方法获取到的intent是已启动的activity的原始intent.换句话说intent的数据没有更新.这样在已启动的 activity里拿到的intent的数据是旧数据.如果要每次获取intent传来的新数据就需要在onnewintent(intent intent)方法里调用setintent(intent)设置这个传来的最新的intent.如下所示:
@override protected void onnewintent(intent intent) { super.onnewintent(intent); log.e("tag", "onnewintent执行了"); setintent(intent); string ringname = intent.getstringextra("ringname"); log.e("tag", ringname+"传过来的值"); if (ringname != null) { pager.setcurrentitem(1); } }
当然,如果activity的启动模式是standard,那么每次都重新创建一个新的activity.这样intent也是最新的.就不用通过setintent来更新这个intent.
我这个项目中,functionactivity中里面是四个fragment,这样 我从其他activity跳转到functionactivity是不会实例化,通过getintent()方法也不能获得最新的intent,为了解决 这个办法。还是在onnewintent方法中,将更新的intent通过getintent().putextras(intent);共享出去,如下 所示:
@override protected void onnewintent(intent intent) { super.onnewintent(intent); log.e("tag", "onnewintent执行了"); setintent(intent); getintent().putextras(intent); }
这样在与它关联的fragment中,就可以调用
@override public void onresume() { super.onresume(); // 第一次进入这个页面,下面的方法是不会执行的,因为ringname是null string ringname = getactivity().getintent().getstringextra("ringname"); if (ringname != null) { newsound.settext(ringname); log.e("tag", ringname + "要保存的值"); sharedpreferenceutil.setstring(getactivity(), sharedpreferenceutil.ringtone_name, ringname); } }
注意,这里fragment调用的时候,一定要在onresume方法中。