2018-06-06-Activity

Activity

Activity簡(jiǎn)介

四大組件之一,在應(yīng)用中一個(gè)Actvity可以用來表示一個(gè)界面,意思為“活動(dòng)”,代表Activity組件啟動(dòng),活動(dòng)結(jié)束,代表一個(gè)Activity的生命周期結(jié)束。一個(gè)android應(yīng)用必須通過Activity來運(yùn)行和開始。Activity的生命周期交給系統(tǒng)同一管理。

  • Application
  • Activity
  • Activity棧
  • Task:一個(gè)Activity棧對(duì)應(yīng)一個(gè)任務(wù)

Activity的狀態(tài)

在Android中,Activity擁有三個(gè)基本的狀態(tài):

1.Resumed :一個(gè)新的Activity啟動(dòng)入棧后,它在屏幕最前端,處于棧的最頂端,此時(shí)他處于可見并且可以和用戶交互的激活狀態(tài)
2.Paused :當(dāng)Avtivity被另一個(gè)透明或者Dailog樣式的Activity覆蓋時(shí)的狀態(tài)。此時(shí)它依然與窗口管理器保持連續(xù),系統(tǒng)繼續(xù)維護(hù)其內(nèi)部的狀態(tài),所以它任然可見,但是它失去了焦點(diǎn),故不可和用戶交互。
3.Stop :當(dāng)Activity被另一個(gè)Activity覆蓋、失去焦點(diǎn)并不可見時(shí)處于Stop狀態(tài)。

Activity有七個(gè)基本的方法:

/**
 * Activity的三個(gè)狀態(tài)和七個(gè)生命狀態(tài)分析
 */
public class MainActivity extends Activity {

    /**
     * 當(dāng)前Activity被銷毀時(shí)調(diào)用,通常在該方法中釋放資源,當(dāng)前Activity被kill
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.out.println("MainActivity--onDestory");
    }


    /**
     * 當(dāng)其他Activity(透明或窗口模式時(shí))進(jìn)入時(shí),該方法會(huì)被調(diào)用,讓當(dāng)前Activity進(jìn)入Paused狀態(tài)(暫停狀態(tài))
     * 當(dāng)前Activity任然可見但是不可與用戶交互
     * 如果其他更高優(yōu)先級(jí)的APP需要內(nèi)存時(shí),當(dāng)前Activity,當(dāng)前ACtivity可能會(huì)被kill
     * 當(dāng)前Activity被返回時(shí),會(huì)調(diào)用onResume
     * */
    @Override
    protected void onPause() {
        super.onPause();
        System.out.println("MainActivity--onPause");
    }

    /**
     * 在onstart方法后調(diào)用,該方法執(zhí)行完成后,用戶科技進(jìn)行交互,當(dāng)前Activity進(jìn)入Resumed狀態(tài)
     * 當(dāng)一個(gè)paused狀態(tài)的Activity被重新返時(shí),會(huì)再次調(diào)用該方法,讓Activity進(jìn)入運(yùn)行狀態(tài)
     *
     */
    @Override
    protected void onResume() {
        super.onResume();
        System.out.println("MainActivity--onResume");
    }

    /**
     * 當(dāng)一個(gè)Stopped狀態(tài)的Activity被返回后調(diào)用,之后調(diào)用onStart方法,進(jìn)入運(yùn)行狀態(tài)
     */
    @Override
    protected void onRestart() {
        super.onRestart();
        System.out.println("MainActivity--onRestart");
    }

    /**
     * 在onCreate方法之后調(diào)用,用于顯示界面但能和用戶交互
     */
    @Override
    protected void onStart() {
        super.onStart();
        System.out.println("MainActivity--onStart");
    }


    /**
     * 當(dāng)其他Activity完全覆蓋該Activity時(shí),會(huì)被調(diào)用,當(dāng)前Activity進(jìn)入Stopped進(jìn)入停止?fàn)顟B(tài)不可見
     * 如果其他更高優(yōu)先級(jí)的APP需要內(nèi)存時(shí),當(dāng)前Activity,當(dāng)前ACtivity可能會(huì)被kill
     * 當(dāng)前Activity被返回時(shí),會(huì)調(diào)用onRestart方法
     */
    @Override
    protected void onStop() {
        super.onStop();
        System.out.println("MainActivity--onStop");
    }

    /**
     * Activity創(chuàng)建時(shí)第一個(gè)被調(diào)用的方法,
     * 通常在該方法中加載布局文件,初始化UI組件,事件注冊(cè)等等
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        System.out.println("MainActivity--onCreate");

    }


}

Activity生命周期

Activity傳遞數(shù)據(jù)

在Android中,不同的Activity實(shí)例可能運(yùn)行在一個(gè)進(jìn)程中,也可能運(yùn)行在不同的進(jìn)程。因此我們需要一種特殊的機(jī)制,幫助我們?cè)贏ctivity之間傳遞消息。Android中通過Intent對(duì)象來表示一條消息,一個(gè)Intent消息不僅包含這個(gè)消息的目的地,還可以包含消息的內(nèi)容,這好比一封Email,其中不僅包含該手賤地址,還可以包含具體的內(nèi)容,對(duì)于一個(gè)Intent對(duì)象,消息“目的地”是必須的,而內(nèi)容則是可選項(xiàng)。

通過Intent來啟動(dòng)一個(gè)Activity

//通過反射機(jī)制,獲取字節(jié)碼
        //創(chuàng)建意圖,參數(shù):上下文,要跳轉(zhuǎn)的組件的字節(jié)碼
        Intent intent = new Intent(this,MainActivityB.class);
        
        //啟動(dòng)一個(gè)Activity
        startActivity(intent);

在上面的實(shí)例中通過Activity.StartActivity(intent)啟動(dòng)另外一個(gè)Activity的時(shí)候,我們?cè)贗ntent類的構(gòu)造器中指定了“收件人的地址”

**傳遞數(shù)據(jù)的兩種方式:

  1. 直接通過Bundle對(duì)象來傳遞:**

第一個(gè)Activity發(fā)送數(shù)據(jù)

//通過反射機(jī)制,獲取字節(jié)碼
        //創(chuàng)建意圖,參數(shù):上下文,要跳轉(zhuǎn)的組件的字節(jié)碼
        Intent intent = new Intent(this,MainActivityB.class);
        //封裝要傳遞的數(shù)據(jù)
        //通過Bundle傳遞數(shù)據(jù),是HashMap的一個(gè)封裝類
        Bundle data = new Bundle();
        data.putString("info",info);

        //Bundle數(shù)據(jù)放入Intent
        intent.putExtra("data",data);

第二個(gè)Activity接收數(shù)據(jù)

        //獲取Intent,不是同一個(gè)Intent但是同樣的內(nèi)容
        Intent intent = getIntent();
        //獲取Bundle
        Bundle data = intent.getBundleExtra("data");
        //從Bundle中取數(shù)據(jù)
        String info = data.getString("info");

2. 通過Intent定義的Bundle對(duì)象

第一個(gè)Activity發(fā)送數(shù)據(jù)

//通過反射機(jī)制,獲取字節(jié)碼
        //創(chuàng)建意圖,參數(shù):上下文,要跳轉(zhuǎn)的組件的字節(jié)碼
        Intent intent = new Intent(this,MainActivityB.class);
        
        intent.putExtra("info",info);

第二個(gè)Activity接收數(shù)據(jù)

Intent intent = getIntent();
String info = intent.getStringExtra("info");

傳遞自定義的對(duì)象數(shù)據(jù)

方法一:序列化對(duì)象

自定義的對(duì)象,必須繼承接口Serializable

//序列化對(duì)象,通過I/O傳輸,存儲(chǔ)文件或者對(duì)象進(jìn)行傳輸。
//這里可能是兩個(gè)進(jìn)程傳數(shù)據(jù),相當(dāng)于通過網(wǎng)絡(luò)傳輸,需要序列化
public class Cat implements Serializable {
    String name;
    int age;
    String type;

    @Override
    public String toString() {
        return "Cat{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", type='" + type + '\'' +
                '}';
    }
}

發(fā)送數(shù)據(jù)

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

接收數(shù)據(jù)

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();
     }
 }


自定義的對(duì)象


/**
 * 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);
    }

    //對(duì)象的創(chuàng)建器,解包成要的對(duì)象
    public static final Parcelable.Creator<Dog> CREATOR
            = new Parcelable.Creator<Dog>() {
        public Dog createFromParcel(Parcel in) {
            Dog dog = new Dog();
            //讀取對(duì)象內(nèi)容,需要和上面的寫的順序一致
            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 + '\'' +
                '}';
    }
}

發(fā)送數(shù)據(jù):

Dog dog = new Dog();
        dog.name="大黃";
        dog.age = 1;
        dog.type = "中華田園犬";

        Intent intent = new Intent(this,MainActivityB.class);
        intent.putExtra("dog",dog);

        startActivity(intent);

接收數(shù)據(jù)

Dog dog = intent.getParcelableExtra("dog");

Activity處理返回結(jié)果

Android提供了一個(gè)機(jī)制,跳轉(zhuǎn)到其他Activity時(shí),在返回,可以接收到其他的activity返回的值,無需再start新的當(dāng)前activity值;

A發(fā)送數(shù)據(jù):startActivityForResult(intent, REQUESTCODE_1);
B接受數(shù)據(jù),設(shè)置返回結(jié)果:setResult(RESULT_OK,intent);
A重寫方法處理返回結(jié)果

@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);
        }

    }

通過請(qǐng)求狀態(tài)碼和結(jié)果狀態(tài)碼,區(qū)分不同的結(jié)果

Activity運(yùn)行時(shí)屏幕方向與顯示方式

Android內(nèi)置了方向感應(yīng)器的支持。Android會(huì)根據(jù)所處的方向自動(dòng)在豎屏和橫屏之間切換。但是有時(shí)我們的程序僅僅能在橫屏和豎屏?xí)r運(yùn)行,比如某些游戲,此時(shí)我們需要鎖定該Activity運(yùn)行時(shí)的屏幕方向,Activity結(jié)點(diǎn)的android:screenOrientation屬性可以完成該項(xiàng)任務(wù)。

以下是一個(gè)示例:
修改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>

代碼設(shè)置,需要在setContentView之前


public class ScreenOrientstion extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //設(shè)置豎屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
        //設(shè)置全屏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //去自己的標(biāo)題
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_screen_orientstion);

    }

}

還可以設(shè)置窗體模式等。

Activity屏幕方向的旋轉(zhuǎn)

屏幕切換時(shí),會(huì)重新創(chuàng)建Activity,此時(shí)為了保存當(dāng)前的Activity的狀態(tài)。Activity狀態(tài)沒有保存,切換時(shí)會(huì)會(huì)調(diào)用onSaveInstanceState(Bundle outState),應(yīng)該重寫onSaveInstanceState(Bundle outState)方法,然后在onCreate中還原數(shù)據(jù)

重寫方法

 @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("index",index);
    }

切換屏幕后會(huì)執(zhí)行onCreate方法

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_screen_orientstion);

        if(savedInstanceState != null){
            index = savedInstanceState;
        }
    }

每次切換屏幕重新創(chuàng)建Activity會(huì)影響性能,可以在manifest文件中添加屬性android:configChanges="keyboard|orientation|screenSize",屏幕切換時(shí)調(diào)用onConfigurationChanged方法,使用了原來的Activity,不用保存對(duì)象了。此方法可以用來加載布局。

Activity通過SharePreference保存數(shù)據(jù)

不想寫了。。。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,209評(píng)論 25 708
  • 【Android Activity】 什么是 Activity? 四大組件之一,通常一個(gè)用戶交互界面對(duì)應(yīng)一個(gè) ac...
    Rtia閱讀 3,942評(píng)論 3 18
  • 羊卓雍措 文/閆殿才 在羊湖,天和山,將一湖的雪水 盡情渲染。 游人鼎沸。湖邊落盡姿態(tài) 相機(jī)和手機(jī)都很累 拉伸著各...
    閆殿才閱讀 1,230評(píng)論 11 37
  • 在一個(gè)寒冷的春天的夜晚,一位母親在收拾家里的舊物。當(dāng)她看到一雙紅色的鞋子時(shí),她把它挑了出來。因?yàn)樗l(fā)現(xiàn)這雙去年買給...
    過路的蜻蜓閱讀 741評(píng)論 0 3
  • 1.六個(gè)錯(cuò)誤學(xué)習(xí)方法 1.聽力時(shí)長少,材料難度高 母語學(xué)習(xí)法:會(huì)說話之前,聽了至少1000小時(shí),所聽的內(nèi)容從快到慢...
    王偵閱讀 2,791評(píng)論 0 3

友情鏈接更多精彩內(nèi)容