Activity
Activity
1.Activity
1.1数据传递
1.什么是数据传递?
2.Activity之间的关系
1)单向数据传递
2)双向数据传递
1.2Intent简介
1.简介
- intent是信使,完成组件之间的通信功能。
- 携带数据,就是一个信息包
- 启动Activity,启动Service,发送BroadCastReceiver
- 承担应用程序之间的组件之间相互通信的作用
2.Activity之间的数据传递
3.具体方法
组件名称 | 方法名称 |
Activity | startActivity() startActivityForResult() |
Service | startService() bindService() |
Broadcasts | sendBroadcast() sendOrderedBroadcast() sendStickyBroadcast() |
- 启动Activity:向Context.startActivity() 或Activity.startActivityForResult()方法传递一个Intent对象,可以启动一个activity,或使得一个已经存在的activity去做一些新的事情。(也可以向 Activity.setResult() 去传递这个Intent对象,返回调用了startActivityForResult()的activity的一些信息。)
- 启动Service:向 Context.startService() 方法传递Intent对象可以初始化一个service或者向一个已经存在的service传递新的指令。类似的,向Context.bindService() 方法传递Intent对象可以在调用所在的组件和目标service之间建立一种连接。如果这个service并没有开始运行,则它可以初始化这个service。
- 发起广播Broadcast:以向下面的广播方法传递Intent对象来发起广播:Context.sendBroadcast(),Context.sendOrderedBroadcast(), 或 Context.sendStickyBroadcast()。系统会找到相应的广播接收者对此进行响应。
4.启动方式
- 显式:直接指定组件的名称
- 隐式:没有显式指定组件的名称,需要进行筛选
注意,启动Activity,Service以及BroadCastReceiver之间的Intent是没有重合的
5.Intent的组成
Android Intent 基本使用及对象构成 - 圣骑士wind - 博客园
- 组件名:要处理的组件的名称,一般就是包名或者类名。是一个可选项,设置的话就显式指定了要转向的组件,没有就是隐式。
- setComponent,setClass,setClassName
- Action:要完成的动作
- data:数据规格,URI是数据和MIME是数据类型
- cateGory:额外信息,能够处理Initent对象的组件的种类
- Extra:额外数据,以Bundle的形式定义。
- putXxx和putExtras就是额外的数据
- Flags:各种类型的Flag。很多是用来指定Android系统如何启动activity,还有启动了activity后如何对待它。所有这些都定义在Intent类中。
注意:
- action动作,category类别,data(uri和数据类型),决定启动哪一个
- 显式,需要指定组件名
6.实例1:
7.实例2:
- 组件名:交给洗衣机
- Action是指Intent要完成的动作,是一个字符串常量。“洗”
- Data属性是执行动作的URI和MIME类型,不同的动作有不同的数据规格。“衣服”
- Category是一个字符串,提供了额外的信息,有关于能够处理这个Intent对象的组件种类。“洗张三的衣服”
- Extras:传递给Intent的额外数据,以Bundle的形式定义,就是一些键值对。“用洗衣机的速洗模式洗衣服”
1.3Initent的显式启动
1.步骤
- 创建Intent
- 设置要启动的组件(Activity)(可以采用有参数构造函数或者是无参数的构造函数)
- startActivity进行启动
1.4Initent的隐式启动
1.优点
- 优点:不需要指明启动哪一个Activity,而由Android系统来决定,有利于使用第三方组件。
- 隐式启动Activity时,Android系统在应用程序运行时解析Intent,并根据一定的规则对Intent和Activity进行匹配,使Intent上的动作、数据与Activity完全吻合。
2.隐式启动匹配的过程
3.IntentFilter
- 过滤Action,数据Data以及Category的作用
- 接收什么样的请求行为,什么类型的请求数据
- 后面的广播就是用到的这个,匹配action,data(uri)以及category等,匹配成功才会启动,否则就失败
- category是对action的补充说明
- 启动action的时候需要Action和Category同时匹配才可以
4.intentFilter的属性
标签 | 属性 | 说明 |
<action> | android:name | 指定组件所能响应的动作,用字符串表示 |
<category> | android:category | 用于为action增加额外的附加类别信息 |
<data> | android:host | 指定一个有效的主机名 |
android:mimetype | 指定组件能处理的数据类型 | |
android:path | 有效的URI路径名 | |
android:port | 主机的有效端口号 | |
android:scheme | 所需要的特定的协议 |
5.启动系统的activity
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlString));
- 参数1:action,就是要执行的动作
- 参数2:data,传递的数据
6.常见的系统的action
动作 | 说明 |
ACTION_ANSWER | 打开接听电话的Activity,默认为Android内置的拨号盘界面 |
ACTION_CALL | 打开拨号盘界面并拨打电话,使用Uri中的数字部分作为电话号码 |
ACTION_DELETE | 打开一个Activity,对所提供的数据进行删除操作 |
ACTION_DIAL | 打开内置拨号盘界面,显示Uri中提供的电话号码 |
ACTION_EDIT | 打开一个Activity,对所提供的数据进行编辑操作 |
ACTION_INSERT | 打开一个Activity,在提供数据的当前位置插入新项 |
ACTION_PICK | 启动一个子Activity,从提供的数据列表中选取一项 |
ACTION_SEARCH | 启动一个Activity,执行搜索动作 |
ACTION_SENDTO | 启动一个Activity,向数据提供的联系人发送信息 |
ACTION_SEND | 启动一个可以发送数据的Activity |
ACTION_VIEW | 最常用的动作,对以Uri方式传送的数据,根据Uri协议部分以最佳方式启动相应的Activity进行处理。对于http:address将打开浏览器查看;对于tel:address将打开拨号呼叫指定的电话号码 |
ACTION_WEB_SEARCH | 打开一个Activity,对提供的数据进行Web搜索 |
1.5Activity之间的单向数据传递
1.简介
当一个Activity启动另一个Activity时,常常会有一些数据要传递过去,在Android中,需要传递的数据放在对象Intent中。
2.方法
前一个Activity传递数据:
- putExtras方法:都是key-value的形式
- putExtras(Bundle data):向Intent中放入需要携带的数据。
- putExtra(String name, int value):向Intent中放入键值对。
- putExtra(String name, char value)
- putExtra(String name, int[] value)
- 。。。。。。。。
后一个Activity获取数据:
- getIntent方法
- 再去调用getXxxExtra
3.采用bundle的数据传递
- 放数据:intent.putExtras(bundle);
- putXxx,放入各种类型数据
- putSerializable,放入可序列化对象
1.6Activity之间的双向数据传递
1.简介
- Activity提供了一个startActivityForResult(Intent intent,int requestCode )方法来启动其他Activity。该方法用于启动指定的Activity,而且期望获取指定Activity返回的结果。
- 为了获取被启动的Activity所返回的结果,当前Activity需要重写onActivityResult(int requestCode,int resultCode,Intent intent)。
- 一个Activity中可能包含多个按钮,并调用startActivityForResult()方法来打开多个不同的Activity处理不同的业务。当这些新Activity关闭时,系统都会调用前面Activity的onActivityResult(int requestCode,int resultCode,Intent intent)方法,利用request Code区分是哪个请求结果触发的,利用resultCode区分返回的数据来自哪个新的Activity。
2.方法
(1)前一个Activity传递数据:
- 第一个参数是Intent,第二个参数是请求码,用于判断数据的来源
(2)后一个Activity传递数据:
- setResult(int resultCode,Intent data)
- resultCode:结果码,一般使用0或1;
- Intent:带有数据的Intent
(3)前一个Activity接收传递数据:
- 重写onActivityResult()方法,
- protected void onActivityResult(int requestCode,int resultCode,Intent data)
- requestCode:启动Activity时传递的请求码;
- resultCode:表示在返回数据时传入结果码;
- data:携带返回数据的Intent
3.为什么需要用requestCode呢?
- 请求码是为了判断数据来源的
- 结果码是用来判断数据处理是不是成功的
1.7Activity数据传递案例
1.项目要求:模拟一个登录注册的界面采用单向和双向数据传递的方式
图1 登录界面
图2 登录成功界面
图3 模拟的注册界面
2.项目目录
- 登录界面-单向
- 主界面-页面跳转,发出单向和双向数据,接收数据
- 注册界面-双向
- 实体类
图3 项目目录
3.参考代码
(1)主界面和布局文件
1)布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="页面跳转"
android:textColor="@color/black"
android:textSize="30dp"
android:gravity="center"
android:layout_gravity="center_horizontal"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/login"
android:layout_margin="5dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="登录"
/>
<Button
android:id="@+id/register"
android:layout_margin="5dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="注册"
/>
</LinearLayout>
</LinearLayout>
2)Java代码
/*
* 页面跳转
* 跳转到登录界面,单向数据传递
* 跳转到注册界面双向数据传递
* */
public class MainActivity extends AppCompatActivity {
Button login,register;
User user=new User();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
login=findViewById(R.id.login);
register=findViewById(R.id.register);
loginListener();
registerListener();
}
//方法:登录
public void loginListener(){
login.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (user != null&&user.getId()!=0&&user.getName()!=null&&user.getPassword()!=null) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, LoginActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("user", user);
intent.putExtras(bundle);
startActivity(intent);
} else {
Toast.makeText(MainActivity.this, "用户信息为空,请注册!", Toast.LENGTH_SHORT).show();
}
}
});
}
//方法:注册
public void registerListener(){
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (user != null&&user.getId()!=0&&user.getName()!=null&&user.getPassword()!=null){
Toast.makeText(MainActivity.this, "用户信息已存在,请登录!", Toast.LENGTH_SHORT).show();
}
else {
Intent intent=new Intent();
intent.setClass(MainActivity.this,RegisterActivity.class);
startActivityForResult(intent,1);
}
}
});
}
//方法:接收回传数据
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
System.out.println("所有回传的数据!");
if (requestCode==1&&resultCode==1){
Intent intent=data;
Bundle bundle=intent.getExtras();
user= (User) bundle.getSerializable("user");
System.out.println(user);
}
}
}
(2)登录界面和布局文件
1)布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoginActivity">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:hint="登录成功提示语!"
android:textColor="@color/black"
android:textSize="20dp"
android:gravity="center"
android:maxLines="1"
android:ellipsize="end"
android:layout_gravity="center_horizontal"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="退出登录"
android:textColor="@color/white"
android:background="@color/red"
android:textSize="30dp"
android:onClick="backLogin"
/>
</LinearLayout>
2)Java代码
//登录后界面
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//获取单向传递的信息
User user=(User) getIntent().getExtras().getSerializable("user");
if (user!=null){
TextView title=findViewById(R.id.title);
title.setText("欢迎您!"+user.getName()+"登录成功!");
}
}
//方法:推出登录
public void backLogin(View view) {
Intent intent=new Intent();
intent.setClass(getBaseContext(),MainActivity.class);
startActivity(intent);
Toast.makeText(this, "退出成功!", Toast.LENGTH_SHORT).show();
finish();
}
}
(3)注册界面和布局文件
1)布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RegisterActivity">
<!-- 为了测试写死了-->
<EditText
android:id="@+id/account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="要注册的账号"
android:enabled="false"
android:text="1"
android:maxLines="1"
android:textColor="@color/black"
/>
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"
android:enabled="false"
android:text="张三"
android:maxLines="1"
android:textColor="@color/black"
/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="要注册的密码"
android:enabled="false"
android:text="123456"
android:maxLines="1"
android:textColor="@color/black"
/>
<LinearLayout
android:layout_margin="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:onClick="backRegister"
android:textSize="30dp"
android:text="取消注册"
android:textColor="@color/white"
android:background="@color/red"
/>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:onClick="forRegister"
android:textSize="30dp"
android:textColor="@color/white"
android:background="@color/blue"
android:text="注册"
/>
</LinearLayout>
</LinearLayout>
2)Java代码
//注册信息界面
public class RegisterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
}
//方法:取消注册
public void backRegister(View view) {
Intent intent=new Intent();
intent.setClass(getBaseContext(),MainActivity.class);
startActivity(intent);
Toast.makeText(this, "取消注册成功!", Toast.LENGTH_SHORT).show();
finish();
}
//方法:注册
public void forRegister(View view) {
Intent intent=new Intent();
Bundle bundle=new Bundle();
User user=new User(1,"张三","123456");
bundle.putSerializable("user",user);
intent.putExtras(bundle);
setResult(1,intent);
Toast.makeText(this, "注册成功!", Toast.LENGTH_SHORT).show();
finish();
}
}
(4)实体类
public class User implements Serializable {
private int id;
private String name;
private String password;
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User() {
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
4.效果图
1.8案例:隐式启动自己设置的activity
1.注意
- 自己设置的在AndroidManifast.xm那么必须加上android.intent.category.DEFAULT,否则不起作用.
1)manifest代码
<!-- 测试隐式启动-->
<activity android:name=".IntentDemo2"android:exported="true">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="com.lxz.openDemo"/>
<category android:name="android.com.lxz.openDemo"/>
</intent-filter>
</activity>
<!-- 隐式启动-->
<activity android:name=".IntentDemo"android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2)第一个activity的Java代码,布局文件就一个button省略
//隐式启动
public void openDemo(View view) {
Intent intent=new Intent();
intent.setPackage("com.lxz.review2");
intent.setAction("com.lxz.openDemo");
intent.addCategory("android.com.lxz.openDemo");
intent.putExtra("code","200");
startActivity(intent);
}
3)被启动的界面Java代码
String code=getIntent().getStringExtra("code");
Toast.makeText(this, "code:"+code, Toast.LENGTH_SHORT).show();
4)效果图
1.9案例:隐式启动系统的activity
1.案例1
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com"));
startActivity(intent);