Android07_多界面_Activity生命周期
Posted 抓根宝
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android07_多界面_Activity生命周期相关的知识,希望对你有一定的参考价值。
四大组件:Activity,BroadCastRevier,Service,Content Provider(内容提供者)
1,多界面应用程序开发
Activity是搭建界面和用户之间的桥梁,所有的页面都是放在FrameLayoutContent下面,相同于通过setContentView对Content进行addView
1.1一个应用程序想要显示界面,必须要有activity,需要在清理里配置activity标签
1.2activity中默认生成的onCreate()方法,通过setContentVIew(R.xxxx)设置显示的布局文件.
1.3添加一个新的界面
①在清单文件里配置
<activity
<!--界面名称-->
android:name="com.zzx.mutiupdown.MainActivity"
android:label="@string/app_name" >
<!--意图过滤器, 如果不想在手机显示,就删掉这几行-->
<intent-filter>
<!--入口-->
<action android:name="android.intent.action.MAIN" />
<!--在桌面产生快捷图标-->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
②创建界面继承Activity类,重写onCreate方法,setContentView()设置显示的布局文件
结论:一个应用程序可以有多个快捷图标在手机上显示,代表可以有多个界面.
通常只保留一个图标在手机上,通过按钮跳转到别的页面
通过点击事件跳转页面:
①设置点击事件,
②Intent intent = new Intent();//意图对象
intent.setClass(上下文,激活界面的字节码);
startActivity(intent);
2,案例,人品计算器
2.1需求:点击界面,显示另一个界面,得出计算结果
①界面标题的取消:修改应用程序的主题,在activity标签中
指定theme属性 的值,
如何不记得去除标题,可以通过系统默认无标题查看style属性 android:theme="@android:style/Theme.Black.NoTitleBar"
增加一条item name=”android:windowNoTitle”>true</item>
②创建另一个界面,在清单文件里进行配置,name属性.
③重写onCreate方法,setContentView,指定布局文件
④主界面创建一个子线程,等待两秒后跳转
Intent intent = new Intent();//意图对象
intent.setClass(上下文,激活界面的字节码);
startActivity(intent);
这一操作不需要通过消息转发,可以直接执行
⑤在计算页面,一个文本输入框,一个按钮,一个显示框\\
⑥这样跳转到子界面,再点返回会回到主界面
在Activity中有一个方法finish();可以直接关闭主界面
额外,第二种方法通过handler.postDelayed(Runable,延迟时间)跳转,第一个参数 Runable,第二参数延迟时间
底层把Runable打包成Message对象,然后发送到MessageQuqe,通过在消息队列中延迟发送, Runable中不能再定义延迟效果,在第二个参数中定义即可,因为它本质上是在主线程中执行的.
第三种方法,Activity中的runOnUiThread方法,但是这种方法不能延迟.底层判断是否是主线程,不是主线程就通过消息队列发送,是主线程就直接调用RUN 方法
3,Activity的数据传递
基本数据类型,String,实现Parcelable的类
3.1,创建意图,
Intent intent = new Intent();
3.2,intent.setClass(this,ResultActivity.class);
简写 intent = new Intent(this,ResultACtivity.class);
3.3, 放置数据,intent.putExtra(“info”,info)// 在意图对象里传递要携带的数据
八大基本数据类型及数组,实现了Seriallizable
Parcelable 这两个接口的类
Finsh()关闭当前Avtivity
startActivity(intent)//执行意图
3.4,在结果界面,可以通过Intent intent = getInten();获取开启我这个Activity的意图.
通过intent.getStringExtra(“key”)//获取信息
也可以用put(String,Parcelable)传递图片,因为bitmap实现了Parcelable
4,界面跳转的显示意图和隐式意图
显示意图:必须要指定被开发的Activity的类名和路径名.就是通过创建Intent跳转.
隐式意图:只需要指定Action(动作)和数据即可
4.1显示意图
intent.setClass(上下文,激活界面的字节码);
New Intent(this,类名.class);
setClassName(全包名,激活界面的全包名)
三种写法都可以
4.2隐式意图
在activity的中定义意图过滤器intent-filter
在里面定义两个标签<action android:name = 全包名.OPEN02>
<category android:name =”android.intent.category.DEFAULT”/>
手机一般写default,
如果在电视应用选tv,如果是车载应用就选car
创建Intent intent = new Intent();
intent.setAction(被开启的全包名.xxx);
intent.addCategory(”android.intent.category.DEFAULT”);//开启的模式
startActivity(intent);
隐式意图会遍历整个清单文件,系统里满足这个过滤器的所有界面,然后找到它,去开启界面,效率较低
区别:
显示意图:不能开启别的应用,适用于激活自己应用程序内部的组件,效率高.
隐式意图:可以开启别的应用,在被开启的界面里需要配置清单文件,就可以被公共访问.
如果setAction(全包名.main)就会打开一个界面,显示所有应用程序的主界面,桌面图标.
隐式意图可以激活系统的应用程序,调用功能,或者授权登陆.
5.隐式意图
5.1重要配置:
<action:>跳转的页面标志
<category:>使用环境,手机,汽车,电视应用
<data android:scheme=”前缀” android:host=”主机地址” 这两个可以随意定义.
代码中setData(Uri.parse(前缀+”://”+ 地址))
intent.setData(Uri.parse("other://www.qq.com"));
如果设置了这个属性android:mimetype=文件类型>必须查表一致
就还要在代码中setType(文件类型);
必须都匹配上才能正确的打开隐式意图
这一行为相当于进一步进行过滤,避免页面标志出现一致
5.1.1 getData可以取值
5.1.2 data,action可能会有多个,只需要满足一个
catrgory有几个就添加几个
5.2出错原因
setType和 setData执行的时候会清楚掉另外一个方法的内容
所以,如果配置里面设置了这些属性,就要通过
setDataType(前缀+ 地址,数据类型);
额外:小技巧如果不知道系统应用的包名和类名,就在模拟器中使用一下这个应用,在LogCat里面就可以看到名称
6.案例,通过隐式应用打开浏览器
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:scheme="about" />
<data android:scheme="javascript" />
</intent-filter>
①主界面布局,定义一个文本框(按钮也可以),用户点击以后跳转到浏览器.
②设置多个点击事件
7,通过隐式意图发送短信
对方号码可以在前缀后面拼接
发送短信的内容要在源代码中查找,找到与发送信息相关的数据即可(属性名)
8,短信助手
需要通过A界面打开B界面,选择短信内容,B界面再把数据返回到A界面,A界面把数据显示在文本区域,如果用户点击发送,打开短信界面,显示输入电话号码和选择文本内容.
8.1 ui布局A界面,B界面
8.2 在B界面中,给每个条目设置一个点击事件
ListView.setOnItemClickListener(){}
8.3 在B界面中返回A界面
如果通过startActivity(Intent) 打开A界面,实际上是开了三个界面,旧A,新A
①可以通过startActivityForResult(intent,requestCode());打开另外一个界面
不能通过getIntent()获取?
②在被打开的界面setResult(resultCode,data);把结果返回开启界面
requestCode请求码
resultCode结果码,目前为0.
data意图,Intent data = new Intent();data.put(x,x);
③Finish();//关闭当前界面
④在开启页面中,重写onActivityResult方法,此方法是新界面传回数据时调用.
8.4 获取手机通讯录中的联系人
9,请求码和结果码
9.1请求码,通过startActivityForResult设置的请求码,可以在开启页面的onActivityResult的方法中进行判断,是从哪一个页面返回来的结果
9.2结果码,如果请求码一致,可以通过结果码判断
10 Activity的生命周期
对象从创建到死亡期间一定会执行的方法
onCreate()开启的时候调用 界面打开就会被创建
数据的初始化,数据的获取
onDestory()死亡的时候调用
释放资源的逻辑(关流,关数据库,对象赋值为null),以及数据保存逻辑
10.1短信助手功能拓展,用户如果自己编辑了短信,在跳转到别的页面的时候保存起来
SharedPreferences sp, 拿到编辑器,添加数据, commit提交
onStart()显示(对用户可见的)的时候调用,在oncreate之后调用
应用场景:当用户重新打开这个程序(没有关闭,只是最小化的时候),继续播放.
onStop()隐藏的时候(没有销毁,在后台继续运行,比如切换到桌面,接收到了一个电话灯,不是关掉后台)调用,在onDestory之前
应用场景,当这个应用界面最小化的时候(接到电话的时候),视频,音频暂停,保存临时信息.不希望在后台还会运行的应用,都可以通过这个方法实现
onResume();继续,获取焦点,继续游戏,取消透明样式
onPause();暂停,失去焦点,
应用场景:游戏应用,暂停,就是通过一个透明的样式把页面覆盖掉,虽然能看,但是不能对场景做操作(也可以用一个提示框+透明的样式)
焦点:
样式:Theme.Translucent.NoTitleBar(透明的,并且没有标题栏)
Activity完整生命周期(entire lifetime):六个方法
可视化生命周期(visbile lifetime):onstart>>onresume>onpause>>onstop>>onRestar
前台生命周期()onresume>>onPause
onRestart()当应用最小化并且没有被关闭,再次被打开的时候调用
回收优先级:后台大于前台周期
额外:
//把数据重新发送给Activity在onStart之后
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
//在onStop之前,和onpause的方法不分先后顺序
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
安卓离线帮助文档的使用:sdk/docs/index.html (国内链接不方便,建议断网使用)
11,横竖屏切换的生命周期
横竖屏切换默认是把旧界面销毁了,然后再重新创建一个新界面,这样会导致编辑的信息,游戏的进度重置.
解决方案①配置screenOrientation=”portrait”//竖直排列,Landspace横屏
把画面固定下来,就不会出现问题了
②配置android:configChanges = “keyboardHidden(软键盘)|screenSize(屏幕大小)|Orientation(横竖屏)”不让横竖屏切换,键盘事件影响程序
一般开发都是固定竖屏(不然横竖屏切换,累死ui)
12,Activity任务栈(task stack)
Task 一个任务一般包含多个 Activity,每个Activity都是用来处理用户交互的一个任务
Stack:栈,一种特殊的数据结构(后进先出),队列也是一种特殊的数据结构(先进先出)
打开应用程序,它就会创建一个任务栈(配置了singleinstance的例外)
13启动模式
配置位置,在Activity标签内配置属性android:LunchModel:模式
13.1 standard:标准的启动模式
13.2 singleTop:单一顶部模式,一个Activity可能会在这种模式下存在多个实例
如果Activity已经被开启,且处于任务栈的栈顶就不会创建新的Activity,而是复用这个已经开启的Activity,是为了防止一些奇怪的用户体验,比如一些页面为了强制用户使用某个功能,开启多个界面,用户如果不知道原理,会发现无论怎么返回都是在这个页面.
但是Android的短信应用,配置了singleTop启动模式,这样如果遇到流氓软件,就只需要退出短信再打开它,就能让着多个界面变成一个界面,关闭一次即可
13.3 singletask,每个定义这个模式的Activity在整个任务栈中最多只允许有一个实例存在
如果要开启的Activity在任务栈中已经存在,直接复用这个已经存在的Activity,并且把这个Activity上面的Avtivity全部清空
应用场景,如果一个Acctivity非常消耗内存和cpu资源,建议把这个Activity做成singletask的启动模式,比如浏览器,比如应用主界面(利用它会把上面的Activity全部删掉来达到节约内存空间的效果)
13.4 singleinstance 单一实例模式,一个应用程序一般只有一个任务栈,并且整个手机设备里只有一个实例,配置了singleinstance的Activity会单独开启一个任务栈例如:手机的通话界面,请求呼叫界面都是单一实例模式
未验证(在这个任务栈中可以创建多个重复的Activity,并且占有了顺序流(即返回也是先返回这些重复的任务栈,再到别的任务栈))
以上是关于Android07_多界面_Activity生命周期的主要内容,如果未能解决你的问题,请参考以下文章
android开发艺术探索学习 之 结合Activity的生命周期了解Activity的LaunchMode