Activity启动模式之SingleInstance


  终于到了最后一种启动模式了,指定为singleInstance模式的活动会启用一个新的返回栈来管理这个活动(其实如果singleTask模式指定了不同的taskAffinity,也会启动一个新的返回栈);并且该返回栈中只放入这一个活动。

  其应用场景是这样的:假设程序中有一个活动是允许其它程序调用的,如果想使其它程序和这个程序共享这个活动的实例,使用其它三种启动模式是不行的,因为每个应用程序都有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance模式可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用同一个返回栈,也解决了共享活动实例的问题。

  话不多说,继续贴代码。

FirstActivity:

 1 public class FirstActivity extends Activity {  2     private Button launch_second;  3  @Override  4     protected void onCreate(Bundle savedInstanceState) {  5         super.onCreate(savedInstanceState);  6         requestWindowFeature(Window.FEATURE_NO_TITLE);  //隐藏标题栏
 7  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  8                 WindowManager.LayoutParams.FLAG_FULLSCREEN);    //隐藏状态栏
 9  setContentView(R.layout.activity_first); 10 
11         launch_second = (Button) findViewById(R.id.launch_second); 12         launch_second.setOnClickListener(new View.OnClickListener() { 13  @Override 14             public void onClick(View v) { 15                 Intent intent = new Intent().setClass(FirstActivity.this, SecondActivity.class); 16  startActivity(intent); 17  } 18  }); 19         Log.i("TAG", "FirstActivity is launched; and this stack id is: "+getTaskId()); 20  } 21 
22  @Override 23     protected void onDestroy() { 24         super.onDestroy(); 25         Log.i("TAG", "FirstActivity is Destroyed!"); 26  } 27 }

SecondActivity

 1 public class SecondActivity extends Activity {  2     private Button launch_third;  3  @Override  4     protected void onCreate(Bundle savedInstanceState) {  5         super.onCreate(savedInstanceState);  6  requestWindowFeature(Window.FEATURE_NO_TITLE);  7  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  8  WindowManager.LayoutParams.FLAG_FULLSCREEN);  9  setContentView(R.layout.activity_second); 10 
11         launch_third = (Button) findViewById(R.id.launch_third); 12         launch_third.setOnClickListener(new View.OnClickListener() { 13  @Override 14             public void onClick(View v) { 15                 Intent intent = new Intent().setClass(SecondActivity.this, ThirdActivity.class); 16  startActivity(intent); 17  } 18  }); 19         Log.i("TAG", "SecondActivity is launched; and this stack id is: " + getTaskId()); 20  } 21 
22  @Override 23     protected void onDestroy() { 24         super.onDestroy(); 25         Log.i("TAG", "SecondActivity is destroyed!"); 26  } 27 }

ThirdActivity

 1 public class ThirdActivity extends Activity {  2  @Override  3     protected void onCreate(Bundle savedInstanceState) {  4         super.onCreate(savedInstanceState);  5  requestWindowFeature(Window.FEATURE_NO_TITLE);  6  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  7  WindowManager.LayoutParams.FLAG_FULLSCREEN);  8  setContentView(R.layout.activity_third);  9         Log.i("TAG", "ThirdActivity is launched; and this stack id is: "+getTaskId()); 10  } 11 
12  @Override 13     protected void onDestroy() { 14         super.onDestroy(); 15         Log.i("TAG", "ThirdActivity is destroyed!"); 16  } 17 }

activity_first

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout  3     xmlns:android="http://schemas.android.com/apk/res/android"
 4  android:id="@+id/linearLayout1"
 5  android:layout_width="match_parent"
 6  android:layout_height="match_parent"
 7  android:orientation="vertical">
 8     <Button  9         android:id="@+id/launch_second"
10  android:layout_width="match_parent"
11  android:layout_height="wrap_content"
12  android:text="启动SecondActivity!"/>
13 </LinearLayout>

activity_second

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout  3     xmlns:android="http://schemas.android.com/apk/res/android"
 4  android:id="@+id/linearLayout2"
 5  android:layout_width="match_parent"
 6  android:layout_height="match_parent"
 7  android:orientation="vertical">
 8     <Button  9         android:id="@+id/launch_third"
10  android:layout_width="match_parent"
11  android:layout_height="wrap_content"
12  android:text="启动ThirdActivity!"/>
13 </LinearLayout>

activity_third

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout  3     xmlns:android="http://schemas.android.com/apk/res/android"
 4  android:id="@+id/linearLayout3"
 5  android:layout_width="match_parent"
 6  android:layout_height="match_parent"
 7  android:orientation="vertical">
 8     <TextView  9         android:layout_width="match_parent"
10  android:layout_height="match_parent"
11  android:text="爱情就像影子,如果踩中了,就请带走我的心"
12  android:textSize="24sp"/>
13 </LinearLayout>

  同样的,在ManifestAndroid.java文件中。我们需要对上述三个Activity进行注册,并且将SecondActivity的启动模式设为SingleInstance,其它两个默认的Standard即可。相信你对上述的代码已经不需要注释就能看懂了!

  

   好了,代码完成了,那么就愉快的运行起来吧。首先启动的是FirstActivity,我们可以看到,它所处的栈是18;点击"启动SecondActivity!",此时的SecondActivity启动,但是它处在的返回栈是19;继续点击"启动ThirdActivity!",可以发现该活动又处在18号的返回栈。因此呢,设置为SingleInstance启动模式的活动会单独创建一个返回栈。

 

  然后我们再点击back键,看看其是如何退出程序的。点击第一次back键,显示的是ThirdActivity首先被销毁,其次是FirstActivity,最后才是SecondActivity。如果按照前面的模式来说,ThirdActivity是由SecondActivity启动的,那么销毁了ThirdActivity之后不是应该销毁SecondActivity吗?怎么这里是先销毁FirstActivity,再销毁SecondActivity。

 

  其实因为ThirdActivity处在18号栈,当出栈之后,发现该栈中还有Activity在,于是先将该栈中的Activity全部出栈之后,然后在对另一个栈19进行出栈出理。如果我们只启动FirstActivity和SecondActivity,那么依旧是SecondActivity先出栈,然后再试FirstActivity。

  测试完之后又是对该启动模式画示意图的时刻了,可画出SingleInstance的原理示意图如下所示:

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM