2010-07-03 63 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启动。