Android四大组件之一——Activity123
来源:互联网 发布:ubuntu安装哪个版本好 编辑:程序博客网 时间:2024/06/05 06:03
Android四大组件之Activity123
Activity是Android最重要也是最常用的组件
一、Activity基本知识
Activity的生命周期
显示状态:onCreate,onStart,onResume
隐藏状态:onPause,onStop
销毁状态:onDestroy
当启动应用时会有如下方法得到执行onCreate-->onStart-->onResume
onStart是可见但不可交互状态
onResume是可见且可交互状态
当点击Back键时会调用onPause-->onStop-->onDestroy(一个Activity从创建到销毁的全过程,onRestart另说)
onPause是不可交互但可见状态
onStop是不可见且不可交互状态
通过Intent启动另一个Activity观察生命周期
需要注意的是点击button后首先执行的是onPause方法,然后创建另一个Activity,当SecondActivity可见时再执行MainActivity的onStop方法。
点击Back键后同理先执行onPause方法,回到MainActivity,因为MainActivity已经有实例,所以执行onRestart方法替代onCreate,之后依然类似,onStart-->onResume,以及SecondActivity的onStop-->onDestroy。
为什么只是先暂停当前Activity,而不是跳转Activity后再执行onPause-->onStop,或者先onPause-->onStop,然后再创建跳转Activity?
1)如果当前的应用是音乐播放器,当有电话打来时,当前的Activity在接听页面显示之前都不会暂停,不符合交互逻辑。
2)同样的例子,电话页面未显示而当前Activity已经stop,则会出现不可见的黑屏状态,直到接听页面创建并显示完成。
Activity横竖屏切换的生命周期
切换横竖屏时会将当前Activity按正常流程Destroy,然后重新创建Activity
切换横竖屏时,如果有输入框之类的控件,则需要保存竖屏时的状态,比如说有输入框之类的控件而且已经有输入内容,此时切到横屏不应该丢失数据,因此需要调用onSaveInstanceState保存状态信息。在onCerate方法中进行判断参数savedInstanceState是否为空
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { Log.i("tag", "MainActivity" + savedInstanceState.getString("libo")); } Log.i("tag", "MainActivity onCreate"); button = (Button) findViewById(R.id.button1); button.setOnClickListener(this); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Log.i("tag", "MainActivity onSaveInstanceState"); outState.putString("libo", "abc"); }
Activity生命周期的应用——音乐播放
onDestroy方法常用作释放资源
private MediaPlayer mediaPlayer;private int position;//在onCreate方法中初始化mediaPlayer = MediaPlayer.create(this, R.raw.ifyou);mediaPlayer.start();//在onPause方法中暂停MediaPlayer,并记录播放进度@Overrideprotected void onPause() { super.onPause(); Log.i("tag", "MainActivity onPause"); if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); position = mediaPlayer.getCurrentPosition(); Log.i("tag", position+""); }} //在onResume方法中读取进度播放@Overrideprotected void onResume() { super.onResume(); Log.i("tag", "MainActivity onResume"); if (position != 0) { mediaPlayer.seekTo(position); Log.i("tag", position+""); mediaPlayer.start(); }}//在onDestroy方法中进行资源的释放@Overrideprotected void onDestroy() { super.onDestroy(); Log.i("tag", "MainActivity onDestroy"); if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; }}
Activity之间的启动方式
显式启动
Intent是Android程序中各组件之间进行交互的一种重要方式,不仅可以指明当前组件想要执行的动作,还可以在不同的组件之间传递数据。一般可被用于启动Activity,启动Service,以及发送广播等。
通过构造Intent,指定需要跳转的Activity。
Intent intent = new Intent(ThirdActivity.this, FourthActivity.class);startActivity(intent);
隐式启动
为将要启动的Activity添加一个Intent过滤器,并指定action标签,指明当前Activity可以响应"libo"这个action。category标签默认为 android.intent.category.DEFAULT,更精确的指明了当前Activity能够响应带有category的Intent。action和category标签内容同时匹配时,这个Activity才能响应。当 category为默认时,可以省略 intent.addCategory() 方法。
<activity android:name="com.example.activity.FourthActivity"> <intent-filter > <action android:name="libo"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
Intent intent = new Intent();intent.setAction("libo");startActivity(intent);隐式启动多用于启动没有源文件的Activity,比如系统的浏览器,拨号,短信等
//打开网页Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);Uri uri = Uri.parse("http://www.qq.com");intent.setData(uri);startActivity(intent);
//打开图库Intent intent = new Intent();intent.setAction(Intent.ACTION_GET_CONTENT);intent.setType("image/*");startActivity(intent);
//发送短信Intent intent = new Intent();intent.setAction(Intent.ACTION_SEND);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_TEXT, "hello csdn");startActivity(intent);
//拨号Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);Uri uri = Uri.parse("tel:666666");intent.setData(uri);startActivity(intent);
以上系统应用可以被调用,网页通过setData方法指定Intent操作的数据。另外,还可以通过Intent-Filter配置Data标签,更精确的指定当前活动可以响应什么类型的操作。
Data标签可以配置如下内容:
1.android:scheme 用于指定数据的协议部分,例如http、geo地理位置、tel拨打电话
2.android:host 用于指定数据的主机名部分,例如www.qq.com
3.android:port 用于指定数据的断口部分,一般紧随主机名之后
4.android:path 用指定主机名和端口之后的部分
5.android:mimeType 用于指定可以处理的数据类型。
更多系统的action可以查阅官方文档
Activity之间的数据传递
向下一个活动传递数据
通过Intent启动另一个Activity时,可以利用Intent携带一定量的具体数据。
具体方法为putExrta。通过键值对的方式。可以传递常用的8种类型及数组,String,int,double等
Intent intent = new Intent(ThirdActivity.this, FourthActivity.class);intent.putExtra("name", "libo");intent.putExtra("age", 21);startActivity(intent);在被启动的Activity中需要先进行getintent,获取启动Intent,然后通过getStringExtra等的函数取出数据
Intent intent = getIntent();if (intent != null) {text.setText(intent.getStringExtra("name") + " " + intent.getIntExtra("age", 0));}
也可以通过Bundle先进行封装,再通过Intent传递
Intent intent = new Intent(ThirdActivity.this, FourthActivity.class);Bundle bundle = new Bundle();bundle.putString("name", "libo");bundle.putInt("age", 21);intent.putExtras(bundle);startActivity(intent);Bundle也可以用于封装对象实例进行传递,不过对象须实现Serializable接口进行序列化(序列化是Java IO中的知识)
public class Person implements Serializable {private String name;private int age;private String address;public Person(String name, int age, String address){this.name = name;this.age = age;this.address = address;}@Overridepublic String toString() {return "name: " + name + "age: " + age + "address: " + address;}}
Intent intent = new Intent(ThirdActivity.this, FourthActivity.class);Person person = new Person("libo", 21, "xian");Bundle bundle = new Bundle();bundle.putSerializable("person", person);intent.putExtras(bundle);startActivity(intent);
Intent intent = getIntent();if (intent != null) {Person person = (Person) intent.getSerializableExtra("person");text.setText(person.toString());}Bundle也可以用于传递图片,但大小不能过大,上限约为0.5M
Intent intent = new Intent(ThirdActivity.this, FourthActivity.class);Bundle bundle = new Bundle();Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);bundle.putParcelable("bitmap", bitmap);intent.putExtras(bundle);startActivity(intent);img.setImageBitmap((Bitmap) intent.getParcelableExtra("bitmap"));当Bundle携带数据量过大时会抛出如下错误
!!! FAILED BINDER TRANSACTION !!!如果需要在另一个Activity中使用本Activity的一些比较大的数据,可以考虑SQLite,或者文件
返回数据给上一个活动
此时启动Activity的方法不是startActivity而是startActivityForResult(Intent intent, int requestCode),request只要保证是唯一值就可以。
Intent intent = new Intent(MainActivity.this, FirstActivity.class);startActivityForResult(intent, 1);
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {switch (requestCode) {case 1:if (resultCode == RESULT_OK) {String str = data.getStringExtra("first");text.setText(str);}break;default:break;}}
Intent intent = new Intent();intent.putExtra("first", "libo");setResult(RESULT_OK, intent);finish();
Activity的启动模式( launchMode)
standard
默认是模式,可以创建条件允许的任意多个
singleTop
如果再次创建的Activity在栈顶,那么就不会再重新创建新Activity,而是执行onNewIntent方法
如果不在栈顶,则跟默认模式相同,还是会再创建新的Activity
singleTask
MainActivity->Activity->MainActivity(MainActivity默认,Activity singleTask),如果此时再启动Activity则会执行第二个MainActivity的onDestroy方法,即在任务栈中进行出栈,直到Activity处于栈顶。
singleInstance
启动Activity时会处于不同的任务栈中
Main1->First->Main2->First->Main3(Main默认模式,First singleInstance),First被启动两次但是只执行一次onCreate方法并创建一个新的任务栈,其余均为onNewIntent方法。
当First启动Main2时,因为是默认模式,则会寻找Task1,并创建Activity,Main3同样,此时显示的是Main3,单击Back键时会返回到Main2,Main1,最后才是First。
Back会先把此栈中的Activity全部出栈,再把Task2中的Activity出栈。
启动活动的最佳写法
启动不是由自己开发的一个Activity,不清楚该Activity需要传递哪些数据,除了查看源码之外,完全可以在Activity创建一个静态方法来提示调用者该Activity的详细信息。
public static void activityStart(Context context, String data1, String data2){Intent intent = new Intent(context, FirstActivity.class);intent.putExtra("data1", data1);intent.putExtra("data2", data2);context.startActivity(intent);}
//启动时,只需一句代码,并且简单完整的传入所需的各个参数FirstActivity.activityStart(this, "abc", "def");
二、深入了解Activity
- Android四大组件之一——Activity123
- Android四大组件之一——广播
- Android四大组件之一——Activity
- Android四大组件之一 ——广播
- Android四大组件之一 ——广播
- Android的四大组件之一——Service
- Android四大组件之一——Broadcast Receiver
- Android——四大组件之一:BroadcastReceiver 广播接收器
- Android 四大组件之一 BroadcastReceiver
- Android 四大组件之一 ContentProvider
- Android 四大组件之一Service
- Android四大组件之一:BroadcastReceiver
- Android 四大组件之一 Service
- Android四大组件之一:Activity
- Android四大组件之一:Service
- Android四大组件之一:BroadcastReceiver
- android 四大组件之一Activity
- Android四大组件之一:Activity
- 成为程序界的叶问,你需要打败这十个人
- Android 可拖拽的GridView效果实现, 长按可拖拽和item实时交换
- redis简单使用方法
- Centos代理上网设置
- Boost 内存管理(smart_ptr库,pool库)
- Android四大组件之一——Activity123
- MyBatis对表CRUD操作_2
- Façade模式--门面模式
- 浮躁的社会,心静者胜出
- [Selenium] selenium webdriver 选择器
- fatal error C1083: 无法打开包括文件:“stdio.h
- UML类图基本用法
- 简单Shader之设置Texture【学习Shader一】
- 支持向量机 SVM 讲义(三)