ActivityGroup的简单用法(1)--详细讲解
1.首先要通过getLocalActivityManager()方法得到一个LocalActivityManager
LocalActivityManager am= getLocalActivityManager();
2.然后通过LocalActivityManager的startActivity(String id, Intent intent),可以与指定的Actiivty绑定,并且返回一个Window。LocalActivityManager可以同时管理多个Activity
Window window1 = am.startActivity("Module1", newIntent(TestView.this, ModuleView1.class)); Window window2 = am.startActivity("Module2", newIntent(TestView.this, ModuleView2.class));
实际中多用简写形式,如,
container是ScrollView的一个实例
container.removeAllViews(); //移除其他所有子视图 container.addView(getLocalActivityManager().startActivity( "Module2", new Intent(TestView.this, ModuleView2.class) .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) ) .getDecorView());
参见老农博客:
http://www.cnblogs.com/over140/archive/2010/09/07/1820876.html
注意:container.removeAllViews():表示在显示该视图之前,先移除其他所有视图.
Intent.FLAG_ACTIVITY_CLEAR_TOP:如果在当前Task中,有要启动的Activity,那么把该Acitivity之前的所有Activity都关掉,并把此Activity置前以避免创建Activity的实例
这种方式具有很大的灵活性,常用的就是实现TabHost分页效果,但很好的避免的TabHost的缺点,如title等
如果已经启动了四个Activity:A,B,C和D。在D Activity里,我们要跳到B Activity,同时希望C finish掉,可以在startActivity(intent)里的intent里添加flags标记,如下所示:
- Intent intent = new Intent(this, B.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
- startActivity(intent);
Intent intent = new Intent(this, B.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent);
这样启动B Activity,就会把D,C都finished掉,如果你的B Activity的启动模式是默认的(multiple) ,则B Activity会finished掉,再启动一个新的Activity B。 如果不想重新再创建一个新的B Activity,则在上面的代码里再加上:
- intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
这样B Activity就会再创建一个新的了,而是会重用之前的B Activity,同时调用B Activity的onNewIntent()方法。
问题:
多activity中退出整个程序,例如从A->B->C->D,这时我需要从D直接退出程序。
网上资料:{
finish()和system(0)都只能退出单个activity。杀进程等的等方式都不行~~~
解决问题:
我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在D窗口打开A窗口时在Intent中直接加入标志Intent.FLAG_ACTIVITY_CLEAR_TOP,再次开启A时将会清除该进程空间的所有Activity。
在D中使用下面的代码:
- Intent intent = new Intent();
- intent.setClass(D.this, A.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //注意本行的FLAG设置
- startActivity(intent);
- finish();
Intent intent = new Intent(); intent.setClass(D.this, A.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //注意本行的FLAG设置 startActivity(intent); finish();
关掉自己
在A中加入代码:
- Override
- protected void onNewIntent(Intent intent) {
- // TODO Auto-generated method stub
- super.onNewIntent(intent);
- //退出
- if ((Intent.FLAG_ACTIVITY_CLEAR_TOP & intent.getFlags()) != 0) {
- finish();
- }
- }
Override protected void onNewIntent(Intent intent) { // TODO Auto-generated method stub super.onNewIntent(intent); //退出 if ((Intent.FLAG_ACTIVITY_CLEAR_TOP & intent.getFlags()) != 0) { finish(); } }
A的Manifest.xml配置成android:launchMode=”singleTop”
原理总结:
一般A是程序的入口点,从D起一个A的activity,加入标识Intent.FLAG_ACTIVITY_CLEAR_TOP这个过程中会把栈中B,C,都清理掉。因为A是android:launchMode=”singleTop”
不会调用oncreate(),而是响应onNewIntent()这时候判断Intent.FLAG_ACTIVITY_CLEAR_TOP,然后把A finish()掉。
栈中A,B,C,D全部被清理。所以整个程序退出了。
下面是关于API的介绍:
1.类的概述:
从API上可以看出ActivityGroup继承Activity,也就是说它和Activity有一样的生命周期。以及创建方法。
A screen that contains and runs multiple embedded activities.
从API上对ActivityGroup的概述可以知道,这个类可以用其他的Activity更新UI。
2.用法:
用getLocalActivityManager()得到一个LocalActivityManager对象,对于LocalActivityManager这个类,API是这样说明的:
Helper class for managing multiple running embedded activities in the same process. This class is not normally used directly, but rather created for you as part of the ActivityGroup implementation.
这是一个辅助类,用来管理多个Activity运行在同一个进程当中。这个类不像平常其他的类那样直接使用,但是当创建ActivityGroup时,它会作为其中的一部分被创建。
getLocalActivityManager().startActivity(String str,Intent intent) 得到LocalActivityManager对象后使用startActivity(String str, Intent intent)方法得到一个Window对象。Window是一个抽象类,API是这样说明的:
Abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc. The only existing implementation of this abstract class is android.policy.PhoneWindow, which you should instantiate when needing a Window. Eventually that class will be refactored and a factory method added for creating Window instances without knowing about a particular implementation.
抽象基类用于顶层窗口的外观以及动作规划。这个类的实例应该作为顶级视图添加窗口管理器。它提供了标准的UI政策,例如背景,标题,错误处理等。 android.policy.phonewindow是对这个抽象类的唯一实现,当你需要一个特定的窗口实例时。最终,这个类将被重构和在不直到特定实例情况下用工厂方法创建窗口。getLocalActivityManager().startActivity(str,intent).getDecorView() 得到Window对象后,使用getDecorView()方法得到一个对顶级窗口的decor view。然后用addView()方法将decor view添加到顶级窗口中
3.异常处理:
在调用addView()之前需要先调用removeAllViews()方法,否则会出现java.lang.IllegalStateException
用Intent调用其他的Activity时,需要在AndroidMainfest中注册,否则会出现java.lang.NullPointerException
4.疑惑:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);这一句有待推敲。无论有没有使用这一句程序都正常运行。查看API中对startActivity(String str,Intent intent)的说明:
If the current activity uses a non-multiple launch mode (such as singleTop), or the Intent has the FLAG_ACTIVITY_SINGLE_TOP flag set, then the current activity will remain running and its Activity.onNewIntent() method called.
If the new Intent is the same (excluding extras) as the previous one, and the new Intent does not have the FLAG_ACTIVITY_CLEAR_TOP set, then the current activity will remain running as-is.
Otherwise, the current activity will be finished and a new one started.
If the given Intent can not be resolved to an available Activity, this method throws ActivityNotFoundException.
如果当前的Activity使用非多发射方式(例如只有顶层),或者Intent带有FLAG_ACTIVITY_SINGLE_TOP标志,所以当前活动的Activity继续活动,Activity.onNewIntent()方法将会被调用。
如果新的Activity与当前运行的相同(不含额外的部分),而且Intent不含有FLAG_ACTIVITY_SINGLE_TOP标志,当前的Activity将会保持现状继续运行。
否则当前的Activity将会被终止,新的Activity将会被开启。
如果Intent不能打开一个可运行的Activity,这个方法将会抛出ActivityNotFoundException。
从API中可以看出,Intent加了FLAG_ACTIVITY_SINGLE_TOP标志,当调用新的Activity时,当前的Activity并没有真的结束。但是根据实例得出结果,Intent有该标志,调用新的Activtiy(ModuleView1)时,正常启动,然后调用新的Activity(ModuleView2),Activity(ModuleView1)被onPause(),再调用Activity(ModuleView1)时,Activity(ModuleView2)先被onPause(),接着Activtiy(ModuleView1)被onStop()-onDestroy()。接着创建一个新的Activity(ModuleView1)。即使第二步是重复调用Activity(ModuleView1),也需要先onStop()-onDestroy(),然后接着创建一个新的Activtiy(ModuleView1)。结束application时,只销毁一次ModuleView1。
当intent没有加FLAG_ACTIVITY_SINGLE_TOP标志,首先调用一个新的Activity(ModuleView1),正常启动。再调用一个Activity(调用ModuleView1),Activity并没有调用onPause,而重新启动时,Activity也没有像一个正常的Activity一样启动,而是直接使用前一个Activity。此时结束整个application时,系统对ModuleView1这个Activity也只销毁一次。当第二次调用的Activity不是ModuleView1时,对ModuleView1也会调用onPause()方法。接着再调用ModuleView1时,这个Activity直接从onResume()启动。
对API上说的会调用Activity.onNewIntent()方法,在例子中并没有被使用到。需要继续探索。。。。
5.说明:
红色字体来自Android SDK文档,蓝色为翻译。
对4中所使用到的那个例子,是一个mianActivity继承ActivityGroup其中有3个ImageView。点击不同的ImageView开启不同的Activity来更新主界面。另外3个Activtiy名字ModuleView1、ModuleView2、ModuleView3.只是继承Activity显示一句话。
http://blog.csdn.net/wangzhe_90228/article/details/7613004#t0