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

    }


}

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<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保存数据

不想写了。。。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,394评论 25 707
  • 【Android Activity】 什么是 Activity? 四大组件之一,通常一个用户交互界面对应一个 ac...
    Rtia阅读 3,793评论 3 18
  • 羊卓雍措 文/闫殿才 在羊湖,天和山,将一湖的雪水 尽情渲染。 游人鼎沸。湖边落尽姿态 相机和手机都很累 拉伸着各...
    闫殿才阅读 1,195评论 11 37
  • 在一个寒冷的春天的夜晚,一位母亲在收拾家里的旧物。当她看到一双红色的鞋子时,她把它挑了出来。因为她发现这双去年买给...
    过路的蜻蜓阅读 633评论 0 3
  • 1.六个错误学习方法 1.听力时长少,材料难度高 母语学习法:会说话之前,听了至少1000小时,所听的内容从快到慢...
    王侦阅读 2,669评论 0 3