在非 UI 线程上实例化视图

Tho*_*alc 4 java android android-ui android-asynctask android-view

我知道 UI 元素(视图层次结构)只能从 UI 线程进行操作。对于后台操作,可以使用 AsyncTask,它提供事件处理程序以到达 UI 线程。

简而言之,是否允许getApplicationContext()在非 UI 线程中实例化 View(绑定到)?这个自定义 View 后代 - 一旦实例化 - 从UI 线程添加到视图层次结构。所以只有构造函数调用是在Asynctask.doInBackground(); 中完成的。它将 ( addView(...))附加到 Activity 的根布局层次结构仍然在 UI 线程中完成。

详细说明:

public MyView extends View {
     public MyView(Context context) { 
            ...
     }
...
}
Run Code Online (Sandbox Code Playgroud)
  1. 我做了一个自定义视图,覆盖onDraw(...)等。

  2. 当用户在我的主 Activity 中单击某个 MenuItem 时,会创建另一个 Activity (MyOtherActivity) 并显示哪个屏幕正是 MyView

  3. 由于必须立即显示 MyOtherActivity 的屏幕,因此我在 AsyncTask 中预先实例化 MyView,而用户在主 Activity 中的其他位置(即他还没有单击该 MenuItem)。MyView 引用存储在静态数据成员中。

  4. MyOtherActivity.onCreate()被调用时,它的构造函数代码从静态中获取 MyView,并通过addView(...).

  5. (我知道静态变量可能会导致内存泄漏,因此我将其设置为null不需要时。)

MyView 在不同的线程中实例化(并getApplicationContext()在其构造函数中获取 的返回值)不是一个问题(并且可能会引入意想不到的问题)吗?

Dar*_*tle 5

最终答案出现在View的文档中,标题为“事件处理和线程”:

注意:整个视图树是单线程的。在任何视图上调用任何方法时,您必须始终在 UI 线程上。如果您正在其他线程上工作并希望从该线程更新视图的状态,则应该使用 Handler。

所以,它不只是东西,显然会影响UI,类似的外观addView(),但“任何方法在任何视图”。

@CommonsWare 链接到的关于 android-developers讨论有不止一位来自 Android 框架团队的高级工程师确认这将被认真对待。