情報は力ではない

UE4 とか Blender とか。

ActivityUnitTestCaseでIllegalStateException

Androidのテストを学ぶためにCreating Unit Tests | Android Developersを読みながら、そのサイトに載っているAndroidTestFunを写経していた。その時、ちょっと詰まってしまったのでメモ。

ActivityUnitTestCaseのstartActivity()を起点にした例外

AndroidTestFunプロジェクトのlesson4にLaunchActivityTestクラスがあるのだけれど、そのtestPreconditions()を書いてテストを走らせた時に例外が発生した。testPrecondisions()のコードは次のようなもの。

   @MediumTest
    public void testPreconditions() {
        //Start the activity under test in isolation, without values for savedInstanceState and
        //lastNonConfigurationInstance
        startActivity(mLaunchIntent, null, null);
        final Button launchNextButton = (Button) getActivity().findViewById(R.id.launch_next_activity_button);

        assertNotNull("mLaunchActivity is null", getActivity());
        assertNotNull("mLaunchNextButton is null", launchNextButton);
    }

テストのログを見てみると次のようなエラーメッセージが書いてあった。

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

なぜこんな例外が発生するのだろうと思って少し調べてみると、こんなサイトがあった。
Issue 128421 - android - ActivityUnitTestCase startActivity() IllegalStateException - Android Open Source Project - Issue Tracker - Google Project Hosting
どうやら同じような例外が発生している人がいるみたいだった。
このissueでは2つの解決法が提供されていた。

  1. setActivity()をオーバーライドする方法
  2. contextを明示的に設定する方法

setActivity()をオーバーライドする方法

@Override
    protected void setActivity(Activity testActivity) {
        if (testActivity != null) testActivity.setTheme(R.style.AppTheme);
        super.setActivity(testActivity);
    }

contextを明示的に設定する方法

protected void setUp() throws Exception {
   super.setUp();
      
   ContextThemeWrapper context = new ContextThemeWrapper(
          getInstrumentation().getTargetContext(), R.style.AppTheme);
   
   setActivityContext(context);

   (...)
}

自分の場合、どちらの方法を使っても例外が発生しなくなった。
原因はよくわかっていないけど、とりあえずこれでまた写経を始めることができる。

Notificationをユーザに消されないようにする

AndroidでのNotificationをユーザに消されないようにするには次のようにすれば良い。

NotificationCompat.Builder builder =
  new NotificationCompat.Builder(context)
    .setOngoing(true); // このメソッドでtrueを指定する

主な使用用途として考えられるのは、音楽の再生中とかダウンロード中のNotification。
注意としては、setOngoing(true)としている限りNotificationが消えることはないので、音楽の再生やダウンロードが終わったらsetOngoing(false)を指定したNotificationをnotifyする必要があるということ。

追記(2015.11.12)

あまり行儀は良くないのかもしれないけどNotificationクラスのflagsを直接操作してもNotificationを消されないようにできる。

Notification notification = new Notification();
notification.flags |= Notification.FLAG_NO_CLEAR;

GitHub実践入門を読んだ。

今日、友達に頂いたGitHub実践入門を読んだ。読みたい本だったのだけれど、お金が無くて買えなかったから非常にありがたい。www.amazon.co.jp

普段からGitやGitHubは軽く使っているので、すらすらと読むことが出来た。
本の中でgit log -pやgit reflog、git rebaseなどの自分が知らないコマンドを簡単に説明してあった。普段Gitを使うのに困らない程度にしかGitコマンドを知らないので、少しずつでもGitコマンドを学ばなければいけないなと思った。また、GitHubにショートカットキーがあることもこの本で初めて知った。
Pull Requestを体験できるのも非常によかった。人生初Pull Requestを行った。

正直なところ、GitHubでIssueを書いたり、Pull Requestを送るのは自分にとってはまだまだ非常に敷居の高いことのように思う。これから少しずつ慣れていければとこの本を読んで思った。

RecyclerViewとCardViewを使ってみた。

Androidの開発をしたばかりで、わからないことが多い。今回はRecyclerViewとCardViewについて少しだけ学んだ。

Getting Started With RecyclerView and CardView on Android - Tuts+ Code Tutorial
少し古い記事だけど、このサイトのコードを写経してRecyclerViewとCardViewの使い方をなんとなく学んだ。
このサイトでは、簡単なプロフィールリストを作成していたので、それを真似てみた。
リストを作成することは出来たので、次はItemをタッチした時に、各プロフィールの詳細用のActivityを開くようにしようと思う。

コードを書いて学ぶことは大事だなと改めて感じた。

github.com

メインスレッドではネットワーク操作を行ってはいけない。

最近、ちょこちょことAndroidの開発を行っている。色々と学ばなければいけないことが多いので、少しずつしか開発が出来ない。
だいぶ古い記事だけど、Androidで広がる,携帯アプリ開発の世界 - 第4回 簡単なRSSリーダーを作ってみる:ITproを写経して
簡単なRSSリーダーを作った。そのコード内でXMLをパースするときにXmlPullParserというものを使っていた。
このXmlPullParserがどういう動作をするのかをもうちょっと知りたくて次のようなコードを書いてた。

public class MainActivity extends ActionBarActivity {
  private static final String FEED_URL = "http://...";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    URL url = new URL(FEED_URL);
    InputStream is = url.openConnection().getInputStream();
    XmlPullParser parser = Xml.newPullParser();
    parser.setInput(is, null);
    ...
}

実行してみたところ、こんな例外が出た。

android.os.NetworkOnMainThreadException

調べてみたところ、メインスレッドでネットワークの操作をするなということらしい。
NetworkOnMainThreadException | Android Developers
「Honeycomb SDK以上(Android 3.0以上)でしか例外は投げられないけど、メインスレッドでネットワーク操作はするなよ」的なことが書いてあった。

今後は気をつけよう。

va_list型というものを知った。

ゲームエンジンアーキテクチャを読んでいて9章のサンプルコードで出てきたva_listとそれに関連するマクロや関数を初めて知ったので簡単なコードを書いてみた。特に使い道のないコード。

va_listのサンプル

va_list型は可変長引数を扱うために使う型。
詳しくはhttp://www.cplusplus.com/reference/cstdarg/va_list/を読むと良いかもしれない。

まだまだ知らないことが多くあるなぁと思った。

ゲームエンジン・アーキテクチャ第2章

第2章のタイトルは「仕事用ツール」。この章では主にバージョン管理システムMicrosoft Visual Studio、それからプロファイリングツールメモリリーク、メモリ破壊の検出について記述している。

2.1 バージョン管理

バージョン管理システムを幾つか紹介した後、SubversionTortoiseSVNを用いてコミットやマージについて説明している。

2.2 Microsoft Visual Studio

ソースファイルは翻訳単位。コンパイラが見るものは全て翻訳単位。

リンカの仕事

  • 全てのマシンコードの最終的な相対アドレスを計算する
  • それぞれの翻訳単位における関数やグローバルデータに対する全ての外部参照が必ず適切に解決されるようにすること

一般的なビルド構成

  • Debug, Release
  • 製品ビルド
    • 全てのデバッグ情報を取り除き、アサートは無効化する。最適化も行う。
  • ツールビルド
    • よくわかっていない。
  • ハイブリッドビルド
    • 翻訳単位の大部分がリリースモードでビルドされ、少しの部分がデバッグモードでビルドされている構成。
    • Visual Studioでは翻訳単位ごとのビルド構成を設定できないので設定するのが面倒らしい。

コードのデバッグ

Visual Studioのウォッチウィンドウは便利っぽい。
今までちゃんとVisual Studioのデバッガを学んで使ったことがなかったので知らないことがちらほらあった。

  • CやC++の指揮をウォッチウィンドウに入力することが出来ることや関数を呼び出すことが出来る
  • ウォッチウィンドウの中で式にサフィックスを付けることでデータを表示する方法を変更できる
    • ",d", ",x"というサフィックスはそれぞれ10進、16進でデータが表示されるようにする
    • ",n"(nは非負整数)はn個の要素を持つ配列として値を処理することができるようにする
  • データブレークポイント

2.3 プロファイリングツール

大まかに2種類ある

  • 統計的プロファイラ
  • 計測的プロファイラ

CやC++プログラマは全員、少なくとも目的とするCPUのアーキテクチャをそれなりに熟知していなければならない(p.91)

なるほどなぁ。