2018-06-06-Activity

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");

    }


}

2018-06-06-Activity_第1张图片
Activity生命周期

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类的构造器中指定了“收件人的地址”

**传递数据的两种方式:

  1. 直接通过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 CREATOR
             = new Parcelable.Creator() {
         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 CREATOR
            = new Parcelable.Creator() {
        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文件


            
                

                
            
        

代码设置,需要在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保存数据

不想写了。。。

你可能感兴趣的:(2018-06-06-Activity)