LoginSignup
12
12

More than 5 years have passed since last update.

SurfaceView を足そうとすると画面が点滅する

Posted at

問題

以下のようなコードを実行して、ボタンをタップすると画面が点滅する。

Telecine_2015-08-25-10-13-01.gif

MainActivity.java
package com.hkurokawa.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MainActivity extends AppCompatActivity {
    ViewGroup content;
    View dummy;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        content = (ViewGroup) findViewById(R.id.content);
        dummy = LayoutInflater.from(this).inflate(R.layout.view_dummy, content, false);
    }

    public void onBtnClick(View view) {
        content.removeAllViews();
        content.addView(dummy);
    }
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onBtnClick"
        android:text="Add SurfaceView" />

    <FrameLayout
        android:id="@+id/content"
        android:layout_below="@id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </FrameLayout>
</RelativeLayout>
view_dummy.xml
<?xml version="1.0" encoding="utf-8"?>
<SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
    android:visibility="gone"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/

調査

調べて分かったこと。

  • 初回のみ起きる。2回目以降の addView では点滅しない。
  • addView のタイミングで起きる。デバッガで追ったところ、addView メソッドを抜けてから点滅するので、どこかで View Hierarchy を監視していて、SurfaceView が追加されたときに何かやっているのかもしれない。
  • addViewonCreate メソッド内であれば点滅はしない。
  • SurfaceView が含まれる Fargment を表示するのでも同じ。内部的に addView が呼ばれるので。
  • 追加する SurfaceView が一瞬見えているのかと思ったけれど、そうではない模様。上の例でも visibility="gone" だけれども点滅する。背景色を変えてもダメ。

解決

以下のように幅と高さが 0dpSurfaceViewactivity_main.xml に含めておけば回避できる。

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- Somehow, if you add a SurfaceView in advance, the screen does not blink. -->
    <SurfaceView
        android:layout_width="0dp"
        android:layout_height="0dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onBtnClick"
        android:text="Add SurfaceView" />

    <FrameLayout
        android:id="@+id/content"
        android:layout_below="@id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </FrameLayout>
</RelativeLayout>

StackOverflow にも同様の解決方法が載っていた。Surface が初めて足されたタイミングで IWindowSession#relayout() が呼ばれるらしく、それが点滅の原因とのこと。

12
12
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
12
12