今天在寫一個call網路api的android程式。大致的流程如下:
- listView上點擊listItem,會call API呼叫server刪除對應資料
- server回傳訊息給手機,手機根據回傳回來的資料,判讀server是否成功刪除,再看要不要刪local資料庫的資料。
- 若是有刪local的資料,同時也要更動listView顯示的資料。
這篇記錄一些我遇到的問題,主要都是跟多執行緒有關。把一些心得記錄下來,算是複習一下android和java多執行緒的概念。以下會提供兩種方法:
提供的第一種方法是用handler,第二種方法先保密最後再說:)
listView上點擊listItem,call API呼叫server刪除對應資料
本來我的程式是沒有另外開另一個執行緒的,也就是直接用UI thread做call API。程式碼中的SOAP是透過網路交換資料的一種協議。結果每次在接收server資料的地方都一直跳出Exception,看了一下logcat,才發現throw出android.os.NetworkOnMainThreadException,也就是說跟網路交換資料的動作跑在主執行緒上了。所以要再外面包一個Runnable另開一個執行緒,專門處理資料收發。Handler.sendMessage的部分後面解釋
[code language=”java”]
new Thread(new Runnable() {
@Override
public void run() {
.
.
.
SOAP.deleteRecord(Fragment.this, account, password, id);
mHandler.sendMessage(mHandler.obtainMessage());
}}).start();
[/code]
server回傳訊息給手機,手機根據回傳回來的資料,判讀server是否成功刪除,再看要不要刪local資料庫的資料。
接下來這個部分就是接收server丟回來的訊息,看要進行什麼動作。本來我是直接在接收的部分就直接進行ListView的操作,結果一樣跳Exception。注意,目前還在我們另外開的執行緒上,所以理所當然不能動主執行緒的UI。也因此,我才會在前面發送request給server的程式碼後,加上
[code language=”java”]
mHandler.sendMessage(mHandler.obtainMessage());
[/code]
如此一來,才可以在副執行緒時,即時告訴主執行緒(UI thread),我動作做完了,你現在可以改UI了。
[code language=”java”]
if(data[0].equals("0")){ //server資料已刪除
/*
local database操作
*/
}
else if (data[0].equals("1")) {
Log.d(TAG, "Download exception");
}
else if (data[0].equals("2")) {
Log.d(TAG, "Account or password error");
}
[/code]
若是有刪local的資料,同時也要更動listView顯示的資料。
而主執行緒接收message的程式碼在底下:
[code language=”java”]
Handler mHandler=new Handler(){
public void handleMessage(Message message){
super.handleMessage(message);
ListItemAdapter adapter = (ListItemAdapter) m_ListView.getAdapter();
/*
UI操作
*/
} }; [/code]
好啦,以上就是第一種方法。
第二種方法
但我還是覺得麻煩,所以又再查了一下,發現android的API就有己經有提供一個方法,叫做Activity.runOnUiThread,這個方法呼叫了,就可以直接在新開的thread上面操作UI了,超級方便。
[code language=”java”]
m_Activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(data[0].equals("0")){
/*
local database操作
*/
/*
UI操作
*/
}
else if (data[0].equals("1")) {
Log.d(TAG, "Download exception");
} else if (data[0].equals("2")) {
Log.d(TAG, "Account or password error");
}
}});
[/code]
搞定:)
參考資料:
http://lak4cyut.blogspot.tw/2011/03/android-tip-activityrunonuithread.html
關於我:
我是沒一村,專長和興趣是程式、主動投資、科技商業模式。可以參考我的書單和比較熱門的文章: