2010-07-03 36 views
6

(對不起,我的第一篇文章不太清楚)Android中的MVC:異步更新的應用程序或服務?

這裏是情況:我有要從互聯網刷新的數據。我們稱之爲Model

我想要做什麼:基本上,它聽起來像一個MVC模型,其中Model也保持在本地(私人)存儲持久。 Model及其相關方法在應用方面是明智的。有幾個Activity的是顯示和操作其不同方面:

  • 用戶 可前往[在不同Activity的 ,從不同角度顯示Model 。目前,我有一個ListActivity所有元素,一個元素的細節Activity
  • 有時Model需要清爽。 當然這是在不同的線程上完成的。刷新可以從幾個Activity的觸發。
  • 有幾個(耗時),可以從不同的Activity
  • 我的應用程序加載被觸發,並保存Model 私人存儲在啓動時 並停止

我的問題共同 任務:我不確定把Model和相關的任務放在哪裏。另外,我不知道用什麼機制來通知Activity的。目前我拿出2種方法:

  • 使用Service併發送廣播。保存到磁盤在Service#onDestroyed()中執行,所以我想通過將它綁定到Activity來最小化。在這一點上,我也不知道如何傳遞更新信息:是否提供獲得者Binder,或將其包括在廣播消息中。
  • 自定義Application對象,以便更新方法獲取器可在全球範圍內使用。然後我使用AsyncTask執行從Activity的更新。如果還有其他Activity位於當前的Activity之後,那麼當用戶返回時,它們將在onResume()中更新。我不使用一類具有靜態方法

原因:

  • 我需要保存和存儲Model到磁盤。
  • 一些方法需要一個Context 顯示祝酒詞,通知,緩存等

而且,我不把這些功能在Activity因爲有操縱同一塊幾項活動持久數據。

下面是僞代碼說明我的意思:

使用服務:

/** Service maintaining state and performing background tasks */ 
class MyService extends Service { 
    Model mModel; 
    Binder mBinder; 

    onCreate() { 
     super.onCreate(); 
     mBinder = new Binder(); 
     // load mModel from disk, or do default initialization 
    } 

    onDestroy() { 
     super.onDestroy(); 
     // save mModel to disk 
    } 

    onBind() { 
     return mBinder; 
    } 

    class Binder { 
     refresh() { 
      new AsyncTask() { 
       doInBackground() { 
        // update mModel from Internet 
       } 
       onPostExecute() { 
        sendBroadcasts(new Intent("my.package.REFRESHED")); 
       } 
      }.execute(); 
     } 

     getState() { 
      return mModel.getState(); 
     } 
    } 
} 

/** Activity displaying result */ 
class MyActivity extends ListActivity { 
    MyService.Binder mBinder; 

    onCreate() { 
     super.onCreate(); 
     // register mReceiver 
     // bind service 
    } 

    onDestroy() { 
     super.onDestroy(); 
     // unbind service 
     // unregister mReceiver 
    } 

    /** Invokes time-consuming update */ 
    refresh() { 
     // binding is asynchronous, and user may trigger refreshing too early 
     if (mBinder != null) { 
      mBinder.refresh(); 
     } 
    } 

    BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     onReceive(Intent intent) { 
      if ("my.package.REFRESHED".equals(intent.getAction()) 
        && mBinder != null) { 
       updateViews(mBinder.getState()); 
      } 
     } 
    }; 
} 

製作功能的自定義應用程序對象全局訪問

/** Custom Application providing domain specific functionalities */ 
class MyApplication extends Application { 
    Model mModel; 

    onCreate() { 
     super.onCreate(); 
     // load mModel from disk, or do default initialization 
    } 

    onTerminate() { 
     super.onTerminate(); 
     // save mModel to disk 
    } 

    void refresh() { 
     /** time-consuming */ 
    } 

    getState() { 
     return mModel.getState(); 
    } 
} 

/** Activity displaying result */ 
class MyActivity extends ListActivity { 
    onResume() { 
     super.onResume(); 

     // in case some top Activities have refreshed 
     // and user is navigating back 
     updateViews(((MyApplication)getApplicationContext()).getState()); 
    } 

    /** Invokes time-consuming update */ 
    refresh() { 
     new AsyncTask() { 
      doInBackground() { 
       ((MyApplication)getApplicationContext()).refresh(); 
      } 
      onPostExecute() { 
       // update the ListView according to result 
       updateViews(((MyApplication)getApplicationContext()).getState()); 
      } 
     }.execute(); 
    } 
} 

弱點,我可以考慮爲Service approa ch是複雜的,因爲綁定是異步的。它很可能是我要重複一些代碼,因爲我有兩個ListActivityActivity

對於Application方法,該文件說,不要依靠onTerminate()被調用。

我知道我很尷尬。傳統的解決這類問題的方法是什麼?

非常感謝。

回答

0

那麼,你可以擴展一個BroadcastReceiver而不是一個Service,當它完成它所需要做的事情時,它會加載一個帶結果的Activity。

+0

這是我的錯,因爲不清楚。我有幾個活動,訪問和變異的應用程序相同的一塊數據:) – Phil 2010-07-03 14:34:28

+0

我編輯我的帖子。希望它不太羅嗦。 – Phil 2010-07-03 14:34:52

0

你沒有解釋什麼樣的信息都過得好,但此行是很重要的:

這些任務涉及到需要 被加載並正常保存的狀態時 在應用程序啓動和停止

如果是這樣的話,爲什麼不在Activity裏面做AsynTask

我有你同樣的擔心發送IntentsArrayList裏面,但我有一個應用程序,正是這樣做,我沒有性能問題。

+0

我很抱歉不夠清楚。我沒有把它放在一個活動中,因爲我有幾個活動可以訪問和改變同一塊應用程序方面的數據。我修改了我的帖子。 – Phil 2010-07-03 14:35:48

1

Service s大多適用於某些未綁定到單個Activity(並且通常與NotificationManager或一起使用)的東西。這似乎並非如此。
所以我的建議是有一個精心設計的AsyncTask,它通過SharedPreferences/SQLite本身(而不是濫用Applicaion)管理狀態,並將從ListActivity啓動。