Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Activity 基礎詳解

Android Activity 基礎詳解

編輯:關於Android編程

活動(Activity)是一種可以包含用戶界面的組件,主要用和用戶進行交互。一個應用程序中可以包含零個或多個活動。

1.活動的基本用法

首先我們創建一個工程。命名為TestActivity。

\

然後一直點擊下一步會到以下界面。

\

因為這個時候系統默認想要為我們創建一個命名為MainActivity的活動,並加載了布局activity_main.xml。我們不去更改它,建立完成之後進去看它的代碼,我們就知道怎麼回事了。(下面的代碼為了讓讀者看到路徑更好的理解活動,我將會放出圖片)

\

這就是一個活動的代碼部分,首先新建一個活動類並讓其繼承Activity,然後在其中重寫onCreate()方法進行初始化,最後通過setContentView()來加載一個布局。

\

這就是我們所加載的布局,布局通常放在res下的layout文件包下。

\

當然,作為安卓的四大組件,活動想要正常使用自然是需要在AndroidManifest.xml中注冊(11-17行代碼)的。如果想要在程序啟動時候首先跳轉到該活動,就需要寫入圖中12-16行代碼的聲明。

然後是幾個知識點:

A)隱藏標題欄,只需要在加載布局之前,寫入requestWindowFeature(WINDOW.FEATRUE_NO_TITLE)即可。

B)Toast提醒方式,在程序中使用它可以將一些短小的信息提示給用戶,這些信息存在一段時間後會自動消失。寫入Toast.makeText(Context, " ", Toast.LENGTH_SHORT).show即可。這個方法實際上傳入的是三個參數:第一個是上下文Context;第二個是想要顯示的文本內容;第三個是顯示的時常長,內置的常量除了我們寫出的Toast.LENGTH_SHORT還有Toast.LENGTH_LONG。然後調用show()就可以將Toast顯示在屏幕上了。

C)菜單的使用,由於手機使用情況跟電腦不同,它只有很小的一個屏幕,而且很有可能由於某種需求,我們的活動上必須顯示大量的菜單列表,這時候為了避免占用屏幕我們可以采用菜單方式來實現。由於在編寫軟件的過程中我們可能涉及到大量的菜單,因此我們可以新建一個文件夾專門用來放菜單(就像布局那樣)。所以在res下新建一個menu文件夾,然後在裡面創建我們的第一個菜單布局。如下圖所示:

\

然後我們需要在活動中去實現如下代碼:

 

package company.testactivity;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.add_item:
                Toast.makeText(MainActivity.this, "Add Selected", Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove_item:
                Toast.makeText(MainActivity.this, "Remove Selected", Toast.LENGTH_LONG).show();
                break;
            default:
        }
        return true;
    }
}

 

首先通過重寫構造方法onCreateOptionMenu()來創建菜單,通過getMenuInflater得到MenuInflater對象,在調用它的inflate方法就可以給當前活動創建菜單了。緊接著,我們為菜單定義一個點擊事件,表示我們這個菜單不是“只可遠觀不可亵玩”的,同時應用了剛才所提到的Toast方法。

\\

D)銷毀一個活動。想要通過代碼銷毀一個活動時,只需要寫入finish()方法即可。

 

 

2.Intent在活動中的使用

Intent為意圖的意思,這很形象的描述了它的作用,而它主要分為顯式和隱式兩種。

我們先來看顯式Intent。

首先新建一個活動,並加載一個布局,前面已經講述過方法了,記得注冊就好,不再贅述。重點來看主活動中的代碼:

 

package company.testactivity;

    import android.content.Intent;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;

    public class MainActivity extends AppCompatActivity {

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

            Button mButton = (Button) findViewById(R.id.explicit_intent);
            mButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    String data = "this is a extra information from MainActivity";
                    Intent explicitIntent = new Intent(MainActivity.this, AnotherActivity.class);
                    explicitIntent.putExtra("extra data", data);
                    startActivity(explicitIntent);
                }
            });
        }
    .
    .
    .    
    }

 

我們增添了一個按鈕,然後為其設置了一個點擊事件。在點擊邏輯中寫入了Intent相關的東西。首先new一個explicitIntent實例,裡面傳入兩個參數:當前活動和目標活動。通過startActivity(explicitIntent)方法即可實現由一個活動跳轉到另一個活動的操作。只不過我們這裡一並演示了跳轉過程中攜帶信息,這是Intent很重要的一個功能。通過putExtra()方法來實現,傳入兩個參數:信息的名稱和信息的內容。

 

package company.testactivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

/**
 * Created by samyang on 2016/9/12.
 */
public class AnotherActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.another_activity);
        Intent intent = getIntent();
        String data = intent.getStringExtra("extra data");
        Toast.makeText(AnotherActivity.this, data, Toast.LENGTH_LONG).show();
    }
}

 

然而目標活動想要接收傳過來的信息需要調用getIntent()方法來獲取從第一個活動傳過來的意圖實例,然後利用該實例調用getStringExtra()方法並傳入信息名稱來拿到信息,這裡我們還是通過Toast作一個簡單的演示。

\\

這裡簡單提一下,布局都很簡單,左邊是放了一個TextView,下面放了一個Button;右邊僅放了一個TextView。代碼就不放出來了,接下來的簡單部分亦是。

接下來看隱式Intent

隱式Intent並不直接指定想要跳轉的活動,而是指定一系列更為抽象的及信息,然後交給系統去分析這個intent從而判斷想要啟動的活動。我在在標簽中指定活動可以響應的action,而則包含了一些附加信息,用於更精確的匹配響應。只有及能夠同時匹配Intent中指定的action及category時這個活動才能相應Intent。核心代碼為:

 


      

 

 


Button maButton = (Button) findViewById(R.id.implicit_intent); maButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent implicitIntent = new Intent("company.testactivity.ACTION_START"); implicitIntent.addCategory("android.intent.category.MY_CATEGORY"); startActivity(implicitIntent); } });
點擊新加入的按鈕之後跳轉到ThirdActivity如下圖所示:

 

\

除此之外,隱式的Intent還有更多用處。例如:可以啟動其它程序的活動,這使得Android中的多個軟件共享成為了可能。

返回數據

在演示顯式Intent的時候我們使用到了將數據傳送給下一個活動,那麼自然還有將數據返回給上一個活動這一操作。此時你查閱文檔可以知道,返回上一個活動按一下back即可,但是並沒有用於啟動活動Intent來傳遞數據的,不過Activity提供了一個startActivityForResult()方法,並且它期望在活動銷毀時返回一個數據給上一個活動,那麼用它肯定可以實現我們想要的操作。 更改explicitButton按鈕的點擊邏輯如下:
Button mButton = (Button) findViewById(R.id.explicit_intent);
mButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String data = "this is a extra information from MainActivity";
        Intent explicitIntent = new Intent(MainActivity.this, AnotherActivity.class);
        explicitIntent.putExtra("extra data", data);
        startActivityForResult(explicitIntent, 1);
    }
});
startActivityForResult()方法接收兩個參數:第一個還是Intent;第二個是請求碼,用於在之後的回調用判斷數據的來源。 在跳轉的活動中添加一個按鈕,其中邏輯如下:
Button backButton = (Button) findViewById(R.id.back_button);
backButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent1 = new Intent();
        intent1.putExtra("data return", "Hello MainActivity");
        setResult(RESULT_OK, intent1);
        finish();
    }
});
這裡又構建了一個Intent,但它沒有任何“意圖”,僅僅用來存放要返回的數據。然後調用了setResult()方法,該方法很重要,專門用於向上一個活動返回數據。其中傳入兩個參數:第一個是活動返回處理結果,一般只傳RESULT_OK或RESULT_CANCELED;第二個就是帶有要返回數據的Intent對象。然後調用finish()銷毀當前活動。 在MainActivity中重寫onActivityResult構造方法如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case 1:
            if (resultCode == RESULT_OK){
                String returnedData = data.getStringExtra("data return");
                Toast.makeText(MainActivity.this, returnedData, Toast.LENGTH_SHORT).show();
            }
            break;
        default:
    }
}
返回到了上一個活動之後,我們想要接收返回的數據必須要重寫onActivityResult構造方法,它帶有三個參數:第一個為requestCode即我們在啟動活動時傳入的請求碼;第二個為resultCode即返回數據時傳入的處理結果;第三個為data即攜帶著返回數據的intent。因此我們首先需要通過requestCode判斷數據來源,然後通過resultCode判斷處理結果是否成功,最後拿出數據。 當然,我們這裡采用的是按鈕點擊事件調用finish()方法銷毀的活動。我們一樣可以吧這段點擊邏輯放在onBackPressed()方法中,這樣通過back鍵就可以達到相同的效果了。    

3.活動的生命周期

實際上Android是通過任務(task)來管理活動的,一個任務就是一組存放在棧裡的活動集合,這個棧也被稱為返回棧(Back Stack),棧是一種先進後出的數據結構,采用下圖來幫助理解:

\

而關於活動的生命周期,我們需要知道,每個活動在其生命周期內最多可能會有四種狀態:

a)運行狀態:當一個活動處於返回棧的棧頂時,就處於運行狀態,這種狀態的活動是系統最不願意回收,因為這會帶來極差的用戶體驗。

b)暫停狀態:當一個活動不在處於棧頂但仍然可見時就會進入這種狀態。處於暫停狀態的活動仍然是完全存活的,系統也不願意回收這樣的活動,只有在內存極低的時候才會考慮去回收這樣的活動。

c)停止狀態:當一個活動不在處於棧頂位置,並且完全不可見,就進入了停止狀態。此時系統仍然為這種活動保留了成員變量,但是由於當其他地方需要更多內存時會回收這種活動,所以這種狀態下保存的數據並不可靠。

d)銷毀狀態:當一個活動從返回棧中移除了之後就變成這種狀態,系統最願意回收這種狀態的活動。

而生命周期的七種回調方法在理解上述四種狀態之後再結合下圖就可以很好的理解了。

\ 另外你還需要知道對於活動的一種劃分方式,除了onRestart()方法外,其他六種方法是兩兩對應並可劃分如下: a)完整生存期:活動在onCreate()方法和onDestory()方法之間所經歷的,一般情況下,一個活動會在onCreate()時完成各種初始化操作,在onDestory()時釋放內存。 b)可見生存期:活動在onStart()方法和onStop()方法之間所經歷的,在可見生存 期內,活動對於用戶總是可見的,即便有可能無法和用戶進行交互。我們可以通過這兩 個方法,合理地管理那些對用戶可見的資源。比如在 onStart()方法中對資源進行加載,而在onStop()方法中對資源進行釋放,從而保證處於停止狀態的活動不會占用過多內存。 c)前台生存期:活動在 onResume()方法和 onPause()方法之間所經歷的,在前台生存期內,活動總是處於運行狀態的,此時的活動是可以和用戶進行相互的,我們平時看到和接觸最多的也這個狀態下的活動。    

4.活動被回收了怎麼辦

當我們的臨時數據還存放在活動中,可活動被回收了怎麼辦?這樣的情況明顯是常常會遇見的。查閱文檔可以發現Activity提供了一個onSaveInstanceState()回調方法,這個方法可以保證活動在回收前一定可以調用。所以我們可以利用這個方法,在活動被銷毀前,將一些我們期望保留的數據保存下來。
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    String tempData = "Something you want to save";
    outState.putString("data key", tempData);
}
可以看到onSaveInstanceState()攜帶了一個Bundle類型的參數,Bundle類提供了一系列的方法用於保存數據,每個保存方法需要傳入兩個參數:取出數據時用到的鍵值和數據對象。 然後取出的數據可以在onCreate中去恢復,因為它也有一個Bundle類型參數,這個參數在一般情況下都是 null,但是當活動被系統回收之前有通過 onSaveInstanceState()方法來保存數據的話,這個參數就會帶有之前所保存的全部數據,我們只需對Bundle對象調用getString()方法並傳入保存時寫入的鍵值即可,當然我們在取出數據之前最好先判斷一下Bundle對象是否為空。  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved