<1>关于Activity和AndroidManifest
我们AS项目里的AndroidManifest.xml文件其实就是一个清单文件,用于描述我们的项目内容
其中包含了一些Application、activity、包名等信息,还包括一些权限的声明(例如在数据存储时使用SD卡读写的权限声明)
四大组件也都需要在这里注册之后才能使用
Application就代表一个应用程序,其中可以包含四大组件
而Activity是用于处理用户操作,与用户进行交互的(可以理解为一个容器,一个窗口,主要用于承载UI内容)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidactivitydemo"> //包名
//这两行就是设置权限,允许外置存储卡读写操作
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
//一个application就代表了一个应用程序
<application
android:allowBackup="true" //允许系统备份
android:icon="@mipmap/ic_launcher" //设置应用的桌面图标(这些图标存储在res文件夹的mipmap里的lc_launcher下)
android:label="@string/app_name" //设置应用程序的名称(它存储在res文件夹的values下的strings里)
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" //支持从右到左
android:theme="@style/Theme.AndroidActivityDemo"> //用于控制样式(它存储在res文件夹的values下的themes里)
<activity
android:name=".MainActivity" //四大组件的静态注册都要这样
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
如何在一个Application中再新建一个activity呢?(即如何再新建一个UI窗口)
——首先新建一个类SecondActivity,这个类继承Activity
——重写其中的onCreate()方法
——然后再新建一个布局activity_second,在SecondActivity类中setContentView()显示这个布局
——最后要使这个新的Activity可以使用,需要在配置列表里注册一下
可以看到,在一个application中注册了有两个activity,一个标签设置为“第一个ActivityDemo”,另一个设置为“第二个ActivityDemo”,同时给了两个intent-filter,都声明的是主入口
所以最终的结果是,在手机中有两个app图标,都可以打开这个程序,分别是这个程序的两个界面
<2>利用显式意图来实现界面跳转
(显式Intent:按名称(完全限定类名)指定要启动的组件)
用一个案例来学习显式意图的界面跳转(目标是在主界面输入账号和密码,点击登录按键后,跳转到另一个界面,并在其中显示我们输入的账号和密码)
——首先,在MainActivity中和原来一样,通过id找到我们输入的账号和密码
——然后判断账号和密码是否为空,如果不为空,则创建一个意图对象 Intent ,把我们的账号和密码的值存储到这个对象里 putExtra()方法,存储了键值对
——调用startActivity()方法进行界面的跳转
——新建一个类SecondActivity,继承Activity并重写其中的onCreate()方法
——这个activity记得要在配置清单中声明一下才能使用
——最后在SecondActivity类中的onCreate方法里,getIntent()得到第一个界面中我们创建的意图对象,然后获取其中的内容并显示
——最终效果如下
<3>利用隐式意图来实现界面跳转
(隐式Intent:不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它)
隐式意图实现界面跳转的方式和显式差不多,主要差别就是创建Intent的方法
<4>区别
显式意图:也就是可以直接看到我们要跳转到的目标组件,例如之前要从MainActivity跳转到SecondActivity,用的是new Intent(this, SecondActivity.class);在这里面我们直接就可以看到目标组件的名称(一般是用于应用内组件的跳转)
隐式意图:用于跳转到第三方应用(一般是用于各个应用之间的跳转)
——创建显式意图的几种写法:
//第一种:
Intent intent = new Intent();
intent.setClassName("包名","类名");
startActivity(intent);
//第二种:
Intent intent = new Intent();
ComponentName componentName = new ComponentName("包名","类名");
startActivity(intent);
//第三种:
Intent intent = new Intent(this, 要跳转的界面类名.class );
startActivity(intent);
其实还有很多种写法,没有全部列出来
创建显式意图主要就是要找到组件的名称 ComponentName = 包名/类的路径名称
由于显式意图主要是用在应用内部各个组件之间的跳转,所以第三种方式就很方便
——创建隐式意图
隐式意图的创建步骤为:
创建Intent对象
给这个intent对象设置Action,设置它的category值,设置包名(可以在Android系统源码里查找过滤器 intent-filter 查看各个系统应用的action值和category值)
使用startActivity()方法跳转到另一个界面
Intent intent = new Intent();
intent.setAction(" 目标应用的组件的action值 ");
intent.setCategory(" 目标应用的组件的category值 ");
intent.setPackage(" 目标应用的组件的包名 ");
startActivity(intent);
采用这种方式,在创建和使用的时候我们是看不见这个组件的名称的,只通过它的action值,category值和包名就可以使用了
<5>组件之间的数据传递
Activity之间的数据传递和组件之间的数据传递是一样的
数据传递又分为两种:1 基本数据类型的数据传递 2 引用数据类型的数据传递(对象的传递)
——基本数据类型数据的传递
直接创建一个意图intent,调用intent中的putExtra()方法就可以把基本数据类型的数据以键值对的形式存储在这个intent中
然后切换界面,在接收界面中首先getIntent()拿到这个intent对象,然后再用intent.getExtra()方法用键获取到相应的值即可
——引用数据类型数据的传递
其实引用数据类型的传递和基本数据类型的数据传递方式差不多,都是利用了putExtra()和getIntent()两个方法,不同的是引用数据类型的数据在传递前必须要把数据序列化
要把数据序列化,就是要在传递的对象的类中实现Parcelable接口或者实现Serializable接口
Parcelable接口是Google自定义的接口,使用起来比较高效,直接将数据存储到内存中,然后传递
Serializable接口则是Java自带的,是写到持久化存储单元里然后再传递的,比较慢
例如我们要传递一个user对象,首先要对User类实现可序列化的接口
然后再传递
(需要注意的是,String类和Bitmap类本身就以及实现了序列化接口的,所以在传递string类型数据或bitmap类型的数据的时候,不需要再对其实现序列化接口,直接和基本数据类型传递一样的使用就可以了)
来写一个拨打电话的按键,练习一下用协议来传数据:
注意要在配置清单中打开打电话的权限
类似的打电话,发短信,或者操作其他应用的都可以通过这种方法,在Android源码中找到相应的参数,通过创建隐式意图的方法进行跳转和根据其中规定的协议进行数据传输
——也可以自己按这种方法定义界面操作,在配置清单中配置一下即可,其中 action 内容就是包名.应用名称 , category 意思就是这个应用的类别(例如DEFAULT就表示这是一个应用),data 后面可以自己设置约束
然后通过隐式意图,填写相关的配置信息,就可以跳转到该应用界面并传输数据
<6>Activity之间的数据回传
例如我们发微信朋友圈的时候,需要从朋友圈编辑界面先跳转到相册界面,选择想要发布的相片,然后选完之后会自动返回到朋友圈的编辑界面,并且选中的相片会传到这里
这种类似的情况就用到了Activity之间的数据回传
数据回传和跳转界面差不多,主要的区别在于数据回传要用到startActivityForResult(intent)这个方法而不是startActivity(intent)方法
写一个充值的例子来练习,具体要求是:
在主界面点击充值按键,跳转到充值界面,在充值界面充值等操作后,自动返回到主界面并显示操作结果
主界面中的操作
支付界面的操作
主要的思路就是,主界面调用startActivityForResult(intent,requestCode<1> )方法
在充值界面中,当完成充值操作会调用setResult(resulCode<2> , intent)方法,当完成取消充值会调用setResult(resultCode<3> ,intent)方法
在主界面中重写onActivityResult()方法,在这个方法中通过判断requestCode来确定返回数据应该去到哪个部位
通过判断resultCode来判断跳转的那个界面到底做了什么操作,用data.getExtra()方法获取到相应操作的数据结果