2011-07-14 13 views
30

でビューを膨らまAsyncTask)?は、私は非常に単純な疑問を持っているバックグラウンドスレッド

私は自分のアプリケーションでこの方法を最も活動を実施し、私はギャラクシーSでこの問題を抱えてまで、問題を持っていたことがないので、私は、それが可能であることを知っている:Android: android.view.InflateException: Binary XML file line #13: Error inflating class <unknown> in SAMSUNG Galaxy S

私が言われてきたそのI バックグラウンドスレッドでViewsを膨らませてはいけませんが、具体的な理由は何ですか?なぜ私のaproachはほとんどのデバイスで動作しますが、Galaxy Sでは動作しませんか?

答えて

36

LayoutInflaterは、それが実行されているスレッドについては何も仮定していません。また、そのドキュメントでは何も言及されていません。また、そのコードの継ぎ目はスレッドに依存しないものとする。

一方、LayoutInflaterによって作成されたビューは、コンストラクタでHandlerをインスタンス化することがあります。彼らはおそらくそれを行うべきではありませんが、コンストラクタにHandlerを作成したり使用したりする必要はありません。

私の推測では、サムスンギャラクシーSは何とかHandlerの作成をトリガし、そのEditTextにいくつかの変更があったことである(インスタンス化されたGestureDetectorのあなたの他の質問のインスタンスからクラッシュログに応じた順番でHandler新しい作成)。デフォルトの実装ではこれが行われません。


全体的に、私はあなたが非UIスレッドから膨らまビューを負いかねますHandler sであり、そのコンストラクタでLooper Sを使用しないようにViewのための明示的な要件がないため安全であることを言うと思います。

実際にはHandlerThreadを作成し、Viewを膨らませてみてください。しかし、私はこれが非常に危険であると言いたいと思います。Samsung Galaxy Sの例では、このスレッドはViewの生存期間中に生き残り、すべてのメッセージをLooperで処理することを前提としています。後でクラッシュする可能性があります。

+6

私はこの最新のファームウェアを実行しているGalaxy Nexusで同じ問題を再現しました(この記事の時点)。背景に浮かぶ景色はもはや選択肢ではありません。 –

+0

HandlerThread forward MainLooperへのメッセージはこの問題を解決するはずです – wanpen

2

バックグラウンドスレッド(例:AsyncTaskのdoInBackground)でビューを展開する(レイアウトに追加しない)ことはできませんか?

可能です。お勧めですか?いいえ。文書で述べたように:

  1. 外部からAndroidのUIツールキットにはアクセスしないでくださいUIスレッド
  2. をふさがないでください:

    したがって、Androidのシングルスレッドモデルには2つのルールが単純にありますUIスレッド

経由:Processes and Threads

6

最新のサポートlibでは、android.support.v4.view.AsyncLayoutInflaterを使用してビューを非同期に拡張することができます。それはそのgenerateLayoutParams(属性セット)親を持っている必要が非同期的に膨張するレイアウトについて

スレッドセーフであり、すべての:特定の要件が満たされていない場合、それはUIスレッド上で膨らませるにフォールバックできるのに注意してくださいインフレーションの一部として構築されたビューは、ハンドラを作成したり、myLooper()を呼び出すことはできません。膨張させようとしているレイアウトを何らかの理由で非同期に構築できない場合、AsyncLayoutInflaterは自動的にUIスレッド上で膨張します。

関連する問題