7

就 Android SDK 而言,这可能没有多大意义,但是,在 C++ 中,我习惯于将 main.cpp(特别是 main() 函数)作为我声明和初始化其他类/对象的地方,然后所有我的应用程序确实发生在这些课程中。之后我再也没有回来检查 main.cpp 中的任何内容。但在 Java、Android SDK 中,您必须在主要活动中覆盖数十个方法,所有这些都发生在一个文件中。例子:

我的项目中有一个 MainActivity.java 和 SomeTest.java 文件,其中首先是扩展 Activity 的默认 MainActivity 类,而 SomeTest.java 包含声明和运行新线程的类。我从 MainActivity.java 初始化 SomeTest 类,并将活动句柄作为参数传递给它:

SomeTest test = new SomeTest(MainActivity.this);

有了 MainActivity 的句柄,我继续从这个新创建的线程做所有事情。当我需要更新 UI 时,我使用 runOnUiThread() 在我的主布局上创建并显示一个新的 ListView(例如)。我想获取新创建的 Listview 的宽度和高度,因为我必须在 MainActivity.java 中覆盖 onWindowFocusChanged() 并从那里通知线程,因为 getWidth() 和 getHeight() 只有在 ListView 是时才有值实际显示在屏幕上。对我来说,从 MainActivity 到该线程进行这样的连接(如果你愿意的话,是“回调”)不是一个好习惯。

有没有办法可以将 onWindowFocusChanged() 之类的方法保留线程中,并且根本不接触 MainActivity.java?

正如我所说,可能没有多大意义。

4

4 回答 4

4

有没有办法可以将 onWindowFocusChanged() 之类的方法保留在线程中,并且根本不接触 MainActivity.java?

onWindowFocusChanged()是一个回调方法。它在活动中被调用。你无法改变这一点。

有了 MainActivity 的句柄,我继续从这个新创建的线程做所有事情。

这通常不是一个好主意。例如,使用后台线程从文件或数据库加载一些数据是完全合理的(尽管使用LoaderAsyncTask可能更好)。但是,通常,后台线程不应该知道也不关心诸如“新创建的 ListView 的宽度和高度”之类的事情。

当然欢迎您将一些逻辑从活动中迁移到其他类中。您可能会为此使用特定的框架,例如片段或自定义视图。但是,类结构不应由您的线程模型驱动。例如,让我们回到你的开场白:

在 C++ 中,我习惯于将 main.cpp(特别是 main() 函数)作为我声明和初始化其他类/对象的地方,然后我的应用程序所做的所有事情都发生在这些类中

但是,在 C++ 中,您不会说您只能拥有两个类,其中一个在某个后台线程上运行。虽然您可能有一个或多个类碰巧使用后台线程(或多个线程),但类结构背后的驱动力不是“我有一个后台线程”,而是“我想重用 XYZ 逻辑”或“我希望使用类层次结构来支持策略模式”或类似的东西。

于 2013-02-22T14:12:55.997 回答
1

就个人而言Context,从 Android SDK 获取的想法似乎很混乱。您所描述的来自过多的责任Activity。这就是为什么您需要在单个文件中跟踪很多东西(Activity的生命周期,获取Context实例以显示Dialog等)。我认为没有完美的解决方案,但我建议使用:

  • Fragment有助于将屏幕(等等逻辑)划分为单独部分的子类
  • 3rd 方框架/库,如AndroidAnnotationsRoboGuiceOtto,它们是避免意大利面条式代码的完美工具
于 2013-02-22T14:31:38.677 回答
0

如果您想从另一个类执行一些 UI 更新,请考虑使用AsyncTask将您需要更新的视图传递给它。如果您需要示例,请告诉我

于 2013-02-22T14:13:53.823 回答
0

我阅读了所有内容并理解了您的陈述,我可以看到您已经进行了一段时间的编程,但显然只是从 Android 开始,我之前做过很多嵌入式系统,所以我完全明白拥有一个看起来像的软件的概念:

void run(){
    object.setup();
    while(true){
        otherObject.run();
    }
}

但是你的问题的逻辑存在一个基本缺陷:

Android 编程是不同于 C++ 和计算机编程的编程范式,您应该了解它的特定范式,而不是假设其他范式的良好实践。

引用你的话:create and show a new ListView (for example) on my main layout. I want to get the width and height of the newly created Listview, for what I have to override onWindowFocusChanged()

从那我可以看出你真的在尝试以一种在 Android 上下文中不推荐的方式来做 Android 的事情。您可以轻松地从 XML 布局实现 ListView,setContentView(int)并使用 Activity onCreate 实例化任何线程 (AsyncTaskLoader) 框架以在后台加载数据并将其传递回 UI。

这并不意味着您的所有代码都将被转储到一个文件中,从而使其变得一团糟。我放的这个小例子可以用实现加载器回调的 Activity 来做,一个带有加载器的单独类,一个带有数据加载工作的单独类,一个带有数据适配器的单独类,活动只是一个中心部分,用于组织和在其生命周期的正确时刻管理这些类,并且在任何时候您都不需要调用onWindowFocusChanged()并且仍然拥有组织良好的代码。

除此之外,请参考 CommonsWare 答案,因为它通常写得很巧妙且正确。

于 2013-02-22T14:31:24.197 回答