Android应用开发-Activity(重制版)
Android四大组件:Activity,Service,Broadcast Receiver,Content Provider
Activity是Context的子类,同时实现了Window.Callback和KeyEvent.Callback接口,可以处理用户与窗体交互的事件。
创建Activity
定义一个XxxActivity类继承Activity,并重写onCreate()
在onCreate()中通过setContentView()加载该Activity的布局文件
在清单文件中配置activity标签,注册这个Activity
activity标签下如果带有下面这部分代码,则会在系统中多创建一个快捷图标
- <activity android:name=".MainActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- <activity android:name=".MainActivity">
一个应用程序可以在桌面创建多个快捷图标。
Activity的名称、图标可以和应用程序的名称、图标不相同
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:icon="@drawable/ic_launcher"
Activity的跳转
Activity的跳转需要创建Intent对象,通过设置Intent对象的参数指定要跳转的Activity
明确指定要启动或者触发的目标组件(可以是Activity,Service,BroadcastReceiver)的类名或包名的Intent,称为显式Intent。通过显式Intent实现Activity的跳转称为显式跳转。
隐式Intent没有明确指定要启动或者触发的目标组件的类名和包名,而只是指定了一系列更为抽象的Intent Filter的属性(包括action,category,data等)值,然后交由系统去分析这个Intent,并帮我们找出预启动或触发的目标组件。通过隐式Intent实现Activity的跳转称为隐式跳转。
显式跳转
跳转至同一应用中的Activity
- Intent intent = new Intent();
- intent.setClass(this, SecondActivity.class);// 指定当前的上下文和目标Activity的字节码
- startActivity(intent);
跳转至不同应用中的Activity
- Intent intent = new Intent();
- // 指定目标Activity所在的应用的包名和目标Activity的包名加类名,这里启动系统自带的拨号器应用(针对Android 4.3)
- intent.setClassName("com.android.dialer", "com.android.dialer.DialtactsActivity");
- startActivity(intent);
隐式跳转
隐式意图跳转至打电话Activity
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_CALL);
- intent.setData(Uri.parse("tel:10086"));
- startActivity(intent);
要让一个Activity可以被隐式启动,需要在该应用清单文件下的activity标签下配置intent-filter子标签
系统会在所有应用的清单文件中寻找与我们创建的隐式Intent匹配的intent-filter,找到则启动,找不到则抛异常
匹配就是intent-filter中定义了什么属性,我们创建的intent中也必须设置什么属性,并且对应的属性值也一样
在清单文件的activity标签下,配置intent-filter子标签,其中再配置data、action和category子标签。其中data标签下可以配置scheme、host、port、path等子标签,它们构成一个android.net.Uri对象 scheme://host:port/path ,也叫URL Scheme,其应用场景大体分为以下几种:
- 服务器下发跳转路径,app端根据服务器下发跳转路径跳转相应的页面
- H5页面点击锚点,根据锚点具体跳转路径app端跳转到相应的页面
- app端收到服务器下发的Push通知栏消息,根据消息的点击跳转路径跳转相关页面
- app端根据URL跳转到另外一个app的指定页面
应用场景
启动同一应用中的Activity,用显式Intent。显式启动效率明显高于隐式,因为显示直接指定了目标Activity,隐式需要遍历所有应用的清单文件寻找匹配的Intent Filter
启动不同应用中的Activity,用隐式Intent。当使用隐式Intent跳转到其他应用中的Activity时,如果系统找到了多个intent-filter与我们创建的Intent匹配,就会弹出对话框,列举所有匹配的Activity,让用户选择。比如我们的手机里如果安装了多款浏览器App,当我们点击一个URL时,会弹出一个对话框让我们选择使用哪个浏览器来打开这个网页,这就是因为跳转到浏览器Activity用的是隐式Intent;有些应用的Activity启动时需要接收数据,比如打电话Activity需要接收电话号码,也只能用隐式Intent
Activity跳转时的数据传递
Activity跳转时,可以把数据封装在Intent中
- Intent intent = new Intent(this, SecondActivity.class);
- intent.putExtra("name", name); // 字符串类型
- intent.putExtra("age", age); // 整型
- startActivity(intent);
- Intent intent = new Intent(this, SecondActivity.class);
在跳转到的目标Activity中取出数据
- Intent intent = getIntent(); // 获取启动该Activity的Intent
- String name = intent.getStringExtra("name");
- int age = intent.getIntExtra("age");
- Intent intent = getIntent(); // 获取启动该Activity的Intent
Intent中可以封装的数据类型:八大基本数据类型及其数组、String及其数组、实现了序列化接口Serializable和Parcelable的对象、Parcelable数组、Bundle对象(数据可以先封装至Bundle,再把Bundle封装至Intent)。
Activity的生命周期
onCreate():创建Activity时被回调
onStart():在屏幕上可见,但是还没有获得焦点,用户还不能与这个Activity进行交互(点击、滑动等)
onResume():可见并且获得焦点,用户已经可以和这个Activity进行交互(点击、滑动等)
onPause():可见,但是失去焦点。
onStop():完全不可见
onDestroy():销毁时调用
onRestart():Activity从不可见变为可见时调用
按Home键,系统依次回调onPause()、onStop(),Activity进入停止状态,进程还在(后台进程);若再次进入该Activity,系统会依次回调onRestart()、onStart()、onResume(),Activity重新进入运行状态
按Back键,系统依次回调onPause()、onStop()、onDestroy(),Activity被销毁,进程还在(空进程);若再次进入该Activity,系统会依次回调onCreate()、onStart()、onResume(),Activity重新进入运行状态
- 按返回键,Android系统会回调onBackPressed()方法,该方法调用了finish(),所以Activity会被销毁
当另一个优先级更高的进程需要内存而手机内存不足时,Android系统才会杀死之前启动的进程,按照进程优先级和LRU算法(优先级相同时)决定杀死哪个进程。
用户也可以到应用管理界面手动杀死某个进程。
Activity的四种启动模式
Task是我们在执行某种工作时所交互的activity的集合,这些activity集合按照打开的顺序被放置在同一个栈中,这个栈叫作Back Stack,Activity的启动模式决定了Back Stack的操作规则,对于启动同一应用中的Activity(启动其他应用中的Activity,四种启动模式的表现形式略微复杂,后续探讨),四种启动模式的表现如下:
standard:默认模式,每次发送一个Intent启动standard模式的Activity时,Android总会为目标Activity创建一个新的实例,并将该Activity实例添加到启动它的Activity所在的Task栈的栈顶
singleTop:Task栈顶单例模式,与标准模式仅有一点不同:当启动的目标Activity已经位于当前Activity所在Task栈的栈顶时,Intent不会再创建一个目标Activity实例(复用已有的Activity实例,不会触发onCreate()),而是通过onNewIntent()被发送到现有的Activity
- 应用:浏览器书签历史记录界面CombinedBookmarkHistoryActivity
- 应用:短信会话记录界面ConversationList
singleTask:采用这种启动模式的Activity在整个Android系统内存中只能有一个实例。对于启动同一个应用中的Activity,如果系统内不存在将要启动的目标Activity,系统将会创建目标Activity的实例,并将它压入当前Task栈顶;如果已经存在该Activity的实例,系统会将该Activity所在Task移至前台(多半是已经在前台),再退栈至该Activity,同时也会通过onNewIntent()将Intent发送到该Activity。对于启动不同应用中的Activity,如果系统内不存在将要启动的目标Activity,系统会创建一个新的Task,再创建出目标Activity的实例入栈;如果已经存在该Activity的实例,表现同启动同一应用中的Activity一致
- 应用:浏览器浏览界面BrowserActivity
singleInstance:采用这种启动模式的Activity在整个Android系统内存中也只能有一个实例,且总是独占一个Task,任何被此Activity启动的Activity都会被放到其它的task中。如果目标Activity不存在,系统会先创建一个新的Task,再创建目标Activity的实例压入栈顶;如果将要启动的目标Activity已经存在,无论它位于哪个应用程序中、位于哪个Task中,系统都会把该Activity所在的Task转到前台,从而使该Activity显示出来
- 应用:来电界面InCallScreen
Activity的横竖屏切换
默认情况横竖屏切换会使Activity销毁重建,触发生命周期方法重新执行
在一些特殊的应用程序中,比如游戏,不希望横竖屏切换导致Activity被销毁重建,因为如果不保存会丢失游戏数据
在清单文件中用以下代码让横竖屏切换时不重建Activity
- android:configChanges="orientation|screenSize|keyboardHidden"
在清单文件中可用以下代码写死Activity的屏幕方向
- android:screenOrientation="portrait" <!-- 竖屏 -->
- android:screenOrientation="landscape" <!-- 横屏 -->
- android:screenOrientation="portrait" <!-- 竖屏 -->
在java文件中可用以下代码写死Activity的屏幕方向(会覆盖清单文件中设置的屏幕方向,因为后执行)
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 竖屏
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 横屏
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 竖屏
Activity销毁时返回数据
步骤
指定请求码requestCode启动新的Activity
- Intent intent = new Intent(this, SecondActivity.class);
- startActivityForResult(intent, requestCode);// 只有用这种方式启动的Activity在销毁时才会回调原Activity的onActivityResult()方法
- Intent intent = new Intent(this, SecondActivity.class);
在新的Activity中设置要返回的数据
- Intent intent = new Intent(); // 该意图仅用来携带数据
- intent.putExtra("tel", tel);
- setResult(resultCode, intent); // 指定一个结果码resultCode,并把数据会返回给原Activity
- finish(); // 销毁当前的Activity
- Intent intent = new Intent(); // 该意图仅用来携带数据
在原Activity里面实现方法
- // 通过intent获取返回的数据
- onActivityResult(int requestCode, int resultCode, Intent intent) {
- }
- // 通过intent获取返回的数据
通过判断请求码和结果码确定返回的Intent的作用
先通过请求码requestCode判断返回的Intent来自哪一个Activity
再通过该Activity返回的结果码resultCode来判断Intent所携带的是该Activity返回的哪一个数据
Android应用开发-Activity(重制版)的更多相关文章
- Android入门笔记(重制版)
Android项目的目录结构(Eclipse版) src:项目源代码文件夹 R.java:存放项目中所有资源文件的资源id,永远不要修改 Android.jar:Android的jar包,导入此包方可 ...
- Android应用开发-Activity
Android四大组件:Activity,Service,Broadcast Receiver,Content Provider Activity是Context的子类,同时实现了Window.Cal ...
- Android开发--Activity生命周期回顾理解
Activity和Servlet一样,都用了回调机制.我们通过类比servlet来学习Activity.当一个servlet开发出来之后,该servlet运行于Web服务器中.服务器何时创建servl ...
- Android开发 ---Activity的7种运行状态
Android开发 ---Activity的7种运行状态 创建 --> 启动 --> 运行 --> 暂停 --> 停止 --> 销毁 重启 操作图解: 1.MainA ...
- Android开发——Activity生命周期
Android开发--Activity生命周期 Activity作为四大组件之首,也是使用最频繁的一种组件.本文将主要讲解Activity生命周期,包括正常情况下的Activity生命周期和异常情况下 ...
- Android软件安全开发实践(下)
Android开发是当前最火的话题之一,但很少有人讨论这个领域的安全问题.本系列将分两期,探讨Android开发中常见的安全隐患和解决方案.第一期将从数据存储.网络通信.密码和认证策略这三个角度,带你 ...
- Android Wear 开发入门
大家好,我是陆嘉杰,我是一名Android开发者.我想和大家进行一些技术交流,希望越来越多的人能和我成为好朋友. 大家都知道,智能手表是下一个开发的风口,而这方面的技术又属于前沿,所以和大家分享下An ...
- Android艺术开发探索第三章——View的事件体系(上)
Android艺术开发探索第三章----View的事件体系(上) 我们继续来看这本书,因为有点长,所以又分了上下,你在本片中将学习到 View基础知识 什么是View View的位置参数 Motion ...
- Android艺术开发探索——第二章:IPC机制(下)
Android艺术开发探索--第二章:IPC机制(下) 我们继续来讲IPC机制,在本篇中你将会学习到 ContentProvider Socket Binder连接池 一.使用ContentProvi ...
随机推荐
- iOS学习之SKTagView的使用
SKTagView是一款支持自动布局的标签tag. 特性: -流式展示标签 -可以配置标签的颜色.事件.间隔.外边距等 -支持Auto layout -可以在UITableViewCell中良好展示 ...
- SSH中,使用Filter拦截直接访问JSP页面!
话不多说,直接上代码 创建一个Filter类 package com.weibo.util; import java.io.IOException; import javax.servlet.Filt ...
- portotype
[ portotype ] [语法] function :function Name是创建新的函数的名称 body : body可以选项,包含调用该函数时被执行的JScrtipt 代码的字符串. ...
- runtime作用
1.发送消息 方法调用的本质,就是让对象发送消息. objc_msgSend,只有对象才能发送消息,因此以objc开头. 使用消息机制前提,必须导入#import <objc/message.h ...
- DotNetBar中TextBoxDropDown效果图
- ckedit 图片上传 php
分享ckedit的使用.直接码出来 <input type="hidden" name="id" id="id" value=&quo ...
- PowerDesigner中Name与Code同步的问题
转自:http://blog.sina.com.cn/u/48932504010005t9 PowerDesigner中,但修改了某个字段的name,其code也跟着修改,这个问题很讨厌,因为一般来说 ...
- MySQL分布式集群之MyCAT(转)
原文地址:http://blog.itpub.net/29510932/viewspace-1664499/ 隔了好久,才想起来更新博客,最近倒腾的数据库从Oracle换成了MySQL,研究了一段时间 ...
- Makefile拆分编写
在实际开发项目中,我们通常将一个工程划分为多个文件夹,每个文件夹代表不能的功能,如:我的一个项目cpl,它分为两个文件夹:src和test.当在cpl文件夹中运行make的时候,它的一级目录都会自动运 ...
- springmvc对同名参数处理-我们到底能走多远系列(44)
springmvc对同名参数处理 扯淡: 中断发博客几个月,其实蛮不爽的,可能最近太忙太劳累了些,很多总结也没时间写,今天刚好遇到个小问题,就阅读下源码找找乐.因为考虑到网上大多是提供解决问题的方案, ...