Activity的启动模式总结

做技术,不论简单与否都应总结

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的标记位:

Activity的启动模式总结_第1张图片


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
实例:
Activity的启动模式总结_第2张图片 
 
Activity的启动模式总结_第3张图片 
 
 

使用 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的启动模式总结_第4张图片

这样就完成了批量关闭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);
    }
}


这样就能很简单的关闭所有activity也就是关闭app:





你可能感兴趣的:(Activity的启动模式总结)