7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Viewの動的生成をUIスレッドで実行するのは間違っている件について

Posted at

TL;DR

  • Viewの作成は別スレッドでも可能。
  • 動的なView生成は別スレッドで実行し、addViewだけUIスレッドで実行するとANR回避できるかも。
  • iOSではXcode9から警告?が出るとのこと。

はじめに

UIスレッドで動的にViewを生成してaddViewするということをしていました。
今まではそれがパフォーマンスに影響するほどの量のViewを生成していなかった、Viewの生成が複雑なロジックではなかったため、問題はありませんでした。
しかし、複雑なロジックでViewの動的生成をする画面が出てきました。
それだけが原因ではないのですが、画面が表示されるまで体感5秒近くかかるし、パフォーマンスが極めて悪いことが分かりました。
これではいかんということで、全体的にロジックを見直し、それに合わせてViewの構築についても見直しすることにしました。

実装

難しいことはしていません。
Viewの生成を別スレッドで実行、生成したViewをコールバックで返すだけです。
Contextなど必要なものはパラメータで渡します。

別スレッド.java
List<View> views = new ArrayList<>();

LinearLayout.LayoutParams params =
        new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
TextView textView = new TextView(context);
textView.setLayoutParams(params);
textView.setText("test");

views.add(textView);
UIスレッド.java
LinearLayout container = findViewById(R.id.container);

for (View view : views) {
    container.addView(view);
}

これで画面にtestと書かれたTextViewが配置されることを確認できました。

おわりに

Viewの生成を別スレッド、addViewはUIスレッドをすることでUIを止めることがなくなります。
Viewの動的生成が複雑な場合にANRを回避できるかも。(そこまで確認してません。)
そもそも動的にViewを作るのであれば、また別の手段を考えるべきなんだろうなぁと思っています。
Contextを渡す必要があるので、メモリーリークしないように対策が必須です。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?