安卓基础第六天(四大组件之Activity)
2018-02-21 03:12
671 查看
Activity 是Android 四大组件之一,它用于展示界面。
是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件。
Activity 之间通过Intent 进行通信。### Activity之间的跳转
在AndroidManifest.xml 的节点中声明
application中lable指程序的名字,
activity中的lable是指activity 的名字
name 属性::包名.Activity 类名
包名如果与mainfest 的package 一致,可以用“.”代替。或者不写
Intent-filter 子节点:
- 添加意图过滤,可以通过隐式意图启动。
- 可以在桌面生成快捷方式,应用程序的入口
如果此activity还指定了以下filter那么这个界面就会在桌面创建快捷方式
Icon 属性:图标
theme 属性:指定主题
一般用于自己程序的内部。显式跳转不可以跳转到其他程序的页面中。
隐式跳转不需要引用到那个类,但是必须得知道那个界面的动作(action)和信息(category)。
案例 RP计算器
跳转页
案例 短信发送器 (请求码,结果码)
requestCode 开启activity时设置的请求吗
resultCode 在目标activity中设置的结果码
主页面
获取联系人页面
获取短信模板页
- 1、当它在屏幕前台时,响应用户操作的Activity, 它是激活或运行状态
- 2、当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时, 它处于暂停状态。
- 3、当它完全被另一个Activity 覆盖时则处于停止状态。
当Activity 从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
图
startActivity 开启一个Activity 时, 生命周期的过程是:
onCreate ->onStart(可见不可交互) ->onResume(可见可交互)
点击back 键关闭一个Activity 时, 生命周期的过程是:
onPause(部分可见不可交互)->onStop(完全不可见)->onDestroy(销毁)
当开启一个新的Activity(以对话框形式), 新的activity 把后面的activity 给盖住一部分时, 后面的activity 的生命周期执行的方法是:
onPause(部分可见, 不可交互)
Activity 以对话框的形式显示,需在activity 节点追加主题android:theme=”@android:style/Theme.Dialog”
当把新开启的Activity(以对话框形式)给关闭时, 后面的activity 的生命周期执行的方法是:
onResume(可见, 可交互)
当开启一个新的activity 把后面的activity 完全盖住时, 生命周期的方法执行顺序是:
onPause ->onStop(完全不可见)
当把新开启的activity(完全盖住)给关闭时, 生命周期的方法执行顺序是:
onRestart ->onStart ->onResume(可见, 可交互)
实际工作中常用的方法以及应用场景有:
onResume 可见, 可交互.。把动态刷新的操作启动。
onPause 部分可见, 不可交互. 把动态刷新的一些操作, 给暂停了。
onCreate 初始化一些大量的数据。
onDestroy 把数据给释放掉, 节省内存。
不让Activity 在横竖屏切换时销毁,只需要在清单文件声明Activity 时配置节点的几个属性即可
兼容所有版本:
禁止横竖屏:
screenOrientation=”” 指定屏幕固定方向,不会随着屏幕旋转而旋转
android:screenOrientation=”portrait” 始终竖屏
android:screenOrientation=”landscape” 始终横屏
一个任务栈包含了一个activity 的集合, 去有序的选择哪一个activity 和用户进行交互:只有在任务栈栈顶的activity 才可以跟用户进行交互
任务栈可以移动到后台, 并且保留了每一个activity 的状态. 并且有序的给用户列出它们的任务, 而且还不丢失它们状态信息
退出应用程序时:当把所有的任务栈中所有的activity 清除出栈时,任务栈会被销毁,程序退出。
重复数据太多, 会导致内存溢出的问题(OOM)
可以在AndroidManifest.xml 配置的android:launchMode 属性为以下四种之一即可。
四种launchMode:
1.standard
默认模式
2.singleTop
如果任务栈的栈顶存在这个要开启的activity,不会重新的创建activity,而是复用已经存在的activity。保证栈顶如果存在,不会重复创建。
应用场景:浏览器的书签
3.singleTask
单一任务栈,在当前任务栈里面只能有一个实例存在,
当开启activity的时候,就去检查在任务栈里面是否有实例已经存在,
如果有实例存在就复用这个已经存在的activity,
并且把这个activity上面的所有的别的activity都清空,
复用这个已经存在的activity。保证整个任务栈里面只有一个实例存在
应用场景:浏览器的activity
4.singleInstance
activity会运行在自己的任务栈里面,并且这个任务栈里面只有一个实例存在
如果你要保证一个activity在整个手机操作系统里面只有一个实例存在,使用singleInstance
应用场景: 来电页面
是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件。
Activity 之间通过Intent 进行通信。### Activity之间的跳转
Activity清单配置
定义类继承Activity在AndroidManifest.xml 的节点中声明
application中lable指程序的名字,
activity中的lable是指activity 的名字
name 属性::包名.Activity 类名
包名如果与mainfest 的package 一致,可以用“.”代替。或者不写
Intent-filter 子节点:
- 添加意图过滤,可以通过隐式意图启动。
- 可以在桌面生成快捷方式,应用程序的入口
如果此activity还指定了以下filter那么这个界面就会在桌面创建快捷方式
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
Icon 属性:图标
theme 属性:指定主题
Activity 之间的跳转
显式意图跳转
可以引用到那个类, 并且可以引用到那个类的字节码时可以使用。一般用于自己程序的内部。显式跳转不可以跳转到其他程序的页面中。
隐式意图跳转
可以在当前程序跳转到另一个程序的页面隐式跳转不需要引用到那个类,但是必须得知道那个界面的动作(action)和信息(category)。
使用Intent意图传递数据
Activity 之间通过Intent 进行通信。Intent 即意图,用于描述一个页面的信息,同时也是一个数据的载体。案例 RP计算器
public class MainActivity extends Activity { private EditText et_name; private RadioGroup rg_group; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_name = (EditText) findViewById(R.id.et_name); rg_group = (RadioGroup) findViewById(R.id.radioGroup1); } // 点击按钮 实现计算人品 跳转到ResultActivity页面 public void click(View v) { // [1]获取用户名 String name = et_name.getText().toString().trim(); // [2] 判断一下name 是否为空 if (TextUtils.isEmpty(name)) { Toast.makeText(getApplicationContext(), "亲 请输入姓名", 1).show(); return; } // [3]判断用户选择的性别 int radioButtonId = rg_group.getCheckedRadioButtonId(); int sex = 0; switch (radioButtonId) { case R.id.rb_male: // 代表选择的是男 sex = 1; break; case R.id.rb_female: // 代表选择的是女 sex = 2; break; case R.id.rb_other: // 代表选择的是人妖 sex = 3; break; } if(sex == 0){ Toast.makeText(getApplicationContext(), "请选择性别", 1).show(); return; } //[4]跳转到ResultActivity页面 用显示意图跳转 Intent intent = new Intent(this, ResultActiviyt.class); //传递姓名 intent.putExtra("name", name); //传递性别 intent.putExtra("sex", sex); startActivity(intent); } }
跳转页
public class ResultActiviyt extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // [1]加载布局 setContentView(R.layout.activity_result); TextView tv_name = (TextView) findViewById(R.id.tv_name); TextView tv_sex = (TextView) findViewById(R.id.tv_sex); TextView tv_result = (TextView) findViewById(R.id.tv_result); // [2]获取mainActivity 传递过来的数据 Intent intent = getIntent(); // 获取开启此Activity的意图对象 // [3]获取name 和 sex 的值 小技巧 :传递的是什么数据类型 这边就按照传递的数据类型取 String name = intent.getStringExtra("name"); int sex = intent.getIntExtra("sex", 0); // [4]根据name 和 sex 显示数据 tv_name.setText(name); byte[] bytes = null; // [5]显示性别 try { switch (sex) { case 1: tv_sex.setText("男"); bytes = name.getBytes("gbk"); break; case 2: tv_sex.setText("女"); bytes = name.getBytes("utf-8"); break; case 3: tv_sex.setText("人妖"); bytes = name.getBytes("iso-8859-1"); break; default: break; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //[6]计算人品结果 市面上大多数应用采用的是随机数 int total = 0; for (byte b : bytes) { // 0001 1111 int number = b&0xff; // 1111 1111 total+=number; } // 获取得分 int score = Math.abs(total)%100; if (score > 90) { tv_result.setText("您的人品非常好,您家的祖坟都冒青烟啦"); }else if (score > 80) { tv_result.setText("您的人品还可以 "); }else if (score > 60) { tv_result.setText("您的人品刚及格"); }else{ tv_result.setText("您的人品太次了 您需要努力啊"); } } }
案例 短信发送器 (请求码,结果码)
requestCode 开启activity时设置的请求吗
resultCode 在目标activity中设置的结果码
主页面
public class MainActivity extends Activity { private EditText et_number; private EditText et_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //[1]找到我们关心的控件 et_number = (EditText) findViewById(R.id.et_number); et_content = (EditText) findViewById(R.id.et_content); } //点击按钮跳转到发送短信模板页面 public void insertsms(View v){ Intent intent = new Intent(this,SmsTemplateActivity.class); startActivityForResult(intent, 2); } //点击按钮 跳转到ContactActivity 页面 public void add(View v){ Intent intent = new Intent(this,ContactActivity.class); // startActivity(intent); //小细节 如果点击按钮 开启了另外一Activity 并且当开启的这个Activity关闭的时候 我想要这个开启Activity的数据 用下面这个方法开启activity startActivityForResult(intent, 1); } //当我们开启的Activity 页面关闭的时候 这个方法就调用 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode==1) { //代表请求ContactActivity这个页面的数据 String phone = data.getStringExtra("phone"); et_number.setText(phone); }else if (requestCode == 2) { //代表请求 短信模板页面的数据 String smsContent = data.getStringExtra("smscontent"); et_content.setText(smsContent); } /* if (resultCode == 10) { //说明数据是从 ContactActivity 返回 String phone = data.getStringExtra("phone"); et_number.setText(phone); }else if (resultCode == 20) { //说明数据 是从 SmsTempate 返回 String smsContent = data.getStringExtra("smscontent"); et_content.setText(smsContent); } */ super.onActivityResult(requestCode, resultCode, data); } //点击按钮 发送短信 public void send(View v){ //[1]获取发送短信的号码 和 发送的内容 String number = et_number.getText().toString().trim(); String content = et_content.getText().toString().trim(); //[2]获取到smsmanager的实例 SmsManager smsManager = SmsManager.getDefault(); ArrayList<String> divideMessages = smsManager.divideMessage(content); for (String div : divideMessages) { /** * destinationAddress 发送给谁 * scAddress 服务中心号码 * * text 要发送的内容 */ smsManager.sendTextMessage(number, null, div, null, null); } } }
获取联系人页面
public class ContactActivity extends Activity { private List<Person> lists; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //加载布局 setContentView(R.layout.activity_contact); //[1]找到控件 ListView lv = (ListView) findViewById(R.id.lv); //[2]准备listview 要显示的数据 模拟点假数据 lists = new ArrayList<Person>(); for (int i = 0; i < 20; i++) { Person p = new Person(); p.setName("张三"+i); p.setPhone("11"+i); lists.add(p); } //[3]展示数据 lv.setAdapter(new MyAdapter()); //[4]给listview 设置点击事件 lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //[5]获取我点中条目的数据 数据在哪里面存着呢 就去哪里取 String phone = lists.get(position).getPhone(); //[5.0]把数据返回给调用者 Intent intent = new Intent(); intent.putExtra("phone", phone); //把结果返回给调用者 setResult(10, intent); //[5.1]关闭当前页面 finish(); } }); } @Override public void onBackPressed() { super.onBackPressed(); } private class MyAdapter extends BaseAdapter{ @Override public int getCount() { return lists.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view; if (convertView == null) { view = View.inflate(getApplicationContext(), R.layout.contact_item, null); }else { view = convertView; } //[1]找到我们在item 中定义的控件 用来显示 数据 TextView tv_name = (TextView) view.findViewById(R.id.tv_name); TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone); //[2]展示数据 tv_name.setText(lists.get(position).getName()); tv_phone.setText(lists.get(position).getPhone()); return view; } } }
获取短信模板页
public class SmsTemplateActivity extends Activity { String objects[] = {"我在吃饭,请稍后联系","我在开会,请稍后联系","我在上课,请稍后联系","我在打代码,请稍后联系","我在约会,请稍后联系"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_smstemplate); //[1]找到lv ListView lv = (ListView) findViewById(R.id.lv); ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.smstemplate_item, objects); //[2]显示数据 lv.setAdapter(adapter); //[3]设置lv 的条目的点击事件 lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //[4]取出点击条目的数据 String smsContent = objects[position]; //[5]把smsContent 返回调用者 Intent intent = new Intent(); intent.putExtra("smscontent", smsContent); setResult(20, intent); //[6]调用finish finish(); } }); } }
Activity生命周期
Activity 有三种状态:- 1、当它在屏幕前台时,响应用户操作的Activity, 它是激活或运行状态
- 2、当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时, 它处于暂停状态。
- 3、当它完全被另一个Activity 覆盖时则处于停止状态。
当Activity 从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
方法名 | 说明 |
---|---|
void onCreate() | 设置布局以及进行初始化操作 |
void onStart() | 可见, 但不可交互 |
void onRestart() | 调用onStart() |
void onResume() | 可见, 可交互 |
void onPause() | 部分可见, 不可交互 |
void onStop() | 完全不可见 |
void onDestroy() | 销毁 |
startActivity 开启一个Activity 时, 生命周期的过程是:
onCreate ->onStart(可见不可交互) ->onResume(可见可交互)
点击back 键关闭一个Activity 时, 生命周期的过程是:
onPause(部分可见不可交互)->onStop(完全不可见)->onDestroy(销毁)
当开启一个新的Activity(以对话框形式), 新的activity 把后面的activity 给盖住一部分时, 后面的activity 的生命周期执行的方法是:
onPause(部分可见, 不可交互)
Activity 以对话框的形式显示,需在activity 节点追加主题android:theme=”@android:style/Theme.Dialog”
当把新开启的Activity(以对话框形式)给关闭时, 后面的activity 的生命周期执行的方法是:
onResume(可见, 可交互)
当开启一个新的activity 把后面的activity 完全盖住时, 生命周期的方法执行顺序是:
onPause ->onStop(完全不可见)
当把新开启的activity(完全盖住)给关闭时, 生命周期的方法执行顺序是:
onRestart ->onStart ->onResume(可见, 可交互)
实际工作中常用的方法以及应用场景有:
onResume 可见, 可交互.。把动态刷新的操作启动。
onPause 部分可见, 不可交互. 把动态刷新的一些操作, 给暂停了。
onCreate 初始化一些大量的数据。
onDestroy 把数据给释放掉, 节省内存。
横竖屏切换
横竖屏切换时,默认情况下会把activity 先销毁再创建,这个体验是非常差的不让Activity 在横竖屏切换时销毁,只需要在清单文件声明Activity 时配置节点的几个属性即可
兼容所有版本:
android:configChanges="orientation|keyboardHidden|screenSize
禁止横竖屏:
screenOrientation=”” 指定屏幕固定方向,不会随着屏幕旋转而旋转
android:screenOrientation=”portrait” 始终竖屏
android:screenOrientation=”landscape” 始终横屏
Activity任务栈
程序打开时就创建了一个任务栈, 用于存储当前程序的activity,所有的activity 属于一个任务栈。一个任务栈包含了一个activity 的集合, 去有序的选择哪一个activity 和用户进行交互:只有在任务栈栈顶的activity 才可以跟用户进行交互
任务栈可以移动到后台, 并且保留了每一个activity 的状态. 并且有序的给用户列出它们的任务, 而且还不丢失它们状态信息
退出应用程序时:当把所有的任务栈中所有的activity 清除出栈时,任务栈会被销毁,程序退出。
重复数据太多, 会导致内存溢出的问题(OOM)
Activity启动模式
为了解决任务栈产生的问题,Android 为Activity 设计了启动模式可以在AndroidManifest.xml 配置的android:launchMode 属性为以下四种之一即可。
四种launchMode:
1.standard
默认模式
2.singleTop
如果任务栈的栈顶存在这个要开启的activity,不会重新的创建activity,而是复用已经存在的activity。保证栈顶如果存在,不会重复创建。
应用场景:浏览器的书签
3.singleTask
单一任务栈,在当前任务栈里面只能有一个实例存在,
当开启activity的时候,就去检查在任务栈里面是否有实例已经存在,
如果有实例存在就复用这个已经存在的activity,
并且把这个activity上面的所有的别的activity都清空,
复用这个已经存在的activity。保证整个任务栈里面只有一个实例存在
应用场景:浏览器的activity
4.singleInstance
activity会运行在自己的任务栈里面,并且这个任务栈里面只有一个实例存在
如果你要保证一个activity在整个手机操作系统里面只有一个实例存在,使用singleInstance
应用场景: 来电页面
相关文章推荐
- 安卓中的四大组件_Activity
- 安卓四大组件之Activity
- 安卓四大组件之Activity学习
- Android基础--Android四大组件之Activity(一)
- 安卓四大组件之activity
- Android 基础知识总结---四大组件之一Activity(一)
- 【Android基础入门〖3〗】四大组件之Activity
- Android基础再回首——四大组件之Activity、Service俩兄弟
- [安卓基础] 009.组件Activity详解
- Android 四大组件之Activity 基础总结(1)
- 安卓四大组件之一 -------------------Activity_生命周期
- 安卓基础第七天(四大组件之BroadcastReceiver,样式主题,国际化,对话框)
- 安卓入门---四大组件---Activity
- Android基础学习【历史流程重走】 ----四大组件之Activity
- Android基础知识之四大组件Activity(三)多个Activity交互的生命周期与设计思想
- Android零基础系列之四大组件:activity
- 安卓四大组件之 Activity
- 安卓四大组件 之 Activity
- 安卓四大组件之Activity
- 安卓基础第八天(四大组件之Service,AIDL)