浅谈一下Android的Activity

手机APP/开发
290
0
0
2023-05-10
标签   Android
目录
  • 前言 :
  • 一 Activity 启动和结束
  • 二 Activity 生命周期
  • 1 Activity 的四种状态
  • 2 流程解读
  • 3 具体功能
  • 4 总结
  • 三 Activity 启动模式分类
  • 1 Standard 标准模式
  • 2 SingleTop 栈顶复用模式
  • 3 SingleTask 栈内复用模式
  • 4 SingleInstance 单实例模式
  • 四 启动模式的设置
  • 1 在Manifest.xml 中指定Activity 启动模式
  • 2 在启动Activity 时,在Intent 中指定启动模式去创建Activity
  • 五 Activity Flags
  • 1 FLAG_ACTIVITY_NEW_TASK
  • 2 FLAG_ACTIVITY_SINGLE_TOP
  • 3 FLAG_ACTIVITY_CLEAR_TASK
  • 4 FLAG_ACTIVITY_CLEAR_TOP
  • 六 Intent
  • 1 显式Intent
  • 2 隐式Intent
  • 七 传递数据
  • 1 向目标Activity 传递数据
  • 2 回传信息

前言 :

Android 系统的四大组件分别是

1 活动 (Activity)

2 服务(Service)

3 广播接收器(Broadcast Receiver)

4 内容提供器 (Content Provider)

其中活动是所有安卓应用程序的门面,凡事你在应用中看到的东西,都是放到活动中的。

一 Activity 启动和结束

1 从当前页面跳转到下个页面, startActivity(原页面.this,目标页面.class)

          // 跳转到下一个页面
                startActivity(new Intent(MainActivity.this, ActFinishActivity.class));

2 结束返回

finish 结束当前页面进行返回

 
    @Override
    public void onClick(View view) {
 
        if (view.getId() == R.id.goBack){
            finish();
        }
    }

二 Activity 生命周期

1 Activity 的四种状态

1> 运行中(Running/Active),这是Activity 位于栈顶库,是可见的,可以与用户交互。

2> 暂停(Paused),当Activity 失去焦点,不能跟用户交互了,但依然可见,就会处于暂停状态。

当一个新的非全屏的Activity或者一个透明的Activity 放置在栈顶,Activity 就处于暂停状态。

3> 停止 (Stoped),当一个Activity 被另外一个Activity完全覆盖,或者点击Home键进入了后台,这时候就处于停止状态。这个时候数据还保存着。

4> 销毁(Destroyed) ,点击返回键或者系统在内存不够用的情况下就会把Activity 从栈里移除销毁。

2 流程解读

1> 在Activity 运行之前,会调用onCreate,onStart,onResume 这三个方法,之后Activity 就处于Running 状态了

2> 当Activity 暂停时候,会调用onPause, Activity 重新恢复到运行状态的时候,会运行onResume

3> Activity 处理停止状态时,会调用onStop。这个时候如果要恢复运行状态就会调用一个新的方法onRestart,然后再去调用onStart,onResume

4>当Activity被销毁的时候,会调用onDestroy方法

3 具体功能

1 onCreate: 当Activity第一次被创建时调用。是生命周期开始的第一个方法。在这里我们可以做一些初始化的操作,比如:调用setContentView()方法去加载界面,绑定布局里的一些控件,初始化一些Activity需要用到的数据。之后会调用onStart方法.

2 onStart:当Activity正在变为可见时调用。这个时候Activity已经可见了,但是还没有出现在前台还不能跟用户交互。可以简单理解为Actvity已经可见但是还没有出现在前台。之后会调用onResume.

3 onResume:当Activity可以跟用户交互时调用,这个时候,这个Activity位于栈的顶部。跟onStart相比,它们都是表示Activity已经可见,但是onStart调用时Activity还在后台,而调用onResume时,Activity已经进入了前台,可以跟用户交互了。之后会调用 onPause.

4 onPause:当Activity暂停时调用这个方法;在这里我们可以用来保存数据,关闭动画和其它比较耗费CPU的操作;但是在这里做的操作绝对不能耗时,因为如果当前Activity要启动一个新的Activity,这个新的Activity会在当前Activity执行完毕onPause之后才能进入可见状态。这个方法之后一般会调用的方法有onStop或者onResume. ==在Android3.0之前,调用这个方法之后,Activity可能会在系统内存紧张时被系统回收==

5 onStop:当Activity进入后台,并且不会被用户看到时调用。当别的Activity出现在前台时,或者Activity会被销毁时,调用此方法;在这个方法调用之后,系统可能会在内存不够的情况下回收Activity;在这个方法之后一般会调用onRestart或者onDestroy.

6 onDestroy:这个方法是Activity生命周期中调用的最后一个方法。它会在Activity被销毁之前调用;Activity销毁原因一般是我们调用Activity的finish方法手动销毁,另一个就是系统在内存紧张的情况下去销毁Activity,以用来节省空间。我们可以通过方法 isFinishing 来判断Activity是否正在被销毁。

7 onRestart:这个方法是在Activity处于停止状态后,又回到可视状态时调用。之后会调用onResume

4 总结

1 打开新页面

onCreate --> onStart --> onRume

2 关闭旧页面

onPause --> onStop --> onDestroy

三 Activity 启动模式分类

这个模式可以在Mainifest.xml 文件中设定,如果不设定,默认就是standard

1 Standard 标准模式

这个模式启动的Activity 会按照启动顺序依次压入到Task 栈中

2 SingleTop 栈顶复用模式

如果栈顶Activity 为我们 要新创建的Activity,那么久不回重复创建新的Activity

3 SingleTask 栈内复用模式

若 需要创建的Activity 已经处于栈中时,此时不会创建新的Activity ,而是将其上面的其他Activity 全部销毁,使其成为栈顶,

4 SingleInstance 单实例模式

具有此模式的Activity 仅仅单独处于一个任务栈中

四 启动模式的设置

1 在Manifest.xml 中指定Activity 启动模式

<activity            android:name=".MainActivity"            android:exported="true"            android:launchMode="singleTask"            >

2 在启动Activity 时,在Intent 中指定启动模式去创建Activity

   Intent intent = new Intent(MainActivity.this, ActFinishActivity.class);                // 栈中存在待跳转的实例时,重新创建该活动的实例,并且清除原来实例上方所有的实例                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);                // 跳转到下一个页面                startActivity(intent);

以上两种方式都能为Activity 设置启动模式,可是二者还是有差别的。

优先级 :动态指定的优先级较高

限定范围:静态指定方式无法为Activity 直接指定 FLAG_ACTIVITY_CLEAR_TOP 标识,

动态指定无法为Activity 指定singleInstance 模式

五 Activity Flags

1 FLAG_ACTIVITY_NEW_TASK

开辟一个新的任务栈

2 FLAG_ACTIVITY_SINGLE_TOP

当栈顶为待跳转的活动实例之时,则重用栈顶的实例

3 FLAG_ACTIVITY_CLEAR_TASK

跳转到新页面的时候,栈中原油的实例都被清空

4 FLAG_ACTIVITY_CLEAR_TOP

栈中存在待跳转的实例时,重新创建该活动的实例,并且清除原来实例上方所有的实例

六 Intent

各个组件之间信息沟通的桥梁吗,它用于Android各个组件之间的通信。

* 1 标明本次通信从哪里来吗,到哪里去,要怎么走

* 2 发起方携带本次通信需要的数据内容,接收方从收到的意图中解析出数据

* 3 发起方若想判断接收方的处理结果,意图就要负责让接收方传回应答的数据内容。

1 显式Intent

明确指定要跳转的Activity

创建方式1 直接初始化

 Intent intent = new Intent(MainActivity.this, ActFinishActivity.class);

创建方式2 setClass

 Intent intent2 = new Intent(); 
 intent2.setClass(MainActivity.this,ActFinishActivity.class);

创建方式3 setComponent

 Intent intent3 = new Intent();
 ComponentName component = new     ComponentName(MainActivity.this,ActFinishActivity.class);
intent3.setComponent(component);

2 隐式Intent

没有明确要跳转的目标Activity,只给出一个动作字符串让系统自动匹配,属于模糊匹配。

比如说

打电话 ACTION_DIAL

发短信 ACTION_SENDTO

当然了 还可以跳转自己定义的页面,不过自己定义的需要设置一下 Manifest.xml

exported = true

IntentFilter在xml中的三個主要的参数:action,categary,data。

        <activity
            android:name=".ActFinishActivity"
            android:exported="true"
            >
            <intent-filter>
                <action android:name="android.intent.action.myselfActivity"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
 
        </activity>
switch (view.getId()){
 
            case R.id.jump_to_tel:
            {
                Intent intent = new Intent();
                intent.setAction(Intent.ACTION_DIAL);
                Uri uri = Uri.parse("tel:123456789");
                intent.setData(uri);
                startActivity(intent);
            }
                break;
            case R.id.jump_to_sms:
                Intent intent2 = new Intent();
                intent2.setAction(Intent.ACTION_SENDTO);
                // 123456789 为发送目标
                Uri uri2 = Uri.parse("sms:123456789");
                intent2.setData(uri2);
                startActivity(intent2);
                break;
            // 跳转我自己的页面
            case R.id.jump_to_my_self:
 
                Intent intent3 = new Intent();
                intent3.setAction("android.intent.action.myselfActivity");
                intent3.addCategory(Intent.CATEGORY_DEFAULT);
                startActivity(intent3);
                break;
 
            default:
                throw new IllegalStateException("Unexpected value: " + view.getId());
        }

七 传递数据

1 向目标Activity 传递数据

传递数据是使用Bundle 来实现的。其内部就是一个Map,用起来也和map 相差无几

原界面传递数据

Intent intent = new Intent(MainActivity.this,ActFinishActivity.class);
// 传递信息到下个界面 通过bundle 包装数据
Bundle bundle = new Bundle();
bundle.putString("params","go on my lady");
intent.putExtras(bundle);
startActivity(intent);

目标界面接收数据

//  获取数据
Bundle bundle = getIntent().getExtras();
String value = bundle.getString("params");
tv.setText(value);
Log.e("Fibonacci", "onCreate: "+value);

2 回传信息

这个时候要使用 ActivityResultLauncher 这个东西 了。其目的用于简化页面中跳转获取返回值以及请求权限。

ActivityResultLauncher必须在onCreate或者onAttach方法下初始化。

在原页面中代码

跳转页面的时候 是 register.launch(intent);

package com.example.leonardoday1;
 
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
 
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
 
import java.net.URI;
 
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 
    private static final String TAG = "Fibonacci";
    private ActivityResultLauncher<Intent> register;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.send_next_msg).setOnClickListener(this);
        TextView tv = findViewById(R.id.main_tv);
 
        register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result != null){
                    Intent intent = result.getData();
                    if (intent != null && result.getResultCode() == Activity.RESULT_OK){
                        // 获取返回的数据
                        Bundle bundle = intent.getExtras();
                        String string = bundle.getString("params");
                        tv.setText(string);
                        Log.e(TAG, "onActivityResult: " + string);
                    }
                }
            }
        });
    }
 
    @Override
    public void onClick(View view) {
 
        switch (view.getId()){
 
            case R.id.send_next_msg:
            {
                Intent intent = new Intent(MainActivity.this,ActFinishActivity.class);
                // 传递信息到下个界面 通过bundle 包装数据
                Bundle bundle = new Bundle();
                bundle.putString("params","go on my lady");
                intent.putExtras(bundle);
                register.launch(intent);
            }
                break;
 
            default:
                throw new IllegalStateException("Unexpected value: " + view.getId());
        }
 
 
    }
}

在目标页面的代码

// 反回信息给上个界面
Intent intent = getIntent();
Bundle bundle = new Bundle();
bundle.putString("params","i have receive your message");
intent.putExtras(bundle);
setResult(Activity.RESULT_OK,intent);
// 返回上个界面
finish();