四大组件之Activity
来源:互联网 发布:淘宝买苹果游戏可靠吗 编辑:程序博客网 时间:2024/06/02 07:13
一、Activity生命周期
Activity 有三个状态:
当它在屏幕前台时,响应用户操作的Activity, 它是激活或运行状态.
当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时(如右图), 它处于暂停状态.
当它完全被另一个Activity覆盖时则处于停止状态.
当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
void onCreate()
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()
- startActivity开启一个Activity时, 生命周期的过程是: onCreate -> onStart(可见, 但不可交互) -> onResume(可见, 可交互)- 点击back键关闭一个Activity时, 生命周期的过程是: onPause(部分可见, 不可交互) -> onStop(完全不可见) -> onDestory(销毁了)- 当开启一个新的Activity(以对话框形式), 新的activity把后面的activity给盖住一部分时, 后面的activity的生命周期执行的方法是: onPause(部分可见, 不可交互)- 当把新开启的Activity(以对话框形式)给关闭时, 后面的activity的生命周期执行的方法是: onResume(可见, 可交互)- 当开启一个新的activity把后面的activity完全盖住时, 生命周期的方法执行顺序: onPause -> onStop(完全不可见)- 当把新开启的activity(完全盖住)给关闭时, 生命周期的方法执行顺序是: onRestart -> onStart -> onResume(可见, 可交互)- 实际工作中使用的方法 - onResume 可见, 可交互. 把动态刷新的操作启动. - onPause 部分可见, 不可交互. 把动态刷新的一些操作, 给暂停了. - onCreate 初始化一些大量的数据. - onDestory 把数据给释放掉, 节省内存.
横竖屏切换时, 生命周期, 默认情况下会把activity销毁再创建.
不让Activity销毁在创建
4.0以下版本
android:configChanges="orientation|keyboardHidden"
4.0以上版本
android:configChanges="orientation|screenSize"
兼容所有版本
android:configChanges="orientation|keyboardHidden|screenSize"
二、跳转到新的Activity
显式开启: 明确知道并且可以引用的是哪一个Activity类对象
//新建一个意图, 指定跳转到哪一个activity类.
Intent intent = new Intent(MainActivity.this, NewActivity.class);
// 使用意图传递参数(参数类型可以是基本类型和实现序列化接口的类)
Intent.putExtra(“name”, “zhangsan”);
// 开始跳转
startActivity(intent);
隐式开启: 不知道将要跳转的是哪一个类, 无法引用到类. 只知道其动作(action), 类型(mimeType)和附加信息.
// 以下是打开系统中浏览器页面.
Intent intent = new Intent();
intent.setAction(“android.intent.action.VIEW”);
intent.addCategory(“android.intent.category.DEFAULT”);
intent.addCategory(“android.intent.category.BROWSABLE”);
intent.setData(Uri.parse(“http://www.baidu.com“));
startActivity(intent);
打开浏览器页面
/*<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>*/Intent intent = new Intent();intent.setAction("android.intent.action.VIEW");intent.addCategory("android.intent.category.BROWSABLE");Uri uri = Uri.parse("http://www.itheima.com");intent.setData(uri);startActivity(intent);
打开系统短信发送的页面
/*<intent-filter> <action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.SENDTO" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="sms" /> <data android:scheme="smsto" /></intent-filter>*/Intent intent = new Intent();intent.setAction("android.intent.action.VIEW");intent.addCategory("android.intent.category.BROWSABLE");Uri uri = Uri.parse("sms:5556");intent.setData(uri);// 使用intent传递数据intent.putExtra("sms_body", "今晚7天假日酒店旁边的肯德基不见不散!!!");startActivity(intent);
三、Intent传递数据
- 可传递类型: 八大基本类型和数组, ArrayList, Bundle数据捆, 序列化接口(javabean)
得到新打开Activity 关闭后返回的数据
如果你想在Activity中得到新打开Activity 关闭后返回的数据,你需要使用系统提供的startActivityForResult(Intent intent, int requestCode)方法打开新的Activity,新的Activity 关闭后会向前面的Activity 传回数据,为了得到传回的数据,你必须在前面的Activity中重写onActivityResult(int requestCode, int resultCode, Intent data)方法:
public class MainActivity extends Activity {
@Override protected void onCreate(Bundle savedInstanceState) {
…….
Button button =(Button) this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){//点击该按钮会打开一个新的Activity
public void onClick(View v) {
//第二个参数为请求码,可以根据业务需求自己编号
startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 1);
}});
}
//第一个参数为请求码,即调用startActivityForResult()传递过去的值
//第二个参数为结果码,结果码用于标识返回数据来自哪个新Activity
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
String result = data.getExtras().getString(“result”));//得到新Activity 关闭后返回的数据
}
} 当新Activity关闭后,新Activity返回的数据通过Intent进行传递,android平台会调用前面Activity 的onActivityResult()方法,把存放了返回数据的Intent作为第三个输入参数传入,在onActivityResult()方法中使用第三个输入参数可以取出新Activity返回的数据。
四、Activity 的启动模式
程序打开时就创建了一个任务栈, 用于存储当前程序的activity.
- 所有的activity属于一个任务栈.
- 一个任务栈包含了一个activity的集合, 去有序的选择哪一个activity和用户进行交互
- 只有在任务栈栈顶的activity才可以跟用户进行交互.
- 任务栈可以移动到后台, 并且保留了每一个activity的状态. 并且有序的给用户列出她们的任务, 而且还不丢失它们状态信息.
退出程序: 把所有的任务栈中所有的activity清除出栈, 任务栈销毁.
问题:
- 用户体验差, 需要点击多次返回才可以把程序退出了.
- 数据冗余, 重复数据太多, 会导致内存溢出的问题(OOM)
在清单文件(AndroidManifest.xml)文件中的activity节点里有个属性android:launchMode就是指定Activity的启动模式. 其默认为标准模式(standard), 以下是四种模式:
Activity的启动模式, 在activity节点里指定launchMode的属性.
standard 标准模式(activity的默认模式), 导致上面的问题出现.
singleTop 单一顶部模式: 如果一个activity的实例已经存在当前任务栈的栈顶, 系统会发送一个Intent给那个实例的onNewIntent方法.
应用场景: 防止别的程序恶意打开我们的页面.singleTask 单一任务栈模式: 如果activity的实例已经存在任务栈中, 系统就不会创建一个新的实例, 而是调用那个实例的onNewIntent方法, 并且把那个已经存在的activity实例以上所有的activity给清除出栈, 把自己变成栈顶的效果.
应用场景: 商品列表 -> 商品详情 -> 图片详情 -> 大图查看 想从大图查看立刻回到商品列表, 并且把后面开启的三个页面关闭时.singleInstance 单一实例模式: 系统会创建一个新的任务栈把activity的实例放在新的任务栈的栈顶(栈底), 其他的activity页面不会在这个任务栈中创建实例.
如果activity的实例已经存在, 系统会调用那个实例的onNewIntent方法.
应用场景: 在整个系统中只需要初始化一次的界面.
案例:人品计算器
public class MainActivity extends Activity { private EditText etName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etName = (EditText) findViewById(R.id.et_name); } /** * 开始计算人品 * @param v */ public void startCalc(View v) { String name = etName.getText().toString().trim(); Intent intent = new Intent(this, RPCalcActivity.class); intent.putExtra("name", name);// startActivity(intent); startActivityForResult(intent, 100); } /** * 当被开启的页面回传数据时出发此方法 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == 100 && resultCode == 200) { String text = data.getStringExtra("rpText"); Toast.makeText(this, text, 0).show(); } }}
public class RPCalcActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setTextSize(20); tv.setTextColor(Color.RED); setContentView(tv); // 当前Activity显示的是一个空白的TextView // 接收姓名 Intent intent = getIntent(); String name = intent.getStringExtra("name"); String text = "姓名: " + name; // 计算人品值 byte[] bytes = name.getBytes(); int rpCode = 0; for (byte b : bytes) { rpCode += b; } System.out.println("人品值为: " + rpCode); rpCode = Math.abs(rpCode) % 101; // 769 101 % 101 = 0 if("李印东".equals(name)) { rpCode = 100; } text = text + "\n人品得分: " + rpCode; // 人品评价信息 String rpText = getRPText(rpCode); text = text + "\n评价: " + rpText; tv.setText(text); Intent data = new Intent(); data.putExtra("rpText", rpText); // 此方法设置的是返回给调用当前activity的那个界面的数据, 不是立刻返回, 而是等待当前activity销毁才去传回去. setResult(200, data); } /** * 根据给定的人品值, 获取对应的人品评价信息 * @param rp * @return */ private String getRPText(int rp) { String rpText = null; if (rp == 0) { rpText = "你一定不是人吧?怎么一点人品都没有?!"; } else if (rp > 0 && rp <= 5) { rpText = "算了,跟你没什么人品好谈的..."; } else if (rp > 5 && rp <= 10) { rpText = "是我不好...不应该跟你谈人品问题的..."; } else if (rp > 10 && rp <= 15) { rpText = "杀过人没有?放过火没有?你应该无恶不做吧?"; } else if (rp > 15 && rp <= 20) { rpText = "你貌似应该三岁就偷看隔壁大妈洗澡的吧..."; } else if (rp > 20 && rp <= 25) { rpText = "你的人品之低下实在让人惊讶啊..."; } else if (rp > 25 && rp <= 30) { rpText = "你的人品太差了。你应该有干坏事的嗜好吧?"; } else if (rp > 30 && rp <= 35) { rpText = "你的人品真差!肯定经常做偷鸡摸狗的事..."; } else if (rp > 35 && rp <= 40) { rpText = "你拥有如此差的人品请经常祈求佛祖保佑你吧..."; } else if (rp > 40 && rp <= 45) { rpText = "老实交待..那些论坛上面经常出现的偷拍照是不是你的杰作?"; } else if (rp > 45 && rp <= 50) { rpText = "你随地大小便之类的事没少干吧?"; } else if (rp > 50 && rp <= 55) { rpText = "你的人品太差了..稍不小心就会去干坏事了吧?"; } else if (rp > 55 && rp <= 60) { rpText = "你的人品很差了..要时刻克制住做坏事的冲动哦.."; } else if (rp > 60 && rp <= 65) { rpText = "你的人品比较差了..要好好的约束自己啊.."; } else if (rp > 65 && rp <= 70) { rpText = "你的人品勉勉强强..要自己好自为之.."; } else if (rp > 70 && rp <= 75) { rpText = "有你这样的人品算是不错了.."; } else if (rp > 75 && rp <= 80) { rpText = "你有较好的人品..继续保持.."; } else if (rp > 80 && rp <= 85) { rpText = "你的人品不错..应该一表人才吧?"; } else if (rp > 85 && rp <= 90) { rpText = "你的人品真好..做好事应该是你的爱好吧.."; } else if (rp > 90 && rp <= 95) { rpText = "你的人品太好了..你就是当代活雷锋啊..."; } else if (rp > 95 && rp <= 99) { rpText = "你是世人的榜样!"; } else if (rp == 100) { rpText = "天啦!你不是人!你是神!!!"; } else { rpText = "你的人品竟然负溢出了...我对你无语.."; } return rpText; }}
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之 Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之 activity
- 四大组件之Activity
- IDEA热部署(一)---解析关键配置。
- 分布式系统一致性
- Android 混淆提示 java.io.FileNotFoundException: ...\proguard-rules\release\aapt_rules.txt (系统找不到指定的路径)
- ELK(一)Logstash
- java list分页
- 四大组件之Activity
- 求a的b次幂的最后3位(难度:1颗星)
- Hadoop学习笔记 --- HDFS架构笔记
- Fragment抛出java.lang.IllegalStateException: Fragment not attached to Activity
- 沉浸布局的使用以及简单的设置,简单无脑
- windows下编译Matconvnet的方法(CPU和GPU)
- 我也说说Emacs吧(2)
- Thinkphp 3.2.3 开发基础
- Table ‘phpmyadmin.pma_table_uiprefs’ doesn’t exist mysql