Android程序活动单元Activity

Android程序活动单元Activity

Android中的四大组件分别是Activity、Service、ContentProvider和BroadcastReceiver,其中Activity是一个负责与用户交互的组件,每个Android应用都会用Activity来显示界面以及处理界面上一些控件的事件

4.1 Activity的生命周期

4.1.1 生命周期状态

Activity的生命周期是指Activity从创建到销毁的整个过程,这个过程大致可分为五种状态,分别是启动状态,运行状态,暂停状态,停止状态和销毁状态

  • 启动状态:Activity启动状态很短暂,一般在Activity启动之后便会进入这个状态
  • 运行状态:Activity在此状态时处于界面最前端,是可见,有焦点,可以与用户交互的,当Activity处于运行状态时,Android会尽可能的保持这种状态,即使存在内存不足的情况,Android也会先销毁栈底的Activity来确保当前Activity正常运行
  • 暂停状态:在某些情况下,Activity对于用户来说仍然可见,但它无法获取焦点,用户对它操作没有响应,此时即是暂停状态
  • 停止状态:当Activity完全不可见时,它就处于停止状态,如果系统内存不足,这种状态下的Activity很容易被销毁
  • 销毁状态:Activity处于销毁状态时将被清理出内存

注意:启动状态和销毁状态都是过度状态,Activity不会在这两个状态停留

4.1.2 生命周期方法

Activity的生命周期包括创建、可见、获取焦点、失去焦点、不可见、重新可见、销毁等环节,针对每个环节Activity都定义了相关的回调方法:

在这里插入图片描述

注意:横竖屏切换时的生命周期

现实生活中,使用手机时会根据不同情况进行横竖屏切换。当手机横竖屏切换时,会根据AndroidManifest.xml文件中Activity的configChanges属性值的不同而调用相应的生命周期方法

当没有设置configChanges属性的值时,Activity生命周期会依次调用onCreate(). onStart(),onResume()方法

当由竖屏切换横屏时,调用的方法依次是onPause()、onStop()、 onDestory()、onCreate()、onStart()和onResume()的方法

在进行横竖屏切换时,首先会调用onDestory()方法销毁Activity,之后调用onCreate()方法重建Activity,这种模式在实际开发中会对程序有一定的影响,例如,用户在界面上输入信息时,进行了横坚屏切换,则用户输入的信息会被清除

如果不希望在横竖屏切换时Activity被销毁重建,可以通过configChanges属性进行设置,示例代码如下:

<activity android :name=" MainActivity"
android:configChanges-“orientationIkeyboardHidden”>

当configChanges属性设置完成之后,打开程序时同祥会调用onCreate()。onStart()、 onResume()方法,但是当进行横竖屏切换时不会再执行其他的生命周期方法。
如果希望某一个界面一直处于竖屏或者横屏状态,不随手机的晃动而改变,可以在清单文件中通过设置Activity的screenOrientation属性完成,示例代码如下:

竖屏: android:screenOrientation=“portrait”
横屏: android: screenOrientation=“landscape”

4.2 Activity的创建、配置、开启和关闭

4.2.1 创建Activity

在这里插入图片描述

4.2.2 配置Activity

异常信息:“无法找到…类”,此时需要在AndroidManidest.xml中声明该Activity

<activity android:name="com.itcast.CustomView.Main2Activity"></activity>

如果Activity所在的包与AndroidManifest.xml文件的标签中通过package属性指定的包名-致,则android:name属性的值可以 直接设置为“ .Activity名称”

<activity android:name=".MainActivity">
4.2.3 开启和关闭Activity
  • 启动Activity

创建完Activity后,可以通过startActivity()方法开启创建的Activity

public void startActivity(Intent intent);

参数intent是Android应用中各组件之间通信的桥梁,一个Activity通过Intent来表达自己的意图,在创建Intent对象时,需要指定想要启动的Activity

在MainActivity的onCreate()方法中启动SecondActivity:

Intent intent = new Intent(MainActivity.this,SeconfActivity.class);
  • 关闭Activity

关闭Activity可以调用其finish()方法

4.3 Intent与IntentFilter

在Android系统中,一般应用程序是由多个核心组件构成的。如果用户需要从一个Activity切换到另一个Activity, 则必须使用Intent来进行切换。 实际上,Activity、 Service和BroadcastReceiver这3种核心组件都需要使用Intent进行操作,Intent用于相同或者不同应用程序组件间的绑定

4.3.1 Intent

Intent被称为意图,是程序各组件之间进行交互的一种重要方式,其不仅可以指定当前组件要执行的动作,还可以在不同组件之间进行数据传递,一般用于启动Activity、Service以及发送广播等

根据开启目标组件的方式不同,Intent被分为两种类型:

  • 显示intent

指直接指定目标组件,例如跳转到指定Activity:

Intent intent = new Intent(this,SecondActivity.class);
startActivity(intent);

注意:第一第二个参数分别指当前和目标Activity

  • 隐式intent

不会明确指出需要激活的目标组件,它被广泛用在不同应用程序之间消息传递,Android系统会使用IntentFilter匹配相应的组件,组件属性:

​ action:表示Intent对象要完成的动作

​ data:表示Intent对象中传递的数据

​ category:表示为action添加的额外信息

在MyWorld程序的MainActivity中打开Project2程序中的SecondActivity,SecondActivity的action为“cn.itcast.START_ACTIVITY”:

(1)在MyWorld程序的清单文件AndroidManifest.xml中配置SecondActivity的action为“cn.itcast.START_ACTIVITY”

<activity android:name="com.itcast.CustomView.Main2Activity">
    <intent-filter>
        <action android:name="cn.itcast.START_ACTIVITY"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

(2)在MyWorld程序的MainActivity中开启SecondActivity的实例代码:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button bt = (Button)findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setAction("cn.itcast.START_ACTIVITY");
                startActivity(intent);
            }
        });
    }
}

注意:在使用隐式Intent开启Activity时,系统会默认为该Intent添加“android.intent.category.DEFAULT"的category,因此为了被开启的Activity能够接收隐式Intent,必须在AndroidManifest.xml文件的Activity标签下的中,为被开启的Activity指定catrgory为"android.intent.category.DEFAULT"

4.3.2 IntentFilter

当发送一个隐式Intent后,Android系统会将它与程序中的每一个组件的过滤器进行匹配,匹配属性有action、 data、 category, 需要这三个属性都匹配成功才能唤起相应的组件

  1. action属性匹配规则

action属性用来指定Intent对象的动作,在清单文件中设置action属性的示例代码如下:

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

上述代码中,标签中间可以罗列多个action属性, 但是当使用隐式Intent激活组件时,只要Intent携带的action与其中一个标签中action的声明相同,action属性就匹配成功

需要注意的是,在清单文件中为Activity添加标签时,必须添加action属性,否则隐式Intent无法开启该Activity

  1. data属性匹配规则

data属性用来指定数据的URI或者数据MIME类型,它的值通常与Intent的action属性有关联,在清单文件中设置data属性的示例代码如下:

<data android:mimeType="..." android:scheme="..."/>

标签中 间可以罗列多个data属性,每个data属性可以指定数据的MIME类型和URI(详见第7章)。其中,MIME类型可以表示image/ipeg. video/* 等媒体类型

隐式Intent携带的data数据只要与IntentFilter中的任意一个data声明相同,data 属性就匹配成功

  1. category属性匹配规则

category属性用于为action添加额外信息,- -个IntentFilter可以不声明category属性,也可以声明多个category属性

<category android:name="android.intent.category.LAUNCHER" />

隐式Intent中声明的category必须全部能够与某一 个IntentFilter中的category匹配才算匹配成功

注意:IntentFilter中罗列的category属性数量必须大于或者等于隐式Intent携带的category属性数量时,category属性才 能匹配成功

如果一个隐式Intent没有设置category属性,那么他可以通过任何一个IntentFilter (过滤器)的category匹配

4.4 Activity之间的跳转

一个Android程序通常会包括多个Activity,这些Activity之间可以相互跳转并传递数据

4.4.1 在Activity之间数据传递

Android提供的Intent可以在界面跳转时传递数据,使用Intent传递数据有两种方式:

  1. 使用Intent的putExtra()方法传递数据

由于Activity之间需要传递不同类型的数据,因此Android系统提供了多个重载的putExtra()方法,方法包括两个参数name表示数据名称,value表示数据信息

提供putExtra()方法将数据存储在Intent对象,在通过getXxxExtra()方法获取数据getXxxExtra()同样有两个参数

MainActivity.class

Intent intent = new Intent();
//设置跳转到的Activity
intent.setClass(MainActivity.this,SeondActivity.class);
intent.putExtra("username",123);
startActivity(intent);

SecondActivity.class

//这里的intent是上一个Activity启动的Intent
Intent intent = getIntent();
int username = getIntExtra("username");
  1. 使用Bundle类传递数据

Bundle类与Map接口类似,都是通过键值对的形式存储数据,首先使用Bundle对象保存数据,接着通过putExtra()将这些方法封装到Intent对象中,然后传递到SecondActivity

MainActivity.class

Intent intent = new Intent();
//设置跳转到的Activity
intent.setClass(this,SecondActivity.class);
//创建Bundle对象
Bundle bundle = new Bundle();
//存入数据
bundle.putString("password",666);
//将Bundle对象封装到Intent对象中
intent.putExtras(bundle);
startActivity(intent);

SecondActivity.class

//获取Bundle对象
Bundle bundle = getIntent().getExtras();
String password = bundle.getInt("password");
4.4.2 Activity之间的数据回传

当我们从MainActivity界面跳转到SecondActivity界面时,在SecondActivity界面 上进行一些操作,当关闭SecondActivity界面时, 想要从该界面返回一些数据到MainActivity界面,此时,Android系统为我们提供了一些方法用于Activity之间数据的回传

  • startActivityForResult()方法
startActivityForResult(Intent intent,int requestCode);

该方法用于开启一个Activity,当开启的Activity销毁时,希望从中返回数据,第一个参数intent表示意图,第二个参数表示请求码,用于标识请求的来源

  • setResult()方法
setResult(int resultCode,Intent intent);

该方法用于携带数据进行回访,第一个参数表示返回码,第二个参数表示返回的数据来源于哪个Activity

  • onActivityResult()方法
onActivityResult(int requestCode,int responseCode,Intent data);

该方法用于接收回传的数据,并根据传递的参数requestCode、responseCode来识别数据来源

典例:在MainActivity中点击button1控件跳转到SecondActivity

在MainActivity中点击按钮跳转到SecondActivity

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button bt = (Button)findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, SecondActivity.class);
                startActivityForResult(intent,1);
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==1 && resultCode==2){
            String acquireData = data.getStringExtra("data");
            Toast.makeText(MainActivity.this,acquireData,Toast.LENGTH_SHORT).show();
        }
    }
}

注意:由于MainActivity中调用startActivityForResult()方法启动SecondActivity,在SecongdActivty程序销毁后回调MainActivity中的onActivityResult()方法来接收回传大数据,因此需要在MIanActivity中重写onActivityResult方法

在SecondActivity中点击按钮回传数据

public class SecondActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Button bt1 = (Button)findViewById(R.id.bt);
        bt1.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.putExtra("data","Hello Android!");
                setResult(2,intent);
                finish();
            }
        });
    }
}

在这里插入图片描述

4.5 Activity的任务栈和启动模式

4.5.1 Android中的任务栈

Android的任务栈是一种用来存放Activity实例的容器。任务栈最大的特点就是先进后出,其主要有两个基本操作,分别是压栈和出栈。通常Android应用都有一个任务栈,每打开一个Activity时,该Activity就 会被压入任务栈。每销毁一个Activity时,该Activity就 会被弹出任务栈

用户操作的Activity永远都是栈顶的Activity

4.5.2 Activity的启动模式

Activity的启动模式有四种,分别是standard、singleTop、singleTask和singleInstance模式

  • standard模式

Activity的默认启动方式,每启动一个Activity就会在栈顶创建一个新的实例

  • singleTop模式

在某些情况下standard启动模式并不合理,当Activity以及位于栈顶时,再次启动该Activity时还需要创建一个新的实例压入任务栈,不能直接复用

singleTop模式启动Activity更合理,该模式会判断要启动的Activity是否位于栈顶,存在则直接复用,否则创建新的实例

  • singleTask模式

使用singleTop虽然可以很好地解决重复压入栈顶Activity实例的问题,但如果Activity并未处于栈顶位置,则在栈中还会压入多个不相连的Activity实例,如果想要某个Activity在整个应用程序中只有一个实例,则需要借助singleTask模式实现

当Activity的 启动模式指定为singleTask时,则每次启动该Activity时,系统首先会检查栈中是否存在当前Activity实例,如果存在则直接使用,并把当
前Activity上面的所有实例全部弹出栈

实际开发中,浏览器主界面通常采用这种模式

  • singlelnstance模式

singleInstance模式是四种启动模式中最特殊的一种, 指定为singleInstance模式的Activity会启动一个新的任务栈来管理Activity实例,无论从哪个任务栈中启动该Activity,该实例在整个系统中只有一个

Android中的桌面使用的就是该模式

开启使用singleInstance模式的Activity分两种情况:

  1. 要开启的Activity实例在栈中不存在,则系统会先创建一个新的任务栈,然后再压入Activity实例

  2. 另一种是要启动的Activity已存在,系统会把Activity所在的任务栈转移到前台,从而使Activity显示

4.6 使用Fragment

4.6.1 Fragment简介

Fragment (碎片)是一种嵌入在Activity中的UI片段,它可以用来描述Activity中的一部分布局,如果Activity 界面布局中的控件比较多比较复杂,那么Activity管理起来就很麻烦,我们可以使用Fragment把屏幕划分成几个片段,进行模块化的管理,从而使程序更加合理和充分地利用屏幕空间

一个Activity中可以包含多个Fragment,一个Fragment也可以在多个Activity中使用,如果在Activity中有多个相同的业务模块,则可以复用Fragment

4.6.2 Fragment的生命周期

因为Fragment是被嵌入到Activity中使用的,因此它的生命周期的状态直接受其所属Activity的生命周期状态影响。当在Activity中 创建Fragment时,Fragment处于启动状态,当Activity被暂 停时,其中的所有Fragment也被暂停,当Activity被 销毁时,所有在该Activity中的Fragment也被销毁。当一个Activity处于运行状态时,可以单独地对每一个Fragment进行操作,如添加或删除,当添加时,Fragment处于启动状态。当删除时,Fragment处于销毁状态

Fragment的生命周期比Activity多了几个方法:

  • onAttach():Fragment与Activity建立关联时调用
  • onCreateView():Fragment创建视图(加载布局)时使用
  • onDestroyView():Fragment关联的视图被移除时调用
  • onDetach():Fragment与Activity解除关联时调用

在这里插入图片描述

4.6.3 创建Fragment

创建Fragment时必须创建一个继承自Fragment的类

public class NewListFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //将布局文件动态加载到Fragment
        View v =inflater.inflate(R.layout.activity_main,container,false);
        return v;
    }
}
4.6.4 在Activity中添加Fragment

Fragment创建完成后不能单独使用,还需要将Fragment添加到Activity中,把Fragment添加到Activity中的两种方式:

  • 在布局文件中添加Fragment

需要使用标签,但该标签必须指定android:name属性,其属性值为Fragment的全路径值

  • 在Activity中动态添加Fragment

当Activity运行时,也可以将Fragment动态的添加到Activity中具体步骤:

(1)创建Fragment实例对象–>(2)获取FragmentManager(Fragment管理器)的实例–>(3)开启FragmentTransaction(事物)–>(4)向Activity的布局容器(一般为FragmentLayout)中添加Fragment–>(5)通过commit()方法提交事物

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //实例化fragment对象
        NewListFragment fragment = new NewListFragment();
        //获取FragmentManager实例
        FragmentManager fm = getFragmentManager();
        //获取FragmentTransaction实例
        FragmentTransaction begin = fm.beginTransaction();
        //添加一个Fragment
        begin.replace(R.id.ll, fragment);
        //提交事物
        begin.commit();
    }
}

如果文章对您有所帮助,记得一键三连支持一下哦~

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香蕉道突破手牛爷爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值