做技术,不论简单与否都应总结
activity有四种常见的启动模式:standard,singleTopc,singleTask和singleInstance
standard:
标准模式,这也是系统的默认启动模式,每次启动一个activity都会重新创建一个新的实例,不管这个实例是否存在,被创建的实例的生命周期与activity的基本生命周期一致,也就是onCreate,onStart,onResume都会被调用,这是一种典型的多实例,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈中,比如activity a启动了activity b(b是标准模式的时候),那么b就会进入到a所在的栈中,注意:当传递的context是appLication时,standard模式启动将会报错:
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?standard模式启动的activity默认会进入activity所属的任务栈中,但是由于非activity类型的context(Application等)并没有在指定任务栈,所以必上 FLAG_ACTIVITY_NEW_TASK标记位,这样在启动的时候就会为他创建一个新的任务栈,这个时候等同于singleTask启动模式
singleTop
栈顶复用模式,在这中模式下,如果新的activity已经位于任务栈的栈顶,那么此activity不会被重新创建,同时它的onNewIntent方法会被回掉,通过此方法我们可以从intent中获取响应的数据传递,这种模式启动的activity的onCreate onstart将不会重新执行,如果启动的activity已经位于栈顶 将不会重新创建新的实例了,a->b 再次启动b 栈里面的实例依旧只有ab,如果是standard模式启动 将会是abb.
singleTask:
栈内复用模式,这是一种单实例模式,这种情况下,只要activity在一个栈中存在,多次启动activity将不会创建实例,和singleTop一样,OnNewIntent将会调用多次,简单的说,如果栈中存在a activity 这种模式下再次启动a ,a 将不会执行onCreate和onStart方法,而是执行onNewIntent方法,如果栈中不存在a ctivity的实例,将会创建一个a activity,oncreate-->onstart等
singleInstance:
加强版singleTask,这种启动模式是单实例,独占任务栈中,例如:以这种模式启动的activity a,系统将会为这个activity创建一个独立的栈 独立的实例
activity的标记位:
flag 非常多,这里简单介绍几个:
public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
singleTask 启动模式
public static final int FLAG_ACTIVITY_SINGLE_TOP = 0x20000000;
等同于singleTop
public static final int FLAG_ACTIVITY_CLEAR_TOP = 0x04000000;
清除activity之上的所有activity 如 a->b->a b将消失
例子:推送通知:如JPush 自定义消息:
网上大部分的教程是要结合public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;这是误人子弟的,完全不需要你只需添加默认的catorgory Intent.CATEGORY_DEFAULT实例:
使用 Intent.CATEGORY_DEFAULT结合广播的context 不需要NewTask标志 便可以通知点击打开目标activity,这里创建了一个intent数组是为了 当应用关闭的时候 打开自定义的通知到对应activity 点击返回键可以回到主页面,当然你不嫌麻烦 可以自定义栈,给用户一级级导航
又如怎么批量关闭activity:
mainActivity->a activity->b activity-> c Activity
这时需要一步关闭abc:
可能最蛮的方法 建立一个stack 在baseActivity onCreate中添加进去,onDestory中移除,然后获取到ab 然后关这两个页面
其实还有第2种方式 需要你深刻理解启动模式:利用singleTop 原理:在结合clearTop 为mainActivity添加intent启动标志,在c activity关闭的地方启动这个intent即可 关闭abc 而又不创建mainactivity:
部分代码:
package com.xuan.test; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; public class MainActivity extends AppCompatActivity { public static void launch(Context context) { Intent intent = new Intent(context, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onOpen(View v) { ActivityA.launch(this); } }
package com.xuan.test; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-03 16:20 */ public class ActivityC extends Activity { public static void launch(Context context) { Intent intent = new Intent(context, ActivityC.class); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_c); } @Override public void onBackPressed() { super.onBackPressed(); MainActivity.launch(this); } }
package com.xuan.test; import android.app.Activity; import android.app.Application; import android.os.Bundle; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-03 16:18 */ public class BaseApplication extends Application { @Override public void onCreate() { super.onCreate(); this.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { LogUtils.d("----------onActivityCreated:"+activity); } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { LogUtils.d("----------onActivityDestroyed:"+activity); } }); } }
</pre><pre code_snippet_id="1668238" snippet_file_name="blog_20160503_6_7193189" name="code" class="java">运行效果:
<img src="http://img.blog.csdn.net/20160503165754770?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<img src="http://img.blog.csdn.net/20160503165808286?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<img src="http://img.blog.csdn.net/20160503165832040?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<img src="http://img.blog.csdn.net/20160503165855301?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
这样就完成了批量关闭activity的操作:
升华:在非launchActivity(或者说非mainActivity)中 关闭app,退出程序
package com.xuan.test; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; /** * @author xuanyouwu * @email [email protected] * @time 2016-05-03 16:20 */ public class ActivityC extends Activity { public static void launch(Context context) { Intent intent = new Intent(context, ActivityC.class); context.startActivity(intent); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_c); } //关闭应用 public void onCloseApp(View v) { MainActivity.launchClose(this); } }
package com.xuan.test; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; public class MainActivity extends AppCompatActivity { private static final String KEY_CLOSE = "close"; public static void launchClose(Context context) { Intent intent = new Intent(context, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.putExtra(KEY_CLOSE, true); context.startActivity(intent); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent.getBooleanExtra(KEY_CLOSE, false)) { finish();//关闭当前 } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onOpen(View v) { ActivityA.launch(this); } }