2015年6月15日月曜日

GoogleサンプルでAndroidアプリを学ぶ(MediaEffects)

GoogleサンプルでAndroidアプリを学ぶ(MediaEffects)

[開発環境]
 Android Studio
[使用したサンプル]
 MediaEffects
[機能]
画像の効果

※Logはなしとしました。
 よって、MainActivityのextendsはFragmentActivityとしました。

なんか1行ずつ分からないので調べていると時間がかかりますが、
意味を理解しながらでないと意味がないと思うので、少しずつ調べていきたいと思います。
Open GL関係は分からないことだらけなので次回にしたいと思います。


フォルダ構成をサンプルと合わせる

ソースが置いてあるフォルダをサンプルと同じApplicationにしたら
ビルドできなくなりました。以下の2つをすることでビルドできました。

  1. settings.gradleで
    include ‘app’ -> include ‘Application’
  2. Build -> clean Project
  3. RUN

savedInstanceState

今までonCreateにあるsavedInstanceStateをあまり気にせずにやっていました。
調べてみるとsavedInstanceStateは前回終了時の状態を保持する変数で最初は、nullが格納されているということ。
ということで以下のように最初の起動のときだけのような処理が必要っぽい。

if (savedInstanceState == null) {}

せっかくなので、もう少し調べてみるとsavedInstanceStateは、superのonCreateにも
渡している。ここでsuperはextendsした親のクラスで親のクラスのonCreateも同様に処理するというようにしている。
これがないとこのクラスのonCreateしか処理されなくなり、よくないらしい。
(具体的な理由は見つかりませんでした。)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

onSaveInstanceState(Bundle outState)

自分のアプリに戻ったときに、前の状態には自動で戻れないので、その状態を意識的に保存する必要がある。STATE_CURRENT_EFFECTという文字列に
現在のEffectの値を入れておく。

その逆にSTATE_CURRENT_EFFECTという文字列から値を取り出すには、
getInt(STATE_CURRENT_EFFECT)。

private static final String STATE_CURRENT_EFFECT = "current_effect";
@Override
public void onSaveInstanceState(Bundle outState)
{
  outState.putInt(STATE_CURRENT_EFFECT, mCurrentEffect);
}

containsKey

特定のキーが含まれているかを確認するメソッド。
含まれていればTrue。

Fragmentのライフサイクル

何回かFragmentをやってきてましたが、少しふみこんで調べてみたところ最低でも以下3つは必要と
記載されてましたが、サンプルを見るとonCreate()とonCreateView()しかないのですが、動いてはいます。

onCreate()
onCreateView()
onPause()

参考
http://www.techdoctranslator.com/android/guide/activities/fragments

Open GLのエラー

AVD Managerのエミュレータで実行していたときに以下のようなエラーがでてハマりましたが、
実機を使うことで解決しました。
一旦、実機で試すことにします。

06-14 10:50:19.598    3848-3863/com.example.android.mediaeffects E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 167
    Process: com.example.android.mediaeffects, PID: 3848
    java.lang.IllegalArgumentException: No config chosen
            at android.opengl.GLSurfaceView$BaseConfigChooser.chooseConfig(GLSurfaceView.java:869)
            at android.opengl.GLSurfaceView$EglHelper.start(GLSurfaceView.java:1023)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1400)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)

メニューがでない

なぜかメニューがでないので調べたところ以下の2点の修正が必要でした。
1. MainActivityのextendsがFragmentになっていた。
 ActionBarActivityがdeprecatedだったのでFragmentActivityにしていたのが
 問題であり、以下にあるようにAppCompatActivityにする必要があった。

https://developer.android.com/intl/ja/reference/android/support/v7/app/ActionBarActivity.html
2. styles.xmlでThemeがAppCompatになっていなかったので以下のように修正。

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
</style>
    <!-- Activity themes -->
<!--
    <style name="Theme.Base" parent="android:Theme.Light" />
    <style name="Theme.Sample" parent="Theme.Base" />
    <style name="AppTheme" parent="Theme.Sample" />   -->

その他

setHasOptionsMenu

Fragment でメニューを追加する場合は必ず setHasOptionsMenu(true)をつける必要があるらしい。おまじない。
onCreateで定義。

@Nullable

onCreateViewをオーバーライドしたら@Overrideに加えて@Nullableもついてきた。
意味としてはNullも許されるということらしい。
サンプルでは引数のViewGroup containerとBundle savedInstanceStateに@Nullableがついていたが、メソッド自身につけられるらしい。

inflate

レイアウトXMLファイルからViewを生成するときにはinflate()を使う。
attachRootをfalseとすることでR.layout.fragment_media_effectsがルートビューとなる。
trueの場合はcontainerがルートビューとなる。

inflater.inflate(R.layout.fragment_media_effects, container, false);

enter image description here

onViewCreated(View view, @Nullable Bundle savedInstanceState)

onCrearedViewが返された事をFragmentに知らせる。
viewを引数に持っているのでfindViewByIdに割り当てる。

参考
http://qiita.com/kkkaaakkku/items/97ef17ab6a7f7b4e365d

setEGLContextClientVersion

OpenGL ESのバージョンを指定する。
サンプルでは2だが、
Android 4.3からはOpenGL ES 3.0対応したらしい。

setRenderer(@Nullable GLSurfaceView.Renderer renderer)

レンダラーをセット。このサンプルでは自分自身なのでthis

setRenderMode(int rendermode)

レンダラーモードの設定。

変数 意味
RENDERMODE_CONTINUOUSLY 連続描画モード(毎フレーム)
RENDERMODE_WHEN_DIRTY 必要な時だけ描画

0 件のコメント :

コメントを投稿