1. 程式人生 > >Android-活動(Activity)Intent

Android-活動(Activity)Intent

稍微正常點的應用都應該不只有一個活動,通常都是有成打的活動,然後通過各種事件進行跳轉。連線起各種活動的橋樑,就是所謂的Intent。

什麼是Intent?

Intent是Android用來連線各個元件並且將元件進行j解耦的重要元件,比如指明當前元件的意圖,或者在元件之間傳遞資料。

Intent相當於一個媒婆,為兩個元件牽線搭橋,並且為他們之間的資訊交換提供了渠道。比如,有一個人(Activity)想找個白富美當老婆,他把這個“意圖”寫在了臉上,然後讓媒婆(Intent)去找找看,有沒有這麼個人是符合要求的。媒婆找了找,還真有一個符合條件的人,然後就把這倆人介紹到一起,並且為對方提供他們想了解的資料。

Intent也分為兩種:顯式Intent(點名道姓)和隱式Intent(條件篩選)。我們一個一個說。

顯式Intent

首先上程式碼:

因為我們要實現Activity的跳轉,所以我們要建立兩個活動才行:

 1 public class FirstActivity extends AppCompatActivity  //第一個活動
 2 {
 3 
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState)
 6     {
 7         super.onCreate(savedInstanceState);
8 setContentView(R.layout.activity_main); 9 Button button1 = (Button) findViewById(R.id.button_1); 10 button1.setOnClickListener(new View.OnClickListener() 11 { 12 @Override 13 public void onClick(View v) 14 { 15 Intent intent = new
Intent(FirstActivity.this, SecondActivity.class); 16 startActivity(intent); 17 } 18 }); 19 } 20 }

 

 1 public class SecondActivity extends AppCompatActivity  //第二個活動
 2 {
 3 
 4     @Override
 5     protected void onCreate(Bundle savedInstanceState)
 6     {
 7         super.onCreate(savedInstanceState);
 8         setContentView(R.layout.activity_second);
 9     }
10 }

 

第一個活動對應的佈局檔案:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent">
 4 
 5     <Button
 6         android:id="@+id/button_1"
 7         android:layout_width="wrap_content"
 8         android:layout_height="wrap_content"
 9         android:text="This is Button 1" />
10 </LinearLayout>

 

第二個佈局檔案沒寫什麼,就不放上來了。

我們分析下程式碼:

FirstActivity在Button的點選事件中定義了一個Intent(媒婆),這個Intent有很多建構函式的過載,我們這裡使用的是

Intent(Context packageContext,Class<?> cls);

這裡我們要傳入兩個引數:第一個是這個啟動活動的上下文(上下文的解釋看上一篇),第二個是我們這個Intent的“意圖”,也就是我們這個Intent想跳轉到哪裡。但是我們要注意,第一個傳入的是物件(.this),第二個是.class,傳入類檔案之後,虛擬機器會自動裝載類檔案。

接下來,我們的Intent已經準備妥當,我們還需要去啟動Intent。使用startActivity(Intent intent),傳入我們的Intent就可以發動“媒婆”,啟動目標活動了。

隱式Intent

顯示Intent好比是指明瞭要志玲做老婆,點名道姓,意圖明顯。而隱式Intent,是規定了條件,只有符合條件的才能被我接納。

要想能匹配得上,有兩部分要完全相同:action和category。

廢話不多說,上程式碼,首先是AndroidMainifest.xml(只貼出修改部分)

1 <activity android:name=".SecondActivity">
2     <intent-filter>
3         <action android:name=".ACTION_START" />
4         <category android:name="android.intent.category.DEFAULT" />
5     </intent-filter>
6 </activity>

 我們修改了SecondActivity的標籤,為它加入了action和catagory標籤。action標籤說明了我們這個活動可以響應哪個action。action表明了我們這個活動可以執行的動作,可以使用系統提供的(比如撥號ACTION_CALL),也可以自己定義。這裡我們是自己定義的;catagory包含了更加細節的一些資訊。

然後我們修改FirstActivity.java的程式碼

 1 public class FirstActivity extends AppCompatActivity
 2 {
 3     @Override
 4     protected void onCreate(Bundle savedInstanceState)
 5     {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.activity_main);
 8         Button button1 = (Button) findViewById(R.id.button_1);
 9         button1.setOnClickListener(new View.OnClickListener()
10         {
11             @Override
12             public void onClick(View v)
13             {
14                 Intent intent = new Intent(".ACTION_START");
15                 startActivity(intent);
16             }
17         });
18     }
19 }

 

我們修改了Intent的建構函式,直接傳入了action的字串,表明我們想啟動能響應.ACTION_START這個action的活動。但是,我們在這裡並沒有出現於category的相關宣告,是怎麼回事呢?

因為我們給SecondActivity傳入的是"android.intent.category.DEFAULT"這個引數,這是一個預設的catgory,在我們startActivity時會自動呼叫這個引數到我們的intent中。

我們啟動程式,效果與剛才的是一樣的。

當然,我們也可以指定多個category,但是隻能有一個action。

1 intent.addCategory(".MY_CATEGORY1");
2 intent.addCategory(".MY_CATEGORY2");

 

這樣就可以為我們的intent新增category了。

但是我們的所有活動裡面必須有一個是能響應你這個intent的,否則程式會崩潰。

 

隱式Intent的更多用法

我們在平時使用別人家的app時一定有過這樣的體驗:點選一個連結,系統會提示你選擇哪一個瀏覽器開啟網頁。這些動作都是通過Intent來完成的。接下來我們看看Intent還有什麼新玩法。

修改程式碼如下:

1 @Override
2 public void onClick(View v)
3 {
4     Intent intent = new Intent(Intent.ACTION_VIEW);
5     intent.setData(Uri.parse("http://www.baidu.com"));
6     startActivity(intent);
7 }

我們這裡傳入的是"ACTION_VIEW"這個action,這是一個系統內建的action。然後我們呼叫intent的setData方法。這個方法是用來指定我們當前Intent操作的資料,它的引數是一個Uri物件。所以我們裡面使用Uri.parse來將一個網址解析成為了一個Uri物件(parse,分析的意思)。然後我們重新執行程式:

 

 

可以看到我們的程式成功響應了我們的請求,打開了我們指定的網頁。

 那我們的程式能不能響應開啟網頁的請求呢?我們只要在相應的activity標籤中去新增屬性就可以了。

修改AndroidManifest.xml如下:

1  <activity android:name=".SecondActivity">
2      <intent-filter tools:ignore="AppLinkUrlError">
3          <action android:name="android.intent.action.VIEW" />
4          <category android:name="android.intent.category.DEFAULT" />
5          <data android:scheme="http" />
6      </intent-filter>
7  </activity>

 

我們修改了SecondActivity的屬性,讓他能響應所有http協議的網址。並且修改了action為系統內建的action,它能響應Intent.ACTION_VIEW,也就是我們剛才傳入的那個值。

我們還能指定的data有:

android:scheme   指定資料的協議,如http;

android:host        指定資料的主機名,如www.baidu.com

android:port         指定埠,比如:8080,:80

還有很多,不常用的就不寫在這裡了。

我們點選FirstActivity的按鈕之後:

可以看到,我們的IntentDemo能夠響應網頁的請求了,就是因為我們在SecondActivity中添加了一個“可以響應http協議”的屬性。

除了網頁,我們還可以讓其響應撥號事件:

1 Intent intent = new Intent(Intent.ACTION_DIAL);
2 intent.setData(Uri.parse("tel:10010"));

 

 

使用Intent傳遞資料

傳遞資料給下一個活動

到目前為止,我們還只是使用Inten來跳轉活動。但是我們如果有需求,讓活動在跳轉的時候傳遞資料呢?

很簡單,Intent是一個橋樑,你把你想傳的放在橋上,然後讓另外一個人過來取不就行了嗎。Intent為我們提供了一個各式各樣的籃子,我們根據我們的需要,將資料放在籃子裡就行了。

上程式碼!

1  @Override
2  public void onClick(View v)
3  {
4      String data = "馬什麼梅?";
5      Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
6      intent.putExtra("my_data", data);
7      startActivity(intent);
8  }

 

我們定義了一個字串,用來作為傳遞的資料。(馬冬什麼?)然後我們使用的是顯式Intent,並使用putExtra(String name,DataType value)方法來傳值的(DataType代表很多資料型別)。

第一個引數,是這個資料的“鍵”。你可以理解為關鍵字,也可以簡單的理解這個資料的名字。你把資料放我這個大籃子裡面了,不得標示一下這個資料的身份嗎,否則到時候用找誰拿去啊。

第二個引數就是我們的資料了。

然後我們在SecondActivity中相應的去接收資料:

1  @Override
2  protected void onCreate(Bundle savedInstanceState)
3  {
4      super.onCreate(savedInstanceState);
5      setContentView(R.layout.activity_second);
6      Intent intent = getIntent();
7      String data = intent.getStringExtra("my_data");
8      Toast.makeText(SecondActivity.this, data, Toast.LENGTH_SHORT).show();
9  }

 

我們定義了一個Intent,並用getIntent()方法來獲取到用來啟動這個activity的Intent。然後使用getStringExtra(String name)來獲取我們存在“籃子”裡面的字串,引數當然就是我們剛才設定的資料的名字(鍵)。為了展示是否成功,我就簡單的去Toast了一下。

可以看到,我們成功返回了資料。我們這裡傳的是字串,要是Boolean就是getExtraBoolean,其他的以此類推,傳的什麼型別就接什麼。

 返回資料給上一個活動

我們傳遞資料給下一個活動是使用的Intent來暫存的,但是我們要是想直接返回上一個活動只需要按下返回鍵就可以了,並沒有什麼Intent參與其中。這時候我們的思路就要轉換一下了。你不主動給我?那好,我直接在啟動你的時候向你伸手要總行了吧!

修改FirstActivity的程式碼如下:

1  @Override
2  public void onClick(View v)
3  {
4      Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
5      startActivityForResult(intent,1);
6  }

 

既然是張嘴要,就給在啟動的時候說明白了。使用startActivityForResult(Intent intent,int requestCode),第一個就是我們的Intent,第二個是請求碼。要是有很多資料返回來的話,我們要對他們進行區分,這就是請求碼的用意。

 接下來就是SecondActivity:

1 @Override
2 public void onClick(View v)
3 {
4     Intent intent = new Intent(SecondActivity.this,FirstActivity.class);
5     intent.putExtra("data_return", "什麼冬梅?");
6     setResult(RESULT_OK, intent);7 }

 

我們還是構建了一個Intent來跳轉到上一個活動。然後放一個字串,並使用setResult(int resultCode,Intent data)來向上一個活動傳值。第一個是結果值,一般使用RESULT_OK和RESULT_CANCELED兩個值,用來告訴上一個活動返回資料的處理結果。第二個就是我們的intent了。

我們既然要向上一個活動返回資料,就得有相應的措施來處理返回資料。

新增FirstActivity的程式碼:

 1 @Override
 2 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
 3 {
 4     switch (requestCode)
 5     {
 6         case 1:
 7             if (resultCode == RESULT_OK)
 8                 Toast.makeText(FirstActivity.this, data.getStringExtra("data_return"), Toast.LENGTH_SHORT).show();
 9             break;
10         default:
11     }
12 }

 

我們重寫了FirstActivity的onActivityResult方法。這個方法接收三個引數,具體意義就不講了,都能看明白。

因為資料會有很多,所以我們第一件事就是去判斷資料來源,也就是我們的requestCode。因為如果有多個時間指向同一activity的話我們就必須分清資料從哪裡來。然後我們還需要去檢查結果碼,看看是不是成功了。

好了,這就是Intent的內容,對於我們初學者來說,這些內容很夠了。

菜鳥一個,多多指教!