【Android】SwiftからのAndroid①　Android勉強

##概要
Android開発の勉強として
[はじめよう Android Studioでアプリ開発](http://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E3%81%86-Android-Studio%E3%81%A7%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA-%E6%B7%B1%E7%80%AC-%E6%AC%BD%E6%AD%A3/dp/4897979846)
を購入したので、その中で覚えておきたいことをまとめておこうとおもいます。
やっぱ本は買うとモチベーションが上がるからいいですね。
電子書籍も欲しいけど持ち運ぶ予定がないものは実際のペーパーに限る。
というか紙媒体買った時に電子データもくれればいいのに。

勉強予定
6/22
　21:30 〜 22:30 ○
6/23
　7:30　〜 8:30 ○
　21:30 〜 22:30 ○
6/24
　7:30　〜 8:30 ○
　21:30 〜 22:30  ○
計：約５時間
⇨　だいたい予定通りに完了。

本の内容は特にダメな部分が気になったところはありませんでした。
Javaがわからなくてもプログラマなら読めるってぐらいの入門書なのでそんなに他の本と差異はないんじゃないかと思います。
サンプルコードが見づらかった、かな。

##本について
Androidの開発入門書はいろいろなものが出ており、特にこれがいい！って感じのものが見つかりませんでした。
ぶったｙけどれも同じようなものかな、って思う（オイ）のでなるべく薄くて２、３日でさらっと確認できる内容のものを選びました。
208ページでAndroidStudioのインストールとかも説明されているので、サクッと概要を確認するにはいいですね。

###気になったこと
別に開発するOSはなんでもいいって書いてますが、本のWindows7の32bitで動かしてるみたいです。
別に気に入ったOS使うのがいいとは思いますが、もうすぐWindows10ってのに？？


##インストール等
諸々設定インストールでｐ27まで。読み飛ばします。

##Android関連基礎知識
###・用語
アクティビティ　⇨　UIViewController
ライフサイクル　⇨　UIViewController関連のイベントの流れ
リソース　⇨　リソース
ビュー　⇨　コントロール
レイアウト　⇨　StoryBoard
リソースID　⇨　画面だとStoryboardIDかな。iOSだとコントロールはOutlet接続しないとIDってつけないからかなり違いはある。
　困るのは違う画面でも同じIDを使っちゃだめらしいってこと。同じ画面ならわかるが違う画面ともかぶっちゃだめってなに？？

###・ソースファイルの表現
ソースファイルは大文字開始のキャメル。
僕は　機能 + 種類.javaってつけるようにする。
MenuActivity.java みたいな。
iOSはデフィルトでそんな感じになってますよね。

###・リソースファイル
xmlは小文字と_しか使えないからそれで命名。その他リソースも同じように命名する。
人の命名規則は参考になりますね。↓
http://seesaawiki.jp/aksoft/d/android%20%B3%AB%C8%AF%B5%AC%CC%F3
ていうか勝手にアクセスするときに画面ID.リソースIDってすればいいのに・・・・
僕は
ビューを3文字で表現_レイアウトを3文字で表現_レイアウト名
で行こうかな。

###・パッケージ
Swift使ってるとパッケージの衝突がアプリケーション単位では起こらないみたいなんで考えないですが、
パッケージの命名はリバースドメインで。
ドメインがない人向けのパッケージ名登録サービスとかもあるらしい。
http://www.java-conf.gr.jp/Package/naming/index.html
使ってるのかな・・・・

###・AndroidStudio基礎
エディタの行番号横のマークからジャンプができたりする。
関連XML、Override先、Override元など。
ブックマーク機能もあるが、僕は基本使わない。TODOコメントを使います。
//TODO 書き直す
って書いとけば
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/553e8f96-0fe5-45b0-9fa6-e5ad849a214a.png)
こんな感じで確認できる機能。
TODOを残したままリリースしないようにしましょう。

###・リファクタリング
右クリック、メニューバーから選択可能
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/37bdc950-55ce-ac68-00aa-c746df4efa6a.png)
名称の変更だけでも便利です。
Swiftも早く対応してくれないかな。検索して書き換えるのは面倒です。ミスるし。

###・基本的なソースについて
```java:MainActivity
//どうやら2.0をサポートライブラリとしてするか3.0以上かで
//SuperクラスがActivityかActionBarActivityか変わるみたい。
public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //必ず実行 指定のレイアウトを適用する
        setContentView(R.layout.activity_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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
```
リソースIDの指定は@ファイル名/リソースID

上の表示が邪魔な場合は

```xml:res/values/styles.xml
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>
```
このファイルのDarkActionBarをNoActionBarに変えればいんじゃないかな。

###・サポートライブラリについて
対象とする下限バージョンまででそれ以上のバージョンで追加された機能を使うためのライブラリ。
ファイル的にはGradle Scriptsのbuild.gradle(Module:app)を見る
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/ef7ffc32-79fe-2a5a-0cd3-3b0fa62a4b95.png)
SDKとのバージョンに差異が発生するとおかしくなるかもしれないらしい。
サポートライブラリがおかしくなった場合はSDKManagerからバージョンアップ可能
ツールバーの右から三番目。（僕のバージョンでいじらないと同じだと）
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/f35304a7-e6dd-003d-9a1d-65b33cad270d.png)
Extrasの二つをUpdate
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/e634d24c-399e-2150-d178-9cbc8dd2b3fa.png)

##UI関連
###・基本的なレイアウト
・リニアレイアウト
　縦、横にビューを配置するレイアウト。均等割とか簡単にできそう
・リレイティブレイアウト
　基本的な指定。相対位置指定
・テーブルレイアウト
　テーブル形式に表示したい時に使う
・フレームレイアウト
　ビューを重ねる時に使う。

###・単位
dp・dpi 1/160inch  一般的なサイズ
sp フォントサイズを指定するときの推奨単位
pt、px、mm、in 固定サイズの表現。混じると分かりづらくなるのでなるべく使わないかな。

###・ビューの大きさ
android:layout_widthとandroid:layout_heightに指定する。
・match_parent
 親レイアウトのサイズを継承する。fill_parentと同じだが、Android2.2以降はこっち推奨。
・wrap_content
　自動調整されたサイズ
・数値
親要素に対して相対的なサイズを指定する場合は上の二つのプロパティを0dpにして
android:layout_weightに割合を入れる。
またビューを追加していく方向はandroid:orientationにverticalかhorizontalを設定

###・レイアウトの入れ子
縦と横のorientationが必要な場合は入れ子にする。
一般的な入れ子はリニアレイアウトにリニアレイアウトを入れる。

###・ソースでレイアウト
setContentViewするレイアウトをソースコードで作成できる。
ViewをControllerに入れるのは望ましくないので基本的にはしない。
設定でユーザーが初期画面をカスタマイズできる、とかだと必要になってくるかも。

###・入れ子は無駄に使わない
画面に表示するビューは少ない方がレスポンスが良くなる。
リニアレイアウトは便利だが、少ないビューで表現できないかを考える。
ただ均等割するためにはリニアレイアウトがよい。
⇨個人的には10、20のビュー数できにする必要はないと思う。
　100単位になるとちょっとと思うが。

###・リソース
プロジェクトのresフォルダ内の情報
初期でないフォルダは右クリックから作成可能。
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/43271b04-8a70-1cc9-c903-61dc86c7f23a.png)

大体はフォルダ名を見ればわかる。
・menu
ActionBarのメニューを定義
・raw
ユーザの独自定義XML
assetsというフォルダをresと同レベルに配置してそこを使うように推奨されている
assetsフォルダにした場合は　⇨　InputStreamなどで読み込む。AssetManagerクラスを利用
rawフォルダにした場合は　⇨　Rでアクセス可能
なぜ推奨されているのかはわからないですが、、、、そこそこ大きなファイルを読み込むのはメモリを食うのかな？

##アクティビティ関連
###・ライフサイクル
特に覚えなくても、
「起動時にしてほしい処理がある」　⇨　起動時のライフサイクルを確認
でいいと思います。

###・ビューへのアクセス
Swiftなら画面とoutlet接続してアクセスするのが一番楽だと思いますが、
ビューを取得するにはfindViewByIdメソッドを利用する

###・アダプタ
ListViewなど実装しなきゃいけないイベントがある場合、
Swiftだとprotocolとして定義されていて、それをUIViewControllerでimplementsする
ってすると思います。　TableViewとか
Androidの場合はアダプタクラスを継承してクラスを作るようです。

クラスは増えますが、同じクラスないにイベントが増えるよりは断然いい気がします。

###・ツールバー
新しいバージョン対応で作成したときに画面上部にタイトルが出ている部分です。
xml定義でツールバーを定義して適用できるようです。
今回は利用予定がないので使うときに詳しく確認
http://qiita.com/kobakei/items/f17019f8b0a88c8e57f4


##イベント(ユーザアクション)関連
###・リスナー
イベントには処理をさせるリスナーが必要
・jQueryのセレクタ.on　イベント追加、みたいなやり方でonCreate時にリスナーを定義
⇨メソッドが肥大化
・リスナーインターフェースをimplementsして色々なビューから発生したイベントを一つのメソッドで処理する方法
⇨メソッドが肥大化　
・Xml定義でイベントと関連付けする方法　←　これ以外なくね？
⇨普通にDesignでonclickで書いたメソッドをActivityで実装すればオッケー。

###・アクティビティの状態保存
バンドルという仕組みを使えば、状態を保存することができる。
画面回転時などアクティビティが閉じて再度開かれるような場合は
onSaveInstanceStateでputInt(str,int) putLong(str,long) putString(str,str)などで状態をバンドルに保存
onRestoreInstanceStateでgetInt(str) getLong(str)などで状態をバンドルから復元
これはアクティビティ間の変数受け渡しにも使えるのかな？？
⇨使わないみたいですね。インテントを利用するようです。
http://techbooster.jpn.org/andriod/application/7190/

##インテント関連
###・明示的インテント
遷移先アクティビティ名を指定して遷移
１．マニュフェストファイルにアクティビティを追加
　⇨右クリックからActivityを追加すれば自動で追加されます。
２．Activityクラスで定義されているstartActicityメソッドにインテントを渡す

```java:MainActivity
public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void aMain_btn_move_click(View view){
        //遷移先クラスを引数にしてIntentを生成してstartActivitに渡すだけ
        Intent intent = new Intent(MainActivity.this,SecondActivity.class);
        //値を渡したい場合
        intent.putExtra("tag","value");
        startActivity(intent);
    }
}

public class SecondActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second_activity);
        //受け取った値の使い方
        Log.i("info",getIntent().getStringExtra("tag"));
    }
}

```

###・暗黙的インテント
別のアプリケーションをコールする。
今回は電話ぐらいですね

```java:MainActivity
Uri uri = Uri.parse(“tel:1111111111″);
Intent i = new Intent(Intent.ACTION_DIAL,uri);
startActivity(i);
```


##DB関連
僕はAjax通信でサーバのDBを利用するので、組み込みDB使わない。
内容は一度流すくらいで必要な時に再度確認する
・端末内の別アプリのテーブルにアクセスできるコンテンツプロバイダという機能がある。
　⇨複数自作アプリをインストールするなら面白い


##その他
###・プリファレンス
SwiftのNSUserDefaults機能ですね。
オブジェクトのシリアライズ、でシリアライズ。
Swiftと比べると保存も読み込みもコードが煩雑。
永続データを保存するファイル名の指定をしなきゃいけないのがいらないですね。
どうせそういうのはコモン関数としてまとめるんですが、いらない手間はやっぱりバグの元。

というわけでインテントの画面遷移をテストした時のソースに前回遷移日時をログに出すようにしたやつ。

```java:MainActivity.java
public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //必ず実行 指定のレイアウトを適用する
        setContentView(R.layout.activity_main);
    }

    public void aMain_btn_move_click(View view){
        //読み込み
        SharedPreferences pref = this.getSharedPreferences("shared", Context.MODE_PRIVATE);
        Log.i("sharedPreferences",pref.getString("pre_time", ""));

        //書き込み
        SharedPreferences.Editor editor = pref.edit();

        editor.putString( "pre_time", new Date().toString());
        editor.commit();

        //遷移先クラスを引数にしてIntentを生成してstartActivitに渡すだけ
        Intent intent = new Intent(MainActivity.this,MainActivity2Activity.class);
        intent.putExtra("tag","value");
        startActivity(intent);
    }
}

```

###・フラグメント
アクティビティを複数のフラグメントというコンテナで構成することで再利用とコードの肥大化を防ぐことが可能。
Swiftには同じような機能はないと思うので、モーダルウィンドウ（ダイアログなど）を利用するときに使うかな。
↓参考
[[Android] DialogFragmentを使ってダイアログを表示する](http://qiita.com/ux_design_tokyo/items/61ca074566d1570b37d3)

###・非同期処理
非同期処理をしている最中にアクティビティを終了したらヌルポが発生するとかめんどいな。
画面が回転した時もアクティビティの更新処理をしないとヌルポが発生するとかめんどいな。

非同期処理については標準の機能以外でライブラリを使った選択肢がないかも調べてこようと思います。


##自分ルールまとめ
・IDは別画面でも重複不可。ビューを表現_レイアウトを3文字で表現_レイアウト名　という命名規則とする
 (aMain_btn_update など)
・ファイルは機能 + 種類.java。MainActivity など
・フォントサイズはsp、その他はdpで大きさを指定するように心がける
・パフォーマンス向上のため(どんだけ違うかわからないが)valueオブジェクトにアクセスするときはgetter/setter経由にしない。

##その他
プロジェクト削除のために、プロジェクトが作成されるフォルダにはショートカットをどこかに用意。
Macならユーザのホームディレクトリ直下だからいいか・・・・

###・コンソールデバッグ
```java:MainActivity.java
        //Verbose トレース
        Log.v("tag", "msg");
        //Debug デバッグ
        Log.d("tag", "msg");
        //Info 情報
        Log.i("tag", "msg");
        //Warn 警告
        Log.w("tag", "msg");
        //Error エラー
        Log.e("tag", "msg");
```
５種類あるが、logcatで見たときに色分けされる３種類だけで十分だと思う。
i、w、eを利用するかな。
まぁデバッグだけでも十分かも。
僕は基本的にコンソールデバッグは削除するので、残しておく人がいるなら使うのかなぁ。

###・Logcat
いらない表示は削除する。
Logcatタブのしたのゴミ箱ボタンで表示clear！
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/08b92a94-4b58-6a60-c236-621642428c8e.png)

###・自動インポート
AndroidStudio > Preferences
Editor > General > Auto Import > Optimize import on the fly
にチェック
Editor > General > Auto Import > Add unambiguous on the fly
にチェック