編輯:關於Android編程
一、帶返回值的Activity回退過程
一般情況下,我們要從當前Activity跳轉到另一個Activity,采用的方法是通過startActivity(Intent)來攜帶數據並實現跳轉
有時候又需要跳轉到的Activity能夠在回退時返回處理結果給前一個Activity,這就要用到以下方法了
public void startActivityForResult(Intent intent, int requestCode)
該方法同樣是用於實現Activity的跳轉,不過多了一個int類型的請求碼requestCode
requestCode用於標示當Activity回退時,處理結果是從哪一個Activity傳遞來的,因為當前Activity有可能需要跳轉到多個Activity
此外,Activity類還包含有以下方法
protected void onActivityResult(int requestCode, int resultCode, Intent data)
requestCode即是請求碼,resultCode用於標示數據處理結果,data用於攜帶數據
因此,我們可以用以下代碼實現Activity的跳轉
private int REQUEST_CODE = 10;
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
Bundle bundle = new Bundle();
bundle.putString("requestText", "啊哈");
intent.putExtras(bundle);
startActivityForResult(intent, REQUEST_CODE);
向Intent中傳入需要傳遞給Main2Activity的數據
然後,在onActivityResult中處理Main2Activity回退後傳遞而來的數據處理結果,這裡用Log來輸出
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
Bundle bundle = data.getExtras();
Log.e("MainActivity", bundle.getString("responseText"));
}
super.onActivityResult(requestCode, resultCode, data);
}
其中,需要判斷requestCode是否與請求碼相等
此外,查看源碼可知,resultCode取值一般為以下三個,用來標示操作結果
/** Standard activity result: operation canceled. */
//標示操作取消
public static final int RESULT_CANCELED = 0;
/** Standard activity result: operation succeeded. */
//標示操作成功
public static final int RESULT_OK = -1;
/** Start of user-defined activity results. */
public static final int RESULT_FIRST_USER = 1;
以上都是在MainActivity中操作,此外還需要在Main2Activity中設置返回結果
先取出傳遞而來的數據requestText
private String requestText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Intent intent = getIntent();
if (intent != null) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
requestText = bundle.getString("requestText");
}
}
init();
}
通過setResult方法設置處理結果為RESULT_OK,並通過intent攜帶處理結果
public void init() {
findViewById(R.id.response).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("responseText", "收到第一個Activity的請求內容為:" + requestText);
intent.putExtras(bundle);
setResult(RESULT_OK, intent);
finish();
}
});
}
這樣就可以實現當Activity回退時,攜帶處理結果到前一個Activity了
二、關於Activity啟動模式的補充說明
在上一篇博文中已經介紹過Activity的四種啟動模式了,這裡再來補充一些內容
singleTask
此為棧內復用模式
如果以在AndroidManifest中聲明屬性的方式來設定啟動模式的話,如果不指定taskAffinity屬性,該Acitvity只會存在於當前棧中
想要讓Activity以單實例的方式存在於一個新的棧的話,可以這樣聲明:
注意,taskAffinity的值不能與包名相同,不然就相當於沒有設置了
可以通過getTaskId()方法來查看當前Activity位於哪個棧,如:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("第一個Activity", getTaskId() + "");
}
singleInstance
即單實例模式
采用此種模式的Activity均會獨立存在於一個棧內,即使兩個Activity的taskAffinity屬性相同
例如
Main2Activity和Main3Activity均聲明為singleInstance模式且棧名為com.custom.czy
但通過Log.e("Activity", getTaskId() + "");查看,還是可以發現兩個Activity存在於不同的棧中
三、Activity的隱式調用
隱式調用不需要明確指定要調用的Activity信息,而是根據Intent具有的信息去匹配目標組件的IntentFilter中所設置的過濾信息,如果匹配成功則啟動,否則會報錯
一個Activity可以包含有多個IntentFilter,只要Intent能夠匹配其中一組< intent-filter >即可啟動該Activity
IntentFilter具有的屬性有:action、category、data
action
action屬性值是一個字符串,系統也為我們提供了多個action,如Intent.ACTION_VIEW可用於打開系統自帶的浏覽器
在 < intent-filter >中可以聲明多個action,只要求Intent中攜帶的action字符串與其中一個相同即成功匹配該Activity
Intent中必須含有action屬性,否則將直接匹配失敗
不過在Intent總設置action時,我試了下,似乎只可以定義一個action,通過構造函數或者setAction(String action)函數來定義action,多次設置只會保留最後一個action值
public void startActivity(View view) {
Intent intent = new Intent("com.bb.hh");
intent.setAction("com.czy.action");
Log.e("++++++", intent.getAction());
startActivity(intent);
}
這樣依然可以成功啟動Activity
category
在< intent-filter >中同樣可以設定多個category屬性,且Intent也可以通過addCategory(String category)添加多個category
與action屬性不同的是,只要是在Intent中包含的category值,< intent-filter >都必須有category與之一一匹配,否則匹配失敗
需要注意的是,系統在startActivity(Intent intent)的時候,會自動為Intent添加一個默認的category值,即:android.intent.category.DEFAULT
所以為了讓Activity可以通過隱式調用的方式啟動,需要在< intent-filter >同樣為之添加一個默認的category值
如上述代碼所示
data
data屬性用於指定當前活動能夠響應什麼類型的數據
如系統自帶的浏覽器自然就能響應http模式的網絡連接要求,因此我們可以用隱式調用的方式來調用浏覽器打開指定網頁
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
如果過濾規則中設置了data屬性,則Intent中也必須含有data屬性且相同才能匹配成功
data包含的屬性值有:
data由兩部分組成,mimeType和URI
mimeType指媒體類型,可以是:image/jpeg、video/*,用於表示圖片、文本、視頻等不同的媒體格式
URL的結構如下所示:
< scheme>://< host>:< port>/[< path>|< pathPrefix>|< pathPatten>]
scheme:URI的模式,如http,file,content,默認值為(content和file)
host:URI的主機名,比如www.baidu.com
port:URI的端口號
path、pathPatten和pathPrefix這三個參數表示路徑信息
如,可以設置某Activity能夠處理的數據類型為圖片image
則可以通過設置mimeType屬性來啟動該Activity
public void startActivity(View view) {
Intent intent = new Intent("com.bb.hh");
intent.setAction("com.czy.action");
intent.addCategory("android.intent.category.czy");
intent.setType("image/png");
startActivity(intent);
}
或者為Intent設置完整的data屬性
public void startActivity(View view) {
Intent intent = new Intent("com.bb.hh");
intent.setAction("com.czy.action");
intent.addCategory("android.intent.category.czy");
intent.setDataAndType(Uri.parse("file://abc"),"image/png");
startActivity(intent);
}
此外,由於通過隱式調用有可能因為匹配不成功而導致報錯,所以在調用之前可以先判斷當前是否有合適的Activity
Intent intent = new Intent("com.bb.hh");
intent.setAction("com.czy.action");
intent.addCategory("android.intent.category.czy");
intent.setDataAndType(Uri.parse("file://abc"), "image/png");
ComponentName componentName = intent.resolveActivity(getPackageManager());
if (componentName != null) {
String name = componentName.getClassName();
Log.e("MainActivity:", "匹配成功:" + name);
startActivity(intent);
} else {
Log.e("MainActivity:", "匹配失敗");
}
如果匹配失敗,resolveActivity方法就會返回null,否則就會返回匹配度最高的Activity信息
本文是對已實現的藍牙防丟器項目的總結,闡述藍牙防丟器的原理、實現與android客戶端的藍牙BLE接口編程。在這裡重點關注如何利用BLE接口來進行工程實現,對於BLE的協
“點九”圖片概述 “點九”是andriod平台的應用軟件開發裡的一種特殊的圖片形式,文件擴展名為:.9.png。 我們都知道android平台有多種不同的分辨
ListView在android開放中用的比較多,所以接下來就進行ListView的使用的講解。 首先創建一個android項目,項目名為ListViewTest. Li
1.3D畫廊的實現 我們知道android系統已經為我們提供好了一個展示圖片的“容器”——Gallery,但