Android Activity

一 Activity简介

Activity是Context的子类

Activity是四大组件之一 用来显示控件和用户交互 

Activity是一个布局容器

Activity如果5s内没有响应 就会导致一个异常 ANR(application not response)

 

二 新建一个Activity

1. 直接或者间接继承Activity

2. AndroidManifest.xml application节点里面配置activity name属性必须配置 其余可选

 

三 意图激活新的Activity

显式意图

用于激活本应用的另一个Activity

startActivity(new Intent(context, OtherActivity.class));

隐式意图

多用于激活其它应用的Activity 可以匹配多个应用

原则: 完全匹配对方暴露的intent-filter(action category data)

// 系统拨号盘
startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:18627777777")));

  

四 意图数据的传递

基本数据类型

// 传递
Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("name", "小白");
intent.putExtra("age", 15);
startActivity(intent);
// 取值
Intent intent = getIntent();
String name = intent.getStringExtra("name");
int age = intent.getIntExtra("age", 0);

对象数据类型

必须让类去实现Parcelable接口或者Serializable接口

推荐使用Parcelable接口 因为消耗资源少 Serializable是Java的序列化接口 在Android里面比较消耗资源

// 传递
Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("user", new User("小白", 15));
startActivity(intent);
// 取值
Intent intent = getIntent();
User user = intent.getParcelableExtra("user");

 

五 打开一个Activity关闭后返回数据

 

六 Activity生命周期

 

七 Activity被系统回收后临时数据的存储

当系统去主动杀死应用程序的时候 是需要对临时数据进行存储的

public class MainActivity extends AppCompatActivity {

    /** 第一种恢复方式 **/
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 只有被系统杀死过 savedInstanceState才有数据
        if (null != savedInstanceState) {
            int page = savedInstanceState.getInt("page");
            Log.i("HUANG", "onCreate page=" + page);
        }
    }

    /** 保存 **/
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // 当系统去主动杀死应用程序的时候 onPause()之后调用
        outState.putInt("page", 100);
    }
    
    /** 第二种恢复方式 **/
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        // 只有被系统杀死过才会在onStart()之后调用
        int page = savedInstanceState.getInt("page");
        Log.i("HUANG", "onRestoreInstanceState page=" + page);
    }

}

 

八 横竖屏切换的生命周期与相关方法

竖屏 -> 横屏

Activity先杀死 再创建

横竖 -> 竖屏

Activity先杀死 再创建

配置横竖屏切换Activity不杀死 只做界面的改变

横竖屏切换的监听

public class MainActivity extends AppCompatActivity {

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 必须配置横竖屏切换Activity不杀死 切换时才会调用
        switch (newConfig.orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                Log.i("HUANG", "横屏");
                break;

            case Configuration.ORIENTATION_PORTRAIT:
                Log.i("HUANG", "竖屏");
                break;
        }
    }

}

 我开发中屏幕方向的处理

 

九 任务栈

任务栈: 用来记录用户的操作行为

栈: 先进后出

进栈(压栈): startActivity()

出栈(弹栈): finish()和用户按下后退键

当启动一个应用程序 系统就会分配一个任务栈给应用

 

十 启动模式

singleInstance 单实例

这样的Activity会单独存放在一个任务栈里面 并且这样的实例只会有一份引用

如果主任务栈里面已存在同样的Activity 那么不会新建Activity 而会复用已存在的Activity 复用Activity就会调用Activity里面onNewIntent()方法

举个例子

AActivity -> BActivity -> BActivity  其中BActivity的启动模式是singleInstance

第二个BActivity会复用第一个BActivity

此时栈的情况 AActivity BActivity

再举个例子

AActivity -> BActivity -> BActivity -> CActivity  其中BActivity的启动模式是singleInstance

第二个BActivity会复用第一个BActivity

此时栈的情况 BActivity AActivity CActivity  很奇怪是吗 我也很奇怪 在三部真机上测试都是这个样子

最后举个例子

AActivity -> BActivity -> AActivity -> BActivity -> CActivity  其中BActivity的启动模式是singleInstance

第二个BActivity会复用第一个BActivity

此时栈的情况 BActivity AActivity AActivity CActivity  这个也很奇怪

singleTask 单任务栈

如果任务栈里面已存在同样的Activity 那么就会销毁该Activity上面所有的Activity 再复用该Activity 复用Activity就会调用Activity里面onNewIntent()方法

singleTop 独占顶端

如果栈顶已存在同样的Activity 那么不会新建Activity 而会复用栈顶的Activity 复用Activity就会调用Activity里面onNewIntent()方法

如果不在栈顶 会新建Activity

standard 标准(默认)

启动一个Activity 该Activity的实例引用就会放置在任务栈 每次启动都会创建一个新的实例

 

十一 intent.setFlags()方法中的参数值含义

Intent.FLAG_ACTIVITY_NO_HISTORY

通过Intent跳转到Activity 如果这个Intent添加FLAG_ACTIVITY_NO_HISTORY标志

这样的Activity会单独存放在一个任务栈里面 并且这样的实例只会有一份引用

如果主任务栈里面已存在同样的Activity 那么就会销毁掉旧Activity 再新建Activity

举个例子

AActivity -> BActivity -> BActivity  其中跳转BActivity的Intent添加了FLAG_ACTIVITY_NO_HISTORY标志

第一个BActivity会被销毁 第二个BActivity是新建的

此时栈的情况 AActivity BActivity

再举个例子

AActivity -> BActivity -> BActivity -> CActivity  其中跳转BActivity的Intent添加了FLAG_ACTIVITY_NO_HISTORY标志

第一个BActivity会被销毁 第二个BActivity是新建的

此时栈的情况 AActivity CActivity

最后举个例子

AActivity -> BActivity -> AActivity -> BActivity -> CActivity  其中跳转BActivity的Intent添加了FLAG_ACTIVITY_NO_HISTORY标志

第一个BActivity会被销毁 第二个BActivity是新建的

此时栈的情况 AActivity AActivity CActivity

Intent.FLAG_ACTIVITY_CLEAR_TOP

通过Intent跳转到Activity 如果这个Intent添加FLAG_ACTIVITY_CLEAR_TOP标志

如果任务栈里面已存在同样的Activity 那么就会销毁掉旧Activity和它上面所有的Activity 再新建Activity

Intent.FLAG_ACTIVITY_SINGLE_TOP

通过Intent跳转到Activity 如果这个Intent添加FLAG_ACTIVITY_SINGLE_TOP标志

如果栈顶已存在同样的Activity 那么不会新建Activity 而会复用栈顶的Activity 复用Activity就会调用Activity里面onNewIntent()方法

如果不在栈顶 会新建Activity

Intent.FLAG_ACTIVITY_NEW_TASK

通过Intent跳转到Activity 如果这个Intent添加FLAG_ACTIVITY_NEW_TASK标志

一般情况: 启动一个Activity 该Activity的实例引用就会放置在任务栈 每次启动都会创建一个新的实例

特殊情况: 如果试图从Activity的外部非正常途径启动一个Activity 比如从一个BroadcastReceiver中启动一个Activity 则Intent必须要添加FLAG_ACTIVITY_NEW_TASK标记 否则报错

 

十二 onNewIntent()方法调用顺序

如果不在栈顶

onNewIntent() -> onStart() -> onResume()

如果已在栈顶

onNewIntent() -> onResume()

 

十三 注意

一般来说 不建议目标Activity的intent.setFlags()的同时该Activity也设置启动模式

尤其是Intent.FLAG_ACTIVITY_NO_HISTORY Intent.FLAG_ACTIVITY_CLEAR_TOP Intent.FLAG_ACTIVITY_SINGLE_TOP 和 singleInstance singleTask singleTop 一起混用

会导致任务栈很奇怪 Activity里面的方法调用也会很奇怪

 

十四 一个变态的方法

public class MainActivity extends AppCompatActivity {

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // 把当前Activity放置在后台
            moveTaskToBack(true);
        }
        return true; //告诉系统交由我来处理
    }

}

 

posted @ 2018-08-30 16:15  梦三  阅读(2513)  评论(0编辑  收藏  举报