3.核心组件Activity

一.创建Activity

  • action的作用

action是显示数据给用户.
action是包含了UI和UI动作的代码.比如跳转,按钮单击事件等等.

每个action都对应一个界面配置文件,布局文件存在res下面的layout目录下.

  • onCreate代码

创建号action后,可以看到有个onCreate代码.这里面就是编写与UI交互的主要方法.

  • 绑定UI配置

在onCreate代码里加入setContenView(R.layout.布局名称)

  • action的注册

创建好action后,需要在AndroidManifest.xml注册.

android studio会自动注册.对于多个活动,我们还可以指定哪个activity作为首页活动.只需要在activity中加入如下代码,就可以首先启动.

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
  • 在活动中查找UI元素

findViewById(R.id.button1)

二.销毁Activity

正常情况下,返回键就会销毁当前活动.
也可以使用finish()方法来销毁.比如在按钮单击事件中执行,当前活动会直接销毁,界面消失.

    private Button btn1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn1=findViewById(R.id.button);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        Log.d(this.getClass().getName(),"测试");
    }

三.action使用menu菜单

  • 创建菜单UI配置
    在res目录下,创建menu文件夹,然后创建menu resource file文件.

在里面添加标签:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/add" android:title="add">
    </item>
</menu>
  • 关联菜单
    然后重写action中的OncreateOptionsMenu()方法.
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menus,menu);
        return true;
    }
  • 给menu增加响应事件
    重写 onOptionsItemSelected
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.addx:
                Toast.makeText(this, "添加",Toast.LENGTH_SHORT).show();
            break;
            default:
        }
        return true;
    }

然后运行,在手机右上角就会出现三个点.点击就会打开菜单.

四.activity跳转(界面跳转)

  • 使用显示Intent

点击按钮,由MainActivity跳转到MainActivityB.

    btnB=findViewById(R.id.button3);
    btnB.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent it = new Intent(MainActivity.this,MainActivityB.class);
            startActivity(it);
            }
        });
  • 隐式Intent

隐式的Intent是指不明确指定哪个action,而是靠系统分析,找出合适的Activity.比如你的app拉起支付宝app.

如果action要接受隐式的Intent跳转,需要在androidManifest.xml中,声明可以接受Intent调用.

比如我们要跳转到MainActivityB,就需要在AndroidManifest.xml修改MainActivityB的声明.

 <activity android:name=".MainActivityB">
     <intent-filter>
         <action android:name="com.example.test.action_start"></action>
         <category android:name="android.intent.category.DEFAULT"></category>
     </intent-filter>
 </activity>

action 是声明这个是可以被隐式调用的activity.

category 是对这action的分类说明.

  • 打开浏览器
btn4 = findViewById(R.id.button4);
btn4.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v) {
        Intent it = new Intent(Intent.ACTION_VIEW);
        it.setData(Uri.parse("http://www.baidu.com"));
        startActivity(it);
    }
});

Intent.ACTION_VIEW是系统内部的通用action,对应的是"android.intent.action.VIEW",配合Uri可以打开不同app等.

//打开电话
it.setData(Uri.parse("tel: 10086"));
//打开邮件
it.setData(Uri.parse("mailto:uri"));
  • action的数据类型

当用打开浏览器时,我希望我新创建的action也能和浏览器一样在可选择清单里,怎么办?

这个时候,就需要设置这个action的数据类型了.

创建一个action,增加一个data配置,action配置为"android.intent.action.VIEW",这样能响应Intent.ACTION_VIEW的设置,配置如下:

<activity android:name=".MainActivity3">
    <intent-filter tools:ignore="AppLinkUrlError">
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="http"/>
    </intent-filter>
</activity>

|数据类型|说明|
|android:scheme|数据协议|
|android:host|域名或主机,如www.baidu.com|
|android:port|数据端口|
|android:path|域名:端口之后的内容|
|android:mimeType|允许使用通配符处理的数据类型|

只有data的配置和intent携带的信息一致时,才会响应intent.

  • category有什么用?

在配置隐式intent时,这个是声明是默认的intent,如果不配置,会直接响应,而不是出现在被拉起的清单中.

五.intent传递数据

  • 传递基本数据类型的数据

通过putExtra可以将数据传递到下个intent,下个intent 使用getStringExtra()获取.

#传递数据
Intent intent= new Intent(Aacitivity.this,Bactivity.class)
String data="我是传递的数据!"
intent.putExtra("key",data)

#获取数据
Intent intent=getIntent();
data=intent.getStringExtra("key")

对于其他基本数据类型,有对应的get方法.

  • 传递对象对象类型的数据

被传递的对象需要实现序列号接口.比如有如下简单的类:

public class Book implements Serializable{
    private String title;
    private int page;
    public Book(){
        title='我是一本书';
        page=812;
    }
    public String getTitle(){
        return title;
    }
    public int getPage(){
        return page;
    }
    
}

使用getSerializableExtra获取对象.

#传递数据
intent.putExtra("book",book);
#取数据
Book book=(Book)intent.getSerializableExtra("book");

  • 返回数据给上个Action

在activity中,有个startActivityForResult方法也是用于启动action的.但这个方法销毁时,期望能返回一个结果给上个活动.

发起的intent使用startActivityForResult启动,并设置请求码为1

Intent it = new Intent(MainActivity1.this,MainActivity4.class);
startActivityForResult(it,1);

接受者,点击按钮返回数据:

btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent it = new Intent();
                it.putExtra("key","你好");
                //一般设置RESULT_OK或者RESULT_CANCELED
                setResult(RESULT_OK,it);
                finish();
            }
        });

发起的intent,重写onActivityResult方法,获取数据:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //验证请求码1
        switch (requestCode) {
            case 1:
                //验证返回码
                if(resultCode==RESULT_OK){
                    Log.i("test",data.getStringExtra("key"));
                }
                break;
            default:
        }
    }

六.action的生命周期

  • action的存储

action通过intent在各个action之间跳转。返回就销毁当前的action。这个活动的是放在stack里的.stack是先进后出,后进先出的数据结构.

每次点击back时,调用finsh()销毁当前action.stack就把最top的action删除.

生命周期状态


  • 运行状态:

当前活动的action.在stack的顶部.

  • 暂停状态

当处于非活动,但是仍然可见时,属于活动状态,不在stack顶部.如非全屏的对话框形式的窗口.
如果不是极度缺少内存,一般系统不会销毁这种action.

  • 停止状态

停止,并且不可见,不在staick顶部.一般不会被销毁,如果缺少内存,可能会被销毁.

  • 销毁状态

从stack移除,就被销毁了.

生命周期的七个方法

  • onCreate()

action初始方法,活动创建时,被调用.

  • onStart()

活动有不可见转为可见时调用.

  • onResume()

活动准备和用户交互时调用.此时,action处于stack栈顶.

  • onPause()

系统准备启动或者恢复另外一个action时.一般会释放无关紧要的数据,保存重要数据.这里的代码执行要快,不然会导致拉起新action卡,导致体验下降.

  • onStop()

action完全不可见时调用.如果启用的活动是对话框的话,此方法不会调用,但是onPause()会调用.

  • onDestroy()

action销毁前会调用.

  • onRestart()

活动停止状态转为运行状态是调用.

通过以上方法,可以看出

1.完整生命周期为onCreate()->onDestroy()之间

2.生存期为onStart()->onStop()之间
onstart()可以拉起前加载数据,onStop()释放数据.

3.前台生存期onResume()->onPause()
onResume()为准备交互,onPause()要恢复或者启动其他action前,要做的释放动作.

返回上个action,上个action以及被销毁怎么办?

如果我们有a->b,b进入不可见的停止状态,这时内存不足,系统把a给销毁了,所以b返回a,a是重写创建.如果我们从b->a发现之前录入的数据没了,体验非常不好.

我们可以在被销毁前,保存临时的用户数据.

  • **销毁前被执行的onSaveInstanceState():
@Override
protected void onSaveInstanceState(Bundle outState){
    super.onSaceInstanceState(outSate);
    String tempData="临时的数据"
    out.State.putString("key",tempdData)
}

现在只需要在onCreate()方法提取数据即可.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState!=null){
            String temp= savedInstanceState.getString("key")
        }
    }

七.action的启动模式

action有四个启动模式.因为每次启动(非唤醒)都会创建一个Instance,所以模式区别是有几个instance.
模式有:standard singeltop singleTask singleInstance,可以在AndroidManifest.xml中,通过activity标签指定andrlid:launchMode属性来指定.

模式实例数存储变量说明
standard可n个本程序stack默认模式,每次启动创建1个,不管当前action是否在栈顶
singleTop可n个本程序stack如果action处于栈顶,直接使用不在创建
singleTask本程序1个本程序stack如果发现栈内有该action,直接使用
singleInstance操作系统1个操作系统共享栈与操作系统的其他共享action共享一个stack,主用用于与其他app共享该action.为了防止不同的app拉起该action导致创建多个instance,所以共享一个stack,这样只会拉起一个

八.活动的最佳实践

定位当前是哪个活动

随着app的action增多,有时不知道到底是哪个action.可以使用继承方式,在action基类里打印具体的action的名字.

方法就是建立一个baseActivity继承AppCompatActivity.然后在onCreate里增加Log.d(“dd”,getClass().getSimpleName())

一键退除app

不可能一一退出所有的action.要一键退出,我们需要将action集中管理.

方法是建立一个action管理的class,里面使用List来进行管理action的清单,可以增加可以删除,也可以一次循环销毁所有action.

然后在baseActivity里的创建方法里,每次创建都将action加入进去.

然后重写基类的onDestroy()方法,在该方法执行时,调用action管理类的删除方法即可. 当要退出整个app时,直接调用action管理类的销毁方法即可.为保证完全退出,可以直接调用android.os.Process.killProcess(android.os.Process.myPid())

启动活动的最佳方法

活动之间跳转,需要创建intent,传递数据. 如果是自己开发的action,如何创建,别人不一定知道,所以最好自己创建,让别人传递创建的参数即可.

比如自己开发的一个action,名称叫Bactivity,实现一个创建action的方法,然后通过onCreate调用.如:

public static void actionStart(Contenxt,String 参数1,String 参数2){
    Intent intent = new Intenet (contenxt,SecondActivity.class);
    intent.putExtra("key",参数1)
    intent.putExtra("key",参数2)
    contenxt.startActivity(intent)
}

这时如果别人要启动你的Bactivity,直接调用你的这个方法即可:

Bactivity.actionStart(调用者的引用(xx.this),参数1,参数2)

这样别人就可以方便的拉起你的action了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT老卢

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

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

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

打赏作者

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

抵扣说明:

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

余额充值