Activity4种启动模式

来源:互联网 发布:python爬虫 去重 编辑:程序博客网 时间:2024/06/06 23:50

什么是启动模式:

启动模式简单地说就是Activity启动时的策略,在AndroidManifest.xml中的<Activity>标签的android:launchMode属性设置;
<activity android:name="ActB" android:launchMode ="singleTask"></activity>
启动模式有4种,分别为standard、singleTop、singleTask、singleInstance;
大家都知道一个activity启动之后都是存放在堆栈中的,也就是一个task。而这4中模式在设置之后再task中的使用是不一样的:

1.standard:

也就是默认模式,不需要配置launchMode,每次激活Activity时(startActivity),都创建Activity实例,并放入任务栈;

2.singletop:

如果某个Activity自己激活自己,即任务栈栈顶就是该Activity,则不需要创建,其余情况都要创建Activity实例;
并且如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建新的实例。

singleTop和standard模式,都会将intent发送新的实例(后两种模式不发送到新的实例,如果已经有了的话)。不 过,singleTop要求如果创建intent的时候栈顶已经有要创建的Activity的实例,则将intent发送给该实例,而不发送给新的实例。

只需将launchMode改为singleTop,就能看到区别。

运行的时候会发现,按多少遍按钮,都是相同的ActiA实例,因为该实例在栈顶,因此不会创建新的实例。如果回退,将退出应用。


3.singleTask

如果要激活的那个Activity在任务栈中存在该实例,则不需要创建,只需要把此Activity放入栈顶,并把该Activity以上的Activity实例都移出栈(pop);
 如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。

其中如果b界面被声明为SingleTask。

先运行taskB,显示a界面,由a界面调用b界面,这时b界面的taskid与a界面的taskid是一致的,说明b界面与a界面在同一个task中;由b界面调用c界面时,c界面的taskid与a和b界面的taskid一致,说明这三个界面是在同一个task中。当前显示的是c界面,此时按Home键回到桌面,运行taskA的界面调用taskB的b界面,这时b界面显示出来,它的taskid没有变,还是之前的taskid,只不过之前显示的是c界面,这时c界面已经不知所踪,这时再按back键,则回到了a界面,然后是taskA的界面。

这说明,SingleTask所标注的Activity在被自身的app调用时,是不新建task的,同时,如果系统中存在了这个SingleTask界面的实例时,会将其所在的task切换到前台,并把SingleTask界面之后开启的其他界面全部关闭(有待考证是否关闭)。


另外有一种情况,例如:a界面被调用,这时按Home键返回到桌面,启动taskA,并调用b界面,这时b界面的taskid与a界面的一致,说明b界面与a界面同属于一个task。如果直接运行taskA调用b界面,b的taskid与taskA的界面的taskid不同,说明在新task中实例化了b界面,由b界面调用c界面,c界面的taskid与b界面一致,说明b与c同属于一个task。


4.singleInstance

如果应用1的任务栈中创建了MainActivity实例,如果应用2也要激活MainActivity,则不需要创建,两应用共享该Activity实例;
一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。

将b界面声明为SingleInstance。

先运行taskB,显示a界面,由a界面调用b界面,这时b界面的taskid与a界面的taskid不同,说明b界面是在新task中生成的实例;由b界面调用c界面,c界面的taskid与a界面的taskid相同,说明a、c界面同属于一个task。

由此可以看出SingleTask与SingleInstance是有本质区别的,而不是像网上说的那样,都是task的root activity,这是有错误的。


测试代码:

在界面中打印出对象的toString值可以根据hash code识别是否创建新Activity实例

  1. import android.app.Activity;  
  2. import android.content.Intent;  
  3. import android.os.Bundle;  
  4. import android.view.View;  
  5. import android.view.View.OnClickListener;  
  6. import android.widget.Button;  
  7. import android.widget.TextView;  
  8.   
  9. public class MainActivity extends Activity {  
  10.     private Button standardButton;  
  11.     private TextView showView;  
  12.     private OnClickListener listener = new OnClickListener(){  
  13.         @Override  
  14.         public void onClick(View v) {  
  15.             Intent intent = new Intent(MainActivity.this,MainActivity.class);  
  16.             startActivity(intent);  
  17.         }  
  18.     };  
  19.     @Override  
  20.     public void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.main);  
  23.         showView = (TextView)this.findViewById(R.id.showview);  
  24.         standardButton = (Button)this.findViewById(R.id.standard);  
  25.         standardButton.setOnClickListener(listener);  
  26.         showView.setText(this.toString());  
  27.     }  
  28. }  

0 0
原创粉丝点击