程式設計雜筆

[程設雜筆] android程式設計利用多執行緒call網路API,並同時更動UI界面

今天在寫一個call網路api的android程式。大致的流程如下:

  1. listView上點擊listItem,會call API呼叫server刪除對應資料
  2. server回傳訊息給手機,手機根據回傳回來的資料,判讀server是否成功刪除,再看要不要刪local資料庫的資料。
  3. 若是有刪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的部分後面解釋

new Thread(new Runnable() {
  @Override
  public void run() {
  .
  .
  .
  SOAP.deleteRecord(Fragment.this, account, password, id);
  mHandler.sendMessage(mHandler.obtainMessage());
}}).start();

server回傳訊息給手機,手機根據回傳回來的資料,判讀server是否成功刪除,再看要不要刪local資料庫的資料。

接下來這個部分就是接收server丟回來的訊息,看要進行什麼動作。本來我是直接在接收的部分就直接進行ListView的操作,結果一樣跳Exception。注意,目前還在我們另外開的執行緒上,所以理所當然不能動主執行緒的UI。也因此,我才會在前面發送request給server的程式碼後,加上


mHandler.sendMessage(mHandler.obtainMessage());

如此一來,才可以在副執行緒時,即時告訴主執行緒(UI thread),我動作做完了,你現在可以改UI了。

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");
}

若是有刪local的資料,同時也要更動listView顯示的資料。

而主執行緒接收message的程式碼在底下:


Handler mHandler=new Handler(){
  public void handleMessage(Message message){
  super.handleMessage(message);
  ListItemAdapter adapter = (ListItemAdapter) m_ListView.getAdapter();
  /*
  UI操作
  */
} }; 

好啦,以上就是第一種方法。

第二種方法

但我還是覺得麻煩,所以又再查了一下,發現android的API就有己經有提供一個方法,叫做Activity.runOnUiThread,這個方法呼叫了,就可以直接在新開的thread上面操作UI了,超級方便。


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");
  }
}});

搞定:)

參考資料:

http://lak4cyut.blogspot.tw/2011/03/android-tip-activityrunonuithread.html

http://j796160836.pixnet.net/blog/post/30577968-%5Bandroid%5D-%E4%BD%BF%E7%94%A8http%E7%9A%84post%E6%96%B9%E5%BC%8F%E5%92%8C%E7%B6%B2%E9%A0%81%E8%A1%A8%E5%96%AE%E6%BA%9D%E9%80%9A-(%E5%8A%A0

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s