第4章 Android程序活动单元Activity

第4章 Android程序活动单元Activity,第1张

第4章 Android程序活动单元Activity 第4章 Android程序活动单元Activity

目录

第4章 Android程序活动单元Activity

4.1 Activity的生命周期

4.1.1 生命周期状态4.1.2 生命周期方法 4.2 Activity的创建、配置、开启和关闭

4.2.1 创建Activity4.2.2 配置Activity4.2.3 开启和关闭Activity 4.3 Intent与IntentFilter

4.3.1 Intent4.3.2 IntentFilter 4.4 Activity之间的跳转

4.4.1 在Activity之间数据传递4.4.2 Activity之间的数据回传 4.5 Activity的任务栈和启动模式

4.5.1 Android中的任务栈4.5.2 Activity的启动模式 4.6 使用Fragment

4.6.1 Fragment简介4.6.2 Fragment的生命周期4.6.3 创建Fragment4.6.4 在Activity中添加Fragment

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属性进行设置,示例代码如下:

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

 
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”

    
        
        
    

(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, 需要这三个属性都匹配成功才能唤起相应的组件

    action属性匹配规则

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


    
    

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

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

    data属性匹配规则

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


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

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

    category属性匹配规则

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


隐式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传递数据有两种方式:

    使用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");
    使用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就 会被d出任务栈

用户 *** 作的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上面的所有实例全部d出栈

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

singlelnstance模式

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

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

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

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

    另一种是要启动的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();
    }
}

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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5717978.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存