Android开发学习一:界面组件Activity

《Android开发实战 从学习到产品》李瑞琪编著 学习笔记。

Android最常见四组件:Activity、Service、ContentProvider、BroadcastReceiver。
Activity:Android开发最重要的组件,Android应用程序界面,凡是在应用中能看到的东西都是放在Activity中的。

一、Activity生命周期

1、概述

Activityt由Activity栈进行管理,新Activity将被加到Activity栈顶,之前的Activity将位于该新Activity底部。Activity的四种状态:

  • 当Activity位于栈顶,处于屏幕最前方,运行状态
  • 当Activity失去焦点但任对用户可见(栈顶Activity透明或未铺满屏幕等),暂停状态
  • 当Activity完全被其他Activity遮挡时,Activity对用户不可见,处于停止状态
  • 当Activity被人为或系统原因销毁,处于销毁状态

开发过程中写的Activity一般都继承Activity类并重写相应的回调方法,Activity生命周期流程图如下:

Activity生命周期流程图

由图知Activity生命周期的7个事件:

  • onCreate():Activity第一次被创建时调用,可在此方法中绑定数据或创建其他视图控件。
  • onStart():当Activity变为用户可见之前调用。
  • onResume():当Activity可以与用户交互之前调用,即Activity对象到达Activity栈顶即将成为前台进程时调用。
  • onPause():当系统调用其他Activity对象时调用(注:新Activity对象必须等待该方法执行完毕再显示出来,多数情况下onPause()方法要关闭onResume()中打开的方法)。
  • onStop():当Activity不可视时调用。
  • onDestroy():当销毁Activity对象时调用。
  • onRestart():当处于onStop()状态的Activity又变为可视时调用。

除这些方法外,还有3个关键的周期循环:

  • Activity的完整周期 从第一次调用onCreate(Bundle)设置所有“全局"状态及完成初始化开始,直至调用onDestroy()释放所有系统资源。
  • Activity的可视生命周期 自onStart()调用开始至onStop()调用为止,用户屏幕可见此Activity。
  • Activity前台生命周期 自onResume()调用起,至onPause()调用为止,该期间Activity位于前台最上面并与用户进行交互。

2、实例:

package com.example.day0907_lifeactivity;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    protected void onDestroy(){
        super.onDestroy();
        Log.i("LifeActivity","onDestroy");
    }

    protected void onPause(){
        super.onPause();
        Log.i("LifeActivity","onPause");
    }

    protected void onResume(){
        super.onResume();
        Log.i("LifeActivity","onResume");
    }

    protected void onRestart(){
        super.onRestart();
        Log.i("LifeActivity","onRestart");
    }

    protected void onStart(){
        super.onStart();
        Log.i("LifeActivity","onStart");
    }

    protected void onStop(){
        super.onStop();
        Log.i("LifeActivity","onStop");
    }


    /*onWindowFocusChanged()方法:在Activity窗口获得或失去焦点时被调动
    (在onResume()之后或onPause()之后调用)*/
    public void onWindowFocusChanged(boolean hasFocus){
        super.onWindowFocusChanged(hasFocus);
        Log.i("LifeActivity","onWindowFocusChanged");
    }

    /*在Activity被覆盖或退居后台之后,系统资源不足将其杀死时;用户改变屏幕方向;
    当前Activity跳转到其他Activity或按Home键回到主屏,自身退居后台时 被调用
    调用在onPause()之前*/
    protected void onSaveInstanceState(Bundle outState){
        Log.i("LifeActivity","onSaveInstanceState");
        super.onSaveInstanceState(outState);
    }

    /*当Activity被覆盖或局后台,系统资源不足将其杀死,然后用户又回到Activity时;
    * 用户改变屏幕方向重建过程中 被调用。调用在onStart()之后*/
    protected void onRestoreInstanceState(Bundle savedInstanceState){
        Log.i("LifeActivity","onRestoreInstanceState");
        super.onRestoreInstanceState(savedInstanceState);
    }
}

点击Android Studio左下角logcat查看日志(设置查看日志level为info,关键字为LifeActivity):

(1).初次运行Activity时:系统调用onCreate和onStart后调用onResume,Activity进入运行状态。
在这里插入图片描述
(2).在模拟机上按Home键回主屏幕或跳转Activity:退居后台后,Activity窗口焦点发生变化,故先调用onWindowFocusChanged方法,再依次调用各个方法。
在这里插入图片描述

(3).重回原Activity:先调用onRestart方法使用户可见,再调用…
在这里插入图片描述
(4). 退出程序:最后调用的onDestroy方法销毁Activity。
在这里插入图片描述(5).横屏:期间调用了一次onDestroy方法销毁Activity及onStart方法打开Activity,故调用了一次onSaveInstanceState方法保存临时数据,和一次onRestoreInstanceState方法恢复数据。
在这里插入图片描述

二、Intent与Activity之间的跳转

Intent:完成组件之间的通信。(此处仅介绍完成Activity间的通信),Intent应用场合主要三种:
①.启动一个Activity。
②.启动一个Service。
③.启动一个BroadCast。

当使用一个Intent进行组件通信时,需要先实例化一个Intent对象,此时需要设置Intent属性

Action(要执行的动作):如ACTION_CALL表示拨打电话、ACTION_EDIT表示调用编辑器、ACTION_SYNC表示同步数据…
Data(执行动作所操作的数据):在Intent中使用指向数据的URI来表示。
Type(显示指定Intent数据类型):不同动作URI数据类型不同。
Category(执行动作的附加信息)
Component(指定Intent目标组件的类名称):通常Android根据Intent包含的上述等属性进行查找,若设置该属性则查找过程不需执行。
Extras(其他所有附加信息的集合):为组件提供扩展信息。

另外,使用Intent时根据是否明确指定Intent对象的接收者,分显示(即在构造Intent对象时就指定接受者)和隐式(在构造Intent对象时不指定接受者,Android需对其进行解析:查找AndroidManifest.xml文件中所有IntentFilter及其定义的Intent,找到最匹配的Intent【判断Intent的Action、Type、Category找到最匹配的Intent】)的Intent。

1.显式意图

要求必须知道被激活组件的包和class
在该项目内创建新Empty Activity(new->)取名为SecondaryActivity,在activity_secondary.xml内放置一个TextView控件编辑其text内容为“第二个Activity!”以作标记。
在activity_main.xml内放置一个Button按钮,使得单击跳转到SecondaryActivity界面,并在MainActivity.java内代码实现跳转功能

package com.example.day0907_lifeactivity;

import android.content.Intent;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.os.Bundle;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //R类:将Android的资源文件存储为键值对的一个类(系统自建,勿改),findViewById获得View控件对象的方法
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            public void onClick(android.view.View view){
                //跳转到第二个Activity
                gotoSecondaryActivity();
            }
        });
    }

    private void gotoSecondaryActivity(){
        Intent toSecondary = new Intent();      //创建一个意图
        toSecondary.setClass(this,SecondaryActivity.class);//指定跳转SecondaryActivity
        toSecondary.putExtra("name","Ricky");    //设置传递字符串
        toSecondary.putExtra("age",25);         //设置传递int类型内容
        //上述两行代码可改为如下代码  android中使用Bundle来共享变量
//        Bundle bundle = new Bundle();
//        bundle.putString("name","Ricky");
//        bundle.putInt("age",25);
//        toSecondary.putExtras(bundle);
        startActivity(toSecondary);
    }


}

SecondaryActivity.java内代码接受数据

package com.example.day0907_lifeactivity;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class SecondaryActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_secondary);

        Intent intent_accept = getIntent();     //创建一个接收意图
        Bundle bundle = intent_accept.getExtras();      //创建一个Bundle对象用于接收Intent数据
        String name = bundle.getString("name");     //获取Intent的内容name
        int age = bundle.getInt("age");     //获取Intent的内容age
        Log.i("SencodaryActivity", name + " " + age);
    }
}

程序效果图
在这里插入图片描述

2.隐式意图

*可以不知道被激活组件的包和class,只通过指定action就进行跳转,如果一个Activity想要启动另一个应用的Activity就只能使用隐式意图

3.带回调方法的意图

有时需定义在MainActivity中的某一控件启动SecondaryActivity并当SecondaryAActivity结束时返回给MainActivity一个执行结果。

4.跳转中对象参数的传递

在Android开发中,有时多个Activity之间需要进行对象的传递,使用Intent也可以完成这一功能。
MainActivity.java 内的gotoSecondaryActivity方法改为:

private void gotoSecondaryActivity(){
        Intent toSecondary = new Intent();      //创建一个意图
        toSecondary.setClass(this,SecondaryActivity.class);//指定跳转SecondaryActivity
        Bundle bundle = new Bundle();
        User user = new User();
        user.setAge(25);
        user.setName("Ricky");
        bundle.putSerializable("user",user);
        toSecondary.putExtras(bundle);
        startActivity(toSecondary);
        //startActivityForResult(toSecondary,RequestCode);//启动带请求码意图
    }

SecondaryActivity.java 内的onCreate方法改为

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_secondary);

        Intent intent = getIntent();    //创建接收意图
        Bundle bundle = intent.getExtras();
        User user = (User)bundle.get("user");   //???
        Log.i("SecodaryActivity", user.getName()+" "+user.getAge());
}

则单击第一个Activity中按钮,日志显示为:
在这里插入图片描述

三、Activity启动模式

Task:以栈来管理Activity。
Activity四种启动模式:standard、singleTop、singleTask、singleInstance。

  1. standard:默认启动模式,若不指定launchMode属性,就会自动使用这种启动模式。
    声明为这种启动模式的Activity可以被实例化多次,一个任务当中也可以包含多个Activity的实例。
  2. singleTop:在AndroidManifest.xml中配置的android:launchMode的属性为singleTop。singleTop模式,若要启动的Activity在当前任务中已存在,且处于栈顶的位置,则系统不会再创建一个该Activity实例,而是调用栈顶Activity的onNewIntent()方法
      例:若Task返回栈中有4个Activity:A-B-C-D,D位于栈顶,A位于栈底,若要求再启动仪一次D,若D启动模式为standard则系统再创建一个D实例,此栈内元素为A-B-C-D-D;若D启动模式为singleTop,系统直接调用D的onNewIntent()方法,此时栈内元素任为A-B-C-D。
  3. singleTask该启动模式表示,系统会创建一个新任务,并将启动的Activity放入这个新任务的底部,但是若该任务中已经存在该Activity的实例,不会新创建该Activity的实例而是调用该Activity的onNewIntent()方法,故该启动模式下Activity在同一个任务中只会存在一个实例。
      singleTask模式默认情况下只有启动其他应用程序的Activity才会创建一个新任务,启动自己程序中的Activity还是会使用相同的任务。
    在这里插入图片描述
  4. singleInstance:singleInstance模式启动Activity会创建一个新的Task,这种Activity所在的Task中始终只会有一个Activity。通过这个Activity打开其他Activity会被放入别的任务当中。
      standard模式是Android默认启动模式,可能造成多次启动问题,如用户手误多次点击一个跳转到新Activity按钮,系统会创建多个新Activity,而用户只需一个。singleTop模式可避免这个问题,该模式在启动Activity时,如果发现该返回栈中的栈顶已是该Activity时,就认为可以直接使用它而不会创建新的Activity实例。若要启动的Activity不在栈顶,还是会创建该Activity的实例。将启动模式设置为singleTask,每次启动Activity时系统首先在返回栈中检查是否有该Activity的实例,若有就直接使用该Activity的实例,并将这个Activity上的所有活动统统出栈,若没有就会创建一个新的Activity。而singleInstance模式的活动将会启用一个新的返回栈来管理这个活动,解决了多个应用访问一个Activity时的共享问题。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章