Activity
Activity简介
四大组件之一,在应用中一个Actvity可以用来表示一个界面,意思为“活动”,代表Activity组件启动,活动结束,代表一个Activity的生命周期结束。一个android应用必须通过Activity来运行和开始。Activity的生命周期交给系统同一管理。
- Application
- Activity
- Activity栈
- Task:一个Activity栈对应一个任务
Activity的状态
在Android中,Activity拥有三个基本的状态:
1.Resumed :一个新的Activity启动入栈后,它在屏幕最前端,处于栈的最顶端,此时他处于可见并且可以和用户交互的激活状态
2.Paused :当Avtivity被另一个透明或者Dailog样式的Activity覆盖时的状态。此时它依然与窗口管理器保持连续,系统继续维护其内部的状态,所以它任然可见,但是它失去了焦点,故不可和用户交互。
3.Stop :当Activity被另一个Activity覆盖、失去焦点并不可见时处于Stop状态。
Activity有七个基本的方法:
/**
* Activity的三个状态和七个生命状态分析
*/
public class MainActivity extends Activity {
/**
* 当前Activity被销毁时调用,通常在该方法中释放资源,当前Activity被kill
*/
@Override
protected void onDestroy() {
super.onDestroy();
System.out.println("MainActivity--onDestory");
}
/**
* 当其他Activity(透明或窗口模式时)进入时,该方法会被调用,让当前Activity进入Paused状态(暂停状态)
* 当前Activity任然可见但是不可与用户交互
* 如果其他更高优先级的APP需要内存时,当前Activity,当前ACtivity可能会被kill
* 当前Activity被返回时,会调用onResume
* */
@Override
protected void onPause() {
super.onPause();
System.out.println("MainActivity--onPause");
}
/**
* 在onstart方法后调用,该方法执行完成后,用户科技进行交互,当前Activity进入Resumed状态
* 当一个paused状态的Activity被重新返时,会再次调用该方法,让Activity进入运行状态
*
*/
@Override
protected void onResume() {
super.onResume();
System.out.println("MainActivity--onResume");
}
/**
* 当一个Stopped状态的Activity被返回后调用,之后调用onStart方法,进入运行状态
*/
@Override
protected void onRestart() {
super.onRestart();
System.out.println("MainActivity--onRestart");
}
/**
* 在onCreate方法之后调用,用于显示界面但能和用户交互
*/
@Override
protected void onStart() {
super.onStart();
System.out.println("MainActivity--onStart");
}
/**
* 当其他Activity完全覆盖该Activity时,会被调用,当前Activity进入Stopped进入停止状态不可见
* 如果其他更高优先级的APP需要内存时,当前Activity,当前ACtivity可能会被kill
* 当前Activity被返回时,会调用onRestart方法
*/
@Override
protected void onStop() {
super.onStop();
System.out.println("MainActivity--onStop");
}
/**
* Activity创建时第一个被调用的方法,
* 通常在该方法中加载布局文件,初始化UI组件,事件注册等等
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("MainActivity--onCreate");
}
}
Activity传递数据
在Android中,不同的Activity实例可能运行在一个进程中,也可能运行在不同的进程。因此我们需要一种特殊的机制,帮助我们在Activity之间传递消息。Android中通过Intent对象来表示一条消息,一个Intent消息不仅包含这个消息的目的地,还可以包含消息的内容,这好比一封Email,其中不仅包含该手贱地址,还可以包含具体的内容,对于一个Intent对象,消息“目的地”是必须的,而内容则是可选项。
通过Intent来启动一个Activity
//通过反射机制,获取字节码
//创建意图,参数:上下文,要跳转的组件的字节码
Intent intent = new Intent(this,MainActivityB.class);
//启动一个Activity
startActivity(intent);
在上面的实例中通过Activity.StartActivity(intent)启动另外一个Activity的时候,我们在Intent类的构造器中指定了“收件人的地址”
**传递数据的两种方式:
- 直接通过Bundle对象来传递:**
第一个Activity发送数据
//通过反射机制,获取字节码
//创建意图,参数:上下文,要跳转的组件的字节码
Intent intent = new Intent(this,MainActivityB.class);
//封装要传递的数据
//通过Bundle传递数据,是HashMap的一个封装类
Bundle data = new Bundle();
data.putString("info",info);
//Bundle数据放入Intent
intent.putExtra("data",data);
第二个Activity接收数据
//获取Intent,不是同一个Intent但是同样的内容
Intent intent = getIntent();
//获取Bundle
Bundle data = intent.getBundleExtra("data");
//从Bundle中取数据
String info = data.getString("info");
2. 通过Intent定义的Bundle对象
第一个Activity发送数据
//通过反射机制,获取字节码
//创建意图,参数:上下文,要跳转的组件的字节码
Intent intent = new Intent(this,MainActivityB.class);
intent.putExtra("info",info);
第二个Activity接收数据
Intent intent = getIntent();
String info = intent.getStringExtra("info");
传递自定义的对象数据
方法一:序列化对象
自定义的对象,必须继承接口Serializable
//序列化对象,通过I/O传输,存储文件或者对象进行传输。
//这里可能是两个进程传数据,相当于通过网络传输,需要序列化
public class Cat implements Serializable {
String name;
int age;
String type;
@Override
public String toString() {
return "Cat{" +
"age=" + age +
", name='" + name + '\'' +
", type='" + type + '\'' +
'}';
}
}
发送数据
public void sendObjClick(View v){
Cat cat = new Cat();
cat.name = "皮卡丘";
cat.age = 2;
cat.type = "中华田园猫";
Intent intent = new Intent(this,MainActivityB.class);
intent.putExtra("cat",cat);
startActivity(intent);
}
接收数据
Cat cat = (Cat) intent.getSerializableExtra("cat");
方法二:
使用java的序列化消耗太大,所以使用android自己的方法,继承Parcelable接口。
下面是官方文档的介绍和基本使用:
Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a non-null static field called ==CREATOR== of a type that implements the Parcelable.Creator interface.
A typical implementation of Parcelable is:
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
自定义的对象
/**
* Created by TianMengmeng on 2018/6/6.
*/
public class Dog implements Parcelable{
String name;
int age;
String type;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
dest.writeString(type);
}
//对象的创建器,解包成要的对象
public static final Parcelable.Creator<Dog> CREATOR
= new Parcelable.Creator<Dog>() {
public Dog createFromParcel(Parcel in) {
Dog dog = new Dog();
//读取对象内容,需要和上面的写的顺序一致
dog.name = in.readString();
dog.age = in.readInt();
dog.type = in.readString();
return dog;
}
public Dog[] newArray(int size) {
return new Dog[size];
}
};
@Override
public String toString() {
return "Dog{" +
"age=" + age +
", name='" + name + '\'' +
", type='" + type + '\'' +
'}';
}
}
发送数据:
Dog dog = new Dog();
dog.name="大黄";
dog.age = 1;
dog.type = "中华田园犬";
Intent intent = new Intent(this,MainActivityB.class);
intent.putExtra("dog",dog);
startActivity(intent);
接收数据
Dog dog = intent.getParcelableExtra("dog");
Activity处理返回结果
Android提供了一个机制,跳转到其他Activity时,在返回,可以接收到其他的activity返回的值,无需再start新的当前activity值;
A发送数据:startActivityForResult(intent, REQUESTCODE_1);
B接受数据,设置返回结果:setResult(RESULT_OK,intent);
A重写方法处理返回结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUESTCODE_1 && resultCode == RESULT_OK){
String number = data.getStringExtra("number");
edittext.setText(number);
}
}
通过请求状态码和结果状态码,区分不同的结果
Activity运行时屏幕方向与显示方式
Android内置了方向感应器的支持。Android会根据所处的方向自动在竖屏和横屏之间切换。但是有时我们的程序仅仅能在横屏和竖屏时运行,比如某些游戏,此时我们需要锁定该Activity运行时的屏幕方向,Activity结点的android:screenOrientation属性可以完成该项任务。
以下是一个示例:
修改manifes文件
<activity
android:name=".ScreenOrientstion"
android:label="@string/title_activity_screen_orientstion"
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
代码设置,需要在setContentView之前
public class ScreenOrientstion extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
//设置全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//去自己的标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_screen_orientstion);
}
}
还可以设置窗体模式等。
Activity屏幕方向的旋转
屏幕切换时,会重新创建Activity,此时为了保存当前的Activity的状态。Activity状态没有保存,切换时会会调用onSaveInstanceState(Bundle outState),应该重写onSaveInstanceState(Bundle outState)方法,然后在onCreate中还原数据
重写方法
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("index",index);
}
切换屏幕后会执行onCreate方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_orientstion);
if(savedInstanceState != null){
index = savedInstanceState;
}
}
每次切换屏幕重新创建Activity会影响性能,可以在manifest文件中添加属性android:configChanges="keyboard|orientation|screenSize"
,屏幕切换时调用onConfigurationChanged方法,使用了原来的Activity,不用保存对象了。此方法可以用来加载布局。
Activity通过SharePreference保存数据
不想写了。。。