代码之家  ›  专栏  ›  技术社区  ›  Phil

android中的mvc:异步更新的应用程序还是服务?

  •  6
  • Phil  · 技术社区  · 14 年前

    (很抱歉在我的第一篇文章中没有这么清楚)

    情况是这样的:我有数据要从互联网上刷新。我们称之为 Model .

    我想做的是: 基本上它听起来像一个mvc模型,其中 模型 在本地(私有)存储中也保持持久性。这个 模型 其相关方法是应用性的。有几个 Activity 显示和操作它的不同方面:

    • 用户 导航到不同的 活动 的 那个显示器 模型 从不同的角度。目前我有一个 ListActivity 对于所有元素,以及 活动 一个元素的细节
    • 有时 模型 需要提神。 当然,这是在另一条线上完成的。刷新可以从几个 活动 s。
    • 有几个(耗时的)共同点 可以从不同的 活动
    • 我的应用程序加载和保存 模型 启动时转到专用存储 停下来

    我的问题: 我不知道放在哪里 模型 以及中的相关任务。另外,我不知道用什么机制来通知 活动 目前我提出了两种方法:

    • 使用 Service 发送广播。保存到磁盘是在 Service#onDestroyed() ,所以我想通过将其绑定到 活动 在这一点上,我也不确定如何传递更新的信息:是否提供 吸气剂 在里面 Binder ,或将其包含在广播消息中。
    • 自定义 Application 对象以便 刷新方法 吸气剂 可在全球范围内使用。然后我从执行更新 活动 正在使用 AsyncTask . 如果还有其他的 活动 是水流后面的 活动 ,它们将在中更新 onResume() 当用户返回时。

    我不使用带有静态方法的类的原因:

    • 我需要保存和存储 模型 到磁盘。
    • 有些方法需要上下文 用于显示祝酒词、通知、缓存等。

    另外,我不把这些功能放在 活动 因为有几个活动可以操作同一块持久数据。

    下面的伪代码说明了我的意思:

    使用服务:

    /** 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();
        }
    }
    

    我能想到的弱点 服务 方法很复杂,因为绑定是异步的。很可能我必须重复一些代码,因为我两个都有 列表活动 活动

    对于 应用程序 方法,文件上说不要依赖 onTerminate() 被召唤。

    我知道我很尴尬。解决这类问题的传统方法是什么?

    非常感谢。

    3 回复  |  直到 14 年前
        1
  •  1
  •   yanchenko    14 年前

    Service s主要适用于不绑定到单个 Activity (通常与 NotificationManager 或A Widget )似乎不是这样。
    所以我的建议是 AsyncTask 通过 SharedPreferences / SQLite 本身(而不是滥用 Applicaion )并将从 ListActivity .

        2
  •  0
  •   xil3    14 年前

    好吧,你可以扩展一个广播接收器而不是一个服务,当它完成它需要做的事情时,它会加载一个带有结果的活动。

        3
  •  0
  •   Macarse    14 年前

    你没有解释你得到了什么样的信息,但这句话很重要:

    这些任务涉及需要 当 应用程序启动和停止

    如果是这样的话,你为什么不 AsynTask 在里面 Activity ?

    我和你一样担心 Intents 具有 ArrayList 但我有一个应用程序正是这样做的,我没有性能问题。