java - 如果我在 Android 中使用单独的线程更新 UI 会不会很糟糕?

标签 java android multithreading

我有一个 ListFragment,通过运行一个读取文件的单独线程来更新它,然后使用该文件初始化一个类并将其发送到 UI 线程。可以吗还是会导致不稳定? android 不是线程安全的是什么意思?使用AsyncTask线程而不是普通线程更好吗?

我将代码切换到单独的线程,现在应用程序有时会崩溃。

这是日志 -

07-10 14:20:21.035: E/AndroidRuntime(11045): FATAL EXCEPTION: Thread-395
07-10 14:20:21.035: E/AndroidRuntime(11045): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5010)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:964)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.requestLayout(View.java:15438)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.setFlags(View.java:8599)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.view.View.setVisibility(View.java:5651)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.AdapterView.updateEmptyStatus(AdapterView.java:750)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.AdapterView.checkFocus(AdapterView.java:720)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:812)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6720)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at hasebou.karim.simplify.TimedEventsListFragment.addToList(TimedEventsListFragment.java:88)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at hasebou.karim.simplify.ReadNWrite.rebuildList(ReadNWrite.java:66)
07-10 14:20:21.035: E/AndroidRuntime(11045):    at hasebou.karim.simplify.ReadNWrite.run(ReadNWrite.java:24)

最佳答案

android isn't thread-safe

完全不正确。 Android 与任何系统一样都是线程安全的。

使用单独的线程来执行长时间运行的任务是一个非常好的策略,事实上,recommended :

When your app performs intensive work in response to user interaction, this single thread model can yield poor performance unless you implement your application properly. Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI. When the thread is blocked, no events can be dispatched, including drawing events. From the user's perspective, the application appears to hang. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog. The user might then decide to quit your application and uninstall it if they are unhappy.

从多个线程更新 UI 是不线程安全的:

Additionally, the Andoid UI toolkit is not thread-safe. So, you must not manipulate your UI from a worker thread—you must do all manipulation to your user interface from the UI thread. Thus, there are simply two rules to Android's single thread model:

  1. Do not block the UI thread
  2. Do not access the Android UI toolkit from outside the UI thread

据我所知,在任何操作系统中,没有任何 GUI 工具包可以从多个线程更新 GUI 是明智或安全的。

除了直接使用线程外,Android还支持AsyncTask进行长时间运行的操作。 AsyncTask 使用线程,但比通用线程机制使用起来更加简单和方便。

关于java - 如果我在 Android 中使用单独的线程更新 UI 会不会很糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24674427/

相关文章:

android - 如何从行号获取游标

Java:在同一线程上多次调用 join()?

java - 在带有 URI 的 HTTP 请求中找不到映射 [springcodes/functions.jsp]

Java办公组件

java - 使用私钥生成 JSON Web token (JWT)

android - 为什么我在Android平台上无法显示图片

java - Freemarker模板加载

java - 如何解决,JSONException : No value for "1"

multithreading - 缓存可以保存来自多个进程的数据吗?

c# - 在另一个线程上访问数据