Android 开发入门(3)
0x05 活动 Activity
(1)启停活动页面
a. 启动和结束
从当前页面跳转至新页面
startActivity(new Intent(this, [targetPage].class))
从当前页面返回至上个页面(相当于关闭当前页面)
finish();
举例:Activity1 跳转至 Activity2:
XML:
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始跳转至二页面" />
Java:
// Activity1.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_1);
findViewById(R.id.btn_1).setOnClickListener(this);
}
@Override
public void onClick(View view) {
// 跳转
startActivity(new Intent(this, Activity2.class));
} // Activity2.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
findViewById(R.id.btn_2).setOnClickListener(this);
}
@Override
public void onClick(View view) {
// 结束并返回
finish();
}
b. 生命周期
生命周期:每个对象从创建到销毁的历程
分类:
- 前景模式:Foreground Process
- 可见模式:Visible Process
- 背景模式:Background Process
- 空白模式:Empty Process
执行顺序:
// Activity1.java
private static final String TAG = "SRIGT"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "Activity1 onCreate");
setContentView(R.layout.activity_1);
findViewById(R.id.btn_1).setOnClickListener(this);
} @Override
public void onClick(View view) {
startActivity(new Intent(this, Activity2.class));
} @Override
protected void onStart() {
super.onStart();
Log.d(TAG, "Activity1 onStart");
} @Override
protected void onResume() {
super.onResume();
Log.d(TAG, "Activity1 onResume");
} @Override
protected void onPause() {
super.onPause();
Log.d(TAG, "Activity1 onPause");
} @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "Activity1 onStop");
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "Activity1 onDestroy");
} @Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "Activity1 onRestart");
}
graph LR
1.onCreate-->2.onStart
-->3.onResume
--切换活动-->4.onPause
-->5.onStop
--返回源活动-->6.onRestart
-->2.onStart
4.onPause--切换活动等待时间较短-->3.onResume
--按退出键-->7.onPause
-->8.onStop
-->9.onDestroyonCreate
:创建活动,将页面布局加载进内存,初始状态onStart
:开始活动,将活动页面显示在屏幕上,就绪状态onResume
:恢复活动,活动页面进入活跃状态,允许用户交互onPause
:暂停活动,活动页面进入暂停状态,不允许用户交互onStop
:停止活动,不显示活动页面onRestart
:重启活动,重新加载内存中的页面数据onDestroy
:销毁活动,回收活动占用的系统资源,把页面从内存中去除onNewIntent
:重用已有活动实例
graph LR
A(不存在)-- onCreate-->B(初始状态)
-- onStart-->C(就绪状态)
-- onResume-->活跃状态
-- onPause-->C
-- onStop-->B
-- onDestroy-->A
c. 启动模式
Activity 的启动模式类似于数据结构中栈的 “ 先进后出 ” 特点
静态设置启动模式
在 manifest 中通过 launchMode 属性设置的
默认启动模式 Standard
启动的 Activity 会依照启动顺序依次压入 Task 栈中
栈顶复用模式 SingleTop
当栈顶 Activity 为目标 Activity 时就不会重复创建新的 Activity。一般用于渠道多、多应用开启调用的 Activity
栈内复用模式 SingleTask
如果 task 栈内存在目标 Activity 实例,则将 task 内的对应 Activity 实例之上的所有 Activity 弹出栈,并将对应 Activity 置于栈顶。一般用于程序主界面、耗费系统资源的 Activity
全局唯一模式 SingleInstance
该模式为目标 Activity 创建一个新的 task 栈,将目标 Activity 放入新的 task,并让目标 Activity 获得焦点
动态设置启动模式
通过 Java 代码实现,通过 Intent 动态设置 Activity 启动模式
FLAG_ACTIVITY_NEW_TASK
开辟新的任务栈
FLAG_ACTIVITY_SINGLE_TOP
当栈顶为待跳转的 Activity 实例时重用栈顶实例
FLAG_ACTIVITY_CLEAR_TOP
当栈中存在待跳转的 Activity 实例时重新创建一个新实例,并清除原实例上方的所有实例
FLAG_ACTIVITY_NO_HISTORY
栈中不保存新启动的 Activity 实例
FLAG_ACTIVITY_CLEAR_TASK
跳转到新页面时栈中原有实例都被清空
(2)消息传递
a. 显/隐式 Intent
Intent 是各组件之间信息沟通的桥梁
- 标明本次通信请求的起点、终点、方式
- 发起方携带所需数据,接收方解析该数据
- 发起方若想判断接收方是否接收成功,Intent 就要让接收方传回应答的数据内容
Intent 组成部分
元素名称 设置方法 说明 Component setComponent 组件,指定 Intent 的来源和目标 Action setAction 行为,指定 Intent 的行为 Data setData URI,指定行为要操纵的数据路径 Category addCategory 类别,指定 Intent 的操作类别 Type setType 数据类型,指定消息的数据类型 Extras putExtras 扩展信息,指定装载的包裹信息 Flags setFlags 标志位,指定 Activity 的启动标志 显式 Intent
直接指定来源活动与目标活动,属于精准匹配
构建方式:
在 Intent 的构造函数中指定
// 创建一个目标确定的 Intent
Intent intent = new Intent(this, ActNextActivity.class);
调用 Intent 对象的 setClass 方法指定
// 创建一个新 Intent
Intent intent = new Intent();
// 设置 Intent 要跳转的目标活动
intent.setClass(this, ActNextActivity.class);
调用 Intent 对象的 setComponent 方法指定
// 创建一个新 Intent
Intent intent = new Intent();
// 创建包含目标活动在内的组件名称对象
ComponentName component = new ComponentName(this, ActNextActivity.class);
// 设置 Intent 携带的组件信息
intent.setComponent(component);
隐式 Intent
具有标记过滤作用,从而不向外暴露活动名称,没有明确指定要跳转的目标活动,只给出一个行为字符串让系统自动匹配,属于模糊匹配
Intent 类的系统行为常量名 系统行为的常量值 说明 ACTION_MAIN android.intent.action.MAIN App 启动时的入口 ACTION_VIEW android.intent.action.VIEW 向用户显示数据 ACTION_SEND android.intent.action.SEND 分享内容 ACTION_CALL android.intent.action.CALL 直接拨号 ACTION_DIAL android.intent.action.DIAL 准备拨号 ACTION_SEMDTO android.intent.action.SENDTO 发送短信 ACTION_ANSWER android.intent.action.ANSWER 接听电话 举例一:调用系统拨号程序:
@Override
public void onClick(View view) {
// 设定目标号码
String phone = "13800000000";
// 创建新 Intent
Intent intent = new Intent();
// 设置 Intent 行为为准备拨号
intent.setAction(Intent.ACTION_DIAL);
// 声明一个拨号的 Uri
Uri uri = Uri.parse("tel: " + phone);
// 设置 Intent 前往的路径
intent.setData(uri);
// 启动 Intent 通往的 Activity 页面
startActivity(intent);
}
举例二:调用系统发送短信:
intent.setAction(Intent.ACTION_SENDTO);
Uri uri = Uri.parse("smsto: " + phone);
b. 向下一个 Activity 发送数据
Intent 使用 Bundle 对象存放待传递的数据信息
Bundle 对象操作各类型数据的读写方法
数据类型 读取方法 写入方法 整型数 getInt putInt 浮点数 getFloat putFloat 双精度浮点数 getDouble putDouble 布尔值 getBoolean putBoolean 字符串 getString putString 字符串数组 getStringArray putStringArray 字符串列表 getStringArrayList putStringArrayList 可序列化结构 getSerializable putSerializable Bundle
- 发送方通过调用 Intent 对象的
putExtras()
方法存入消息包裹 - 接收方通过调用 Intent 对象的
getExtras()
方法取出消息包裹
- 发送方通过调用 Intent 对象的
实例:
发送方
@Override
public void onClick(View view) {
Intent intent = new Intent(this, Activity2.class); // 创建包裹用来发送消息
Bundle bundle = new Bundle();
bundle.putString("message", "需要发送的消息"); intent.putExtras(bundle);
startActivity(intent);
}
接收方
TextView rec = findViewById(R.id.tv_rec); // 接收消息
Bundle bundle = getIntent().getExtras();
// 将接收到的消息存储在 str 中
String str = bundle.getString("message"); rec.setText(str);
c. 向上一个 Activity 返回数据
- 上一个页面打包好请求数据,调用
startActivityForResult()
方法执行跳转动作 - 下一个页面接收并解析请求数据,进行相应处理
- 下一个页面在返回上一个页面时,打包应答数据并调用
setResult()
方法返回数据包裹 - 上一个页面重写方法
onActivityResult()
,解析获得下一个页面的返回数据
实例:
发送方
private String str = "text";
private ActivityResultLauncher<Intent> register; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_1);
((TextView)findViewById(R.id.req)).setText("待发送的消息: " + str);
findViewById(R.id.btn_1).setOnClickListener(this); register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result != null) {
Intent intent = result.getData();
if (intent != null && result.getResultCode() == Activity.RESULT_OK) {
Bundle bundle = intent.getExtras();
String str = bundle.getString("content");
((TextView)findViewById(R.id.res)).setText("应答内容" + str);
}
}
});
} @Override
public void onClick(View view) {
Intent intent = new Intent(this, Activity2.class);
Bundle bundle = new Bundle();
bundle.putString("content", str);
intent.putExtras(bundle);
register.launch(intent);
}
接收方
private String str; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
TextView req = findViewById(R.id.req);
Bundle bundle = getIntent().getExtras();
String content = bundle.getString("content");
str = String.format("收到的消息: " + content);
req.setText(str); findViewById(R.id.btn_2).setOnClickListener(this);
((TextView)findViewById(R.id.res)).setText("带返回的消息: " + str);
} @Override
public void onClick(View view) {
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("string", str);
setResult(Activity.RESULT_OK, intent);
finish();
}
(3)消息附加
a. 利用资源文件配置字符串
在 /values/strings.xml 中配置字符串
<resources>
<string name="app_name">Test</string>
</resources>
在 Activity 中调用
((TextView)findViewById(R.id.req)).setText(getString(R.string.app_name));
b. 利用元数据传递配置信息
元数据时一种描述其他数据的数据,它相当于描述固定活动的参数信息。通过在 AndroidManifest.xml 文件的 Activity 节点中添加
<meta-data />
,通过android:name=""
属性指定元数据的名称,通过android:value=""
属性指定元数据的值
- 调用
getPackageManger()
方法获取当前应用的包管理器 - 调用包管理器的
getActivityInfo()
方法获取当前活动的信息对象 - 活动信息对象的 metaData 是 Bundle 包裹类型,调用包裹对象的
getString()
方法获取指定名称的参数值
实例:
在 AndroidManifest.xml 中设置元数据
<activity
android:name=".Activity1"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> <meta-data
android:name="ysjName"
android:value="text" />
</activity>
在 Activity 中调用元数据
// 获取应用包管理器
PackageManager pm = getPackageManager();
try {
// 从应用包管理器中获取当前 Activity 信息
ActivityInfo activityInfo = pm.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
// 获取 Activity 附加的元数据信息
Bundle metaData = activityInfo.metaData;
((TextView)findViewById(R.id.req)).setText(metaData.getString("ysjName"));
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
c. 利用元数据配置快捷菜单
可用元数据传送资源数据从而给应用页面注册快捷方式。元数据中
<meta-data />
的android:resource=""
属性可指定一个 XML 文件,表示元数据需要的信息保存在 XML 数据中
- 在 res/values/strings.xml 添加各菜单项的在字符串配置
- 创建 res/xml/shortcuts.xml,在此设置各组菜单项的快捷方式定义
- 给 Activity 节点注册元数据的快捷菜单配置
实例:
shortcuts.xml
<?xml version ="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="sc1"
android:enabled="true"
android:icon="@drawable/ic_launcher_background"
android:shortcutShortLabel="@string/title1"
android:shortcutLongLabel="@string/longTitle1"> <intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.example.test"
android:targetClass="com.example.test.Activity1" /> <categories
android:name="android.shortcut.conversation" /> </shortcut>
<shortcut
android:shortcutId="sc2"
android:enabled="true"
android:icon="@mipmap/ic_launcher"
android:shortcutShortLabel="@string/title2"
android:shortcutLongLabel="@string/longTitle2"> <intent
android:action="android.intent.action.VIEW"
android:targetPackage="com.example.test"
android:targetClass="com.example.test.Activity2" /> <categories
android:name="android.shortcut.conversation" /> </shortcut>
</shortcuts>
其中,strings.xml 文件内容如下:
<resources>
<string name="app_name">Test</string>
<string name="title1">短标题1</string>
<string name="title2">短标题2</string>
<string name="longTitle1">很长很长很长很长的长标题1</string>
<string name="longTitle2">很长很长的长标题2</string>
</resources>
在 AndroidManifest.xml 中设置元数据
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts"
android:value="" />
Android 开发入门(3)的更多相关文章
- [译]:Xamarin.Android开发入门——Hello,Android Multiscreen深入理解
原文链接:Hello, Android Multiscreen_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android Multiscreen深入理解. 本 ...
- [译]:Xamarin.Android开发入门——Hello,Android深入理解
返回索引目录 原文链接:Hello, Android_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android深入理解 本部分介绍利用Xamarin开发And ...
- [译]:Xamarin.Android开发入门——Hello,Android快速上手
返回索引目录 原文链接:Hello, Android_Quickstart. 译文链接:Xamarin.Android开发入门--Hello,Android快速上手 本部分介绍利用Xamarin开发A ...
- 教我徒弟Android开发入门(一)
前言: 这个系列的教程是为我徒弟准备的,也适合还不懂java但是想学android开发的小白们~ 本系列是在Android Studio的环境下运行,默认大家的开发环境都是配置好了的 没有配置好的同学 ...
- Android开发入门经典【申明:来源于网络】
Android开发入门经典[申明:来源于网络] 地址:http://wenku.baidu.com/view/6e7634050740be1e650e9a7b.html?re=view
- Android开发入门要点记录:四大组件
cocos2dx跨平台开发中需要了解android开发,昨天快速的浏览了一本Android开发入门教程,因为之前也似懂非懂的写过Activity,Intent,XML文件,还有里面许多控件甚至编程思想 ...
- Android开发入门
教我徒弟Android开发入门(一) 教我徒弟Android开发入门(二) 教我徒弟Android开发入门(三) 出处:http://www.cnblogs.com/kexing/tag/Androi ...
- android开发入门经验 ADT Bundle环境搭建
现在有许多做开发的转做移动端开发,做J2EE的转做Android开发,我也把自己的一些入门经验与大家分享一下,希望能给你带来帮助. 工具/原料 JDK,ADT,JAVA 方法/步骤 开发工具的准备 ...
- [Android]Android开发入门之HelloWorld
引言:在做Unity开发的时候,发现这么个问题,虽然Unity是跨平台的,能够进行Android,IOS,Web,PC等开发,但如果要实现一些稍微系统层的东西,还是需要通过通信,调用原系统的接口(自定 ...
- 教我徒弟Android开发入门(二)
前言: 上一期实现了简单的QQ登录效果,这一期继续对上一期进行扩展 本期的知识点: Toast弹窗,三种方法实现按钮的点击事件监听 正文: Toast弹窗其实很简单,在Android Studio ...
随机推荐
- Linux 多进程服务配置 systemd
目录 Linux 多进程服务配置 systemd sysvinit和systemd 多进程保活 创建配置文件(设定重试次数) 多进程服务管理 链式启动(服务依赖) 指定关闭进程方式 - ExecSto ...
- 微软应用商店错误代码“0x80131500”怎么修复?
处理方法一 打开"运行"输入 inetcpl.cpl ("WINDOWS"+"R"键,输入 inetcpl.cpl亦可),点开高级往下拉,勾 ...
- 摆脱鼠标系列 - vscode 上一个编辑器 下一个编辑器 Ctrl + h Ctrl + l
摆脱鼠标系列 - vscode 上一个编辑器 下一个编辑器 Ctrl + H Ctrl + L 为什么 根据 hjkl h是左边的原则 h 左移一位 b 左移一个单词 H 移动到句首 0 是行首 I是 ...
- bat 执行 窗口jar包
bat 执行 窗口jar包 @echo off start javaw -jar .\yourname.jar exit
- 🚀🚀🚀Elasticsearch 主副分片切换过程中对业务写入有影响吗
先说下结论,只要集群中的工作节点过半,有候选的master节点,挂掉的节点中不同时包含索引的主分片和副分片,那么ES是可以做到让业务无感知的进行主副分片切换的. 蓝胖子会先讲解下ES集群写入文档的原理 ...
- vmware虚拟机共享文件夹显示不出来的解决办法
今天在虚拟机里部署测试环境时,遇到一个问题,就是在vmware设置里明明共享了文件夹,但是在CentOS里却看不到共享的文件夹 环境 宿主机:MacBook Pro 虚拟机:vmware 15 虚拟机 ...
- 【Mahjong hdu 枚举】搜索枚举
#####枚举 import java.io.*; import java.util.*; public class Main { static HashSet<String> set1; ...
- JS(DOM事件高级)
一 注册事件(绑定事件) 1.1 注册事件概述 给元素添加事件,称为注册事件或者绑定事件.注册事件有两种方式:传统方式和方法监听注册方式 1.2 addEventListener 事件监听方式 eve ...
- JS(循环)
一 for循环 在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件.由循环体及循环的终止条件组成的语句,被 称之为循环语句 1 语法结构 for循环主要用于把某些代码 ...
- 从零开始的 dbt 入门教程 (dbt cloud 自动化篇)
一.引 在前面的几篇文章中,我们从 dbt core 聊到了 dbt 项目工程化,我相信前几篇文章足够各位数据开发师从零快速入门 dbt 开发,那么到现在我们更迫切需要解决的是如何让数据更新做到定时化 ...