跨進程調用Activity

【跨進程調用activity】

跨進程調用Activity的目的比較簡單,就是Application A中,有個Activity,想要給其它Application B調用,這時候就要分兩步進行:

(1) 在Application A的Manifest中設置Activity的屬性

  1. <activity  
  2. android:name=".SubActivity"  //該activity的class name  
  3. android:exported="true">   
  4. <intent-filter>    
  5. <action android:name="net.blogjava.mobile.MYACTION"/>    
  6. <data android:scheme="info"/>  
  7. <category android:name="android.intent.category.DEFAULT" />            
  8. </intent-filter>  
  9. </activity>  

上述代碼中:

a.  android:exported="true" :設置爲"True"則表示將該Activity暴露給外部;但在本demo中發現,這個屬性可以不用設置,demo也是生效。這是因爲:設置了intentFilter之後,exported就默認被設置爲true了,除非再強制設爲false。

b.  <action android:name="net.blogjava.mobile.MYACTION"/> :這裏是設置Intent對應的名字,在調用的時候,需要該名字。當然這裏也可以爲空。(若爲空串,調用的時候需要指定調用activity的包名和類名,後文詳述)

c.  <data android:scheme="info"/> :data元素用於把數據規範添加到一個Intent過濾器中,如果這裏定義了info,那在intent中就需要添加uri爲“info://”的字樣;如果name爲空,這裏也就不需要設置;

關於data的詳細介紹,參考 http://blog.csdn.net/fireofstar/article/details/7561589

d.  <category android:name="android.intent.category.DEFAULT" /> : 意思是說,每一個通過 startActivity() 方法發出的隱式 Intent 都至少有一個 category,就是 "android.intent.category.DEFAULT",所以只要是想接收一個隱式 Intent 的 Activity 都應該包括 "android.intent.category.DEFAULT" category,不然將導致 Intent 匹配失敗。
從上面的論述還可以獲得以下信息:  1、一個 Intent 可以有多個 category,但至少會有一個,也是默認的一個 category。 2、只有 Intent 的所有 category 都匹配上,Activity 纔會接收這個 Intent。

這四個部分是註冊時候的主要動作,但a可以無視,正如前面所說; d是不可缺少的,若少了,則無法調用成功,會提示找不到Activity的錯誤。(關於隱式Intent的內容,有專門的文章,之前看過但現在有點忘了,下次再整理下)

(2) 在Application B 中啓動intent,調用該Activity

調用的code比較簡單,如下:

  1. Intent i =  new Intent("net.blogjava.mobile.MYACTION", Uri.parse("info://111"));  
  2. this.startActivity(i);  
  3. Log.v("HelloActivity" , "Start the new activity");  

new Intent中,第一個參數就是(1)中配置的action name,兩者要一致;第二個參數就是data類型,前面的"info://"不可少,而info後面的內容可以隨意,當然你也可以添加有意義的內容。


另外一種方式是:

  1. Intent intent = new Intent();  
  2. ComponentName cn=new ComponentName("com.example.phonelistenertest",  
  3.                 "com.example.phonelistenertest.SubActivity");    
  4. intent.setComponent(cn);  
  5. startActivity(intent);    

這裏,只需要指定你需要調用的Activity是在哪個包中,以及類名是什麼,即格式爲:(包名,包名+類名)

而Application A中的Manifest只需要配置如下:

  1. <activity  
  2.             android:name=".SubActivity"  
  3.             android:exported="true"  
  4.            >  

即,只需要指定該Activity的名字,並將它暴露給外部就行,可以不用設置Intent-filter。同樣,如果你沒有設置exported屬性,會提示錯誤權限不允許訪問SubActivity。也可以用個設置一個空的intent-filter來打開該屬性,這也是網上爲什麼有的例子添加了intent-filter,但只有一個空串action的緣故。

這裏也應該是跟Intent的顯式,隱式調用方式有關。


【SingleTask】

現有2個項目,taskA、taskB。taskA負責調用taskB中指定的界面。
taskB中有3個界面,a、b、c,每個界面顯示它所在的task id。

SingleTask
其中b界面被聲明爲SingleTask。
先運行taskB,顯示a界面,由a界面調用b界面,這時b界面的taskid與a界面的taskid是一致的,說明b界面與a界面在同一個task中;由b界面調用c界面時,c界面的taskid與a和b界面的taskid一致,說明這三個界面是在同一個task中。當前顯示的是c界面,此時按Home鍵回到桌面,運行taskA的界面調用taskB的b界面,這時b界面顯示出來,它的taskid沒有變,還是之前的taskid,只不過之前顯示的是c界面,這時c界面已經不知所蹤,這時再按back鍵,則回到了a界面,然後是taskA的界面。

這說明,SingleTask所標註的Activity在被自身的app調用時,是不新建task的,同時,如果系統中存在了這個SingleTask界面的實例時,會將其所在的task切換到前臺,並把SingleTask界面之後開啓的其他界面全部關閉(有待考證是否關閉)。

另外有一種情況,例如:a界面被調用,這時按Home鍵返回到桌面,啓動taskA,並調用b界面,這時b界面的taskid與a界面的一致,說明b界面與a界面同屬於一個task。如果直接運行taskA調用b界面,b的taskid與taskA的界面的taskid不同,說明在新task中實例化了b界面,由b界面調用c界面,c界面的taskid與b界面一致,說明b與c同屬於一個task。


SingleInstance

將b界面聲明爲SingleInstance。

先運行taskB,顯示a界面,由a界面調用b界面,這時b界面的taskid與a界面的taskid不同,說明b界面是在新task中生成的實例;由b界面調用c界面,c界面的taskid與a界面的taskid相同,說明a、c界面同屬於一個task。

由此可以看出SingleTask與SingleInstance是有本質區別的,而不是像網上說的那樣,都是task的root activity,這是有錯誤的。

 文章來源: http://blog.csdn.net/wang_zun_ren/article/details/6823257

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章