勉強:動的にコントロールを作成する方法
静的に作るばかりだったので、動的にコントロールを作成するとどんな感じか調べました。
参考サイト
https://akira-watson.com/android/button-hardcoding.html
ふむふむ。
今電車で満員電車なので、
帰って速攻まとめます!
勉強:データバインディングライブラリ?
データバインディングライブラリ知らなかった。。。
ロジックとレイアウトのデータを結びつけるのに最低限のコードで済ませることができるのがこのデータバインディングライブラリ。
今までリストを表示する為に、プログラム上でレイアウトとデータを結び付ける処理が必要だったのですがそれを XML 内に記述ができます。
以下引用と調べた基本的なこと↓
使用可能環境
サポート ライブラリのため、Android 2.1(API レベル 7 以降)のすべての Android プラットフォーム バージョンでお使いいただけます。
データ バインディングを使うには、Android Plugin for Gradle 1.5.0-alpha1以降が必要です。
使用する為に
アプリでデータバイディングを使用するよう設定するには、
dataBinding
要素をアプリ モジュール内のbuild.gradle
ファイルに追加します。設定に使うコード スニペットは次のとおりです。
android {
....
dataBinding {
enabled = true
}
}
実際に使ってみよう♫
データ バインディング用のレイアウト ファイルは通常のレイアウト ファイルとは若干異なっており、最初にルート要素の layout タグがあり、その下に data要素、view のルート要素と続きます。この view 要素は、通常のレイアウト ファイルにおけるルート要素です。サンプル ファイルは以下のようになります。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>data 要素内の user variable で、このレイアウトで使用するプロパティを記述します。
<variable name="user" type="com.example.User"/>レイアウト内の式は、 "
@{}
" 構文を使った属性プロパティで記述します。これで、TextView のテキストが user の firstName に設定されました。<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>次にデータオブジェクトの指定をします。User クラスに Plain Old Java Object (POJO) を使用しているとします。
public class User {
public final String firstName;
public final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}このタイプのオブジェクトが持つデータは変更できません。アプリでは一度だけ読み込んで、その後はまったく変更がないデータを使用することが多くあります。また、JavaBeans オブジェクトを使うこともできます。
public class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
}データ バインディングの観点では、この 2 つのクラスは同等です。TextView の
android:text
属性に使われる@{user.firstName}
式は、先のクラス内でfirstName
フィールドに、後のクラス内でgetFirstName()
メソッドにアクセスすることになります。または、firstName()
メソッドが存在すれば、そのメソッドに解決されます。データのバインディングについてデフォルトでは、レイアウト ファイルの名前をパスカルケースに変換して、末尾に "Binding" をつけたものがバインディングクラスになります。上のレイアウト ファイルは
main_activity.xml
なので、MainActivityBinding
クラスが作成されます。このクラスにはレイアウト プロパティ(user
変数)からレイアウトのビューまでのすべてのバインディングが含まれ、バインディング式に値を適用する方法が指定されています。バインディングの作成はインフレート中に行うのが最も簡単です。@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
User user = new User("Test", "User");
binding.setUser(user);
}これで完了です。アプリを実行して、UI で Test User が見えることを確認してください。次のようにしても確認できます。
MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());ListView または RecyclerView アダプタ内でデータ バインディング アイテムを使う場合には、こちらの方法を使用することをお勧めします。
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
//or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
リスト、配列およびマップのアクセスについて
一般的なコレクションである配列、リスト、疎なリスト、マップには、便宜上、演算子
[]
を使ってアクセスします。<data>
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<variable name="list" type="List<String>"/>
<variable name="sparse" type="SparseArray<String>"/>
<variable name="map" type="Map<String, String>"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
…
android:text="@{list[index]}"
…
android:text="@{sparse[index]}"
…
android:text="@{map[key]}"
参考サイト:
勉強:thisとgetContextの違いについて
プログラムで
thisを使っているところもあったり
getApplicationContextも使っているところもあったり
違いはなんなのかなーーー?
と思ったので、確認。
以下引用
●Contextのライフサイクル
ApplicationContextはアプリケーションのライフサイクルと連動し、ActivityContextは
アクティビティのライフサイクルと連動しています。
つまり、2つはどちらもContextインスタンスではありますが、中身は全く異なるものに
なります。
ContextのライフサイクルについてはDeveloperページのgetApplicationContextが参考に
なります。
以下要約です。BroadcastReceiverを登録するregistReceiverを使用するケースにおいて...
・ActivityContextを使った場合
レシーバはActivityと関連付けて登録されます。システムはActivityが破棄される
前に登録したBroadcastReceiverがunregistReceiverされることを期待します。
もしunregistReceiverされなかった場合は、フレームワークがこれをクリーンナップし、
エラーログを出力します。
・ApplicationContextを使った場合
レシーバはApplicationと関連付けて登録されグローバルな状態となる。
そのためフレームワークがこれをクリーンアップすることがなく、unregistReceiverを
忘れると容易にリークしてしまいます。参考:http://developer.android.com/reference/android/content/Context.html#getApplicationContext()
Contextを渡す対象のAPIは、ActivityかApplicationどちらが良いのかについては、
ライフサイクルを意識することも重要であることが上記からわかります。
●Context保持によるメモリリーク問題
Contextに関するメジャーな問題としてメモリリークがあります。
前述からもわかるようにContextへの参照はActivityへの参照でもある可能性があります。
下記のようにActivityContextを長期間保持するようなコードは簡単にメモリリークを引
き起こす可能性があります。private static Context mContext; // ... mContext = activityInstance;ActivityContextはActivityのライフサイクルと連動していることを思い出してください。
private staticなmContextは、これを保持するActivityのライフサイクルが終了したとして
も、mContextによるActivityへの参照は破棄されず、メモリリークが発生します。
Contextへの参照を使用する場合に留意するべき点は下記となります。
- Contextの参照は関連するContextのライフサイクルに合わせる
(ApplicationContextならApplicationライフサイクルに、ActivityContextであれば
Activityのライフサイクルに合わせること)- 可能であればApplicationContextの使用を考える
- Activity内部に非staticなインナークラスの作成は極力避ける。
- 可能であればActivityへの参照は弱参照を用いる
Context参照がリークした場合、Activityとそれに紐付くインスタンス(特にViewやBitmap等)
が諸々リークするため、予想以上に大量のメモリリークとなる恐れがあります。
場合により、ガベージコレクタによるインスタンス回収が間に合わずOutOfMemory例外が
発生することもあります。(ガベージコレクタはメモリリーク保証しない)
Contextにまつわるメモリリーク問題のより詳細な情報は下記が参考になります。
http://developer.android.com/resources/articles/avoiding-memory-leaks.html
ActivityContextではメモリリークの可能性に考慮する必要があるのですね。
勉強:オブジェクトのクラス名を知りたいときは?
作業中にデバッグをしていたのですが
変数の型の確認の仕方がわかりにくかったので
もっとわかりやすい方法はないかなと思って調べました。
オブジェクトからクラスを取得します。
Object obj;
Class classObj = obj.getClass( );
そして、クラスのオブジェクトから名前を取得します。
String className = classObj.getName( );
ちゃんと取得できました><
参考サイト:
勉強:例外処理
Javaの例外処理について。
基本的なこと復習。
【例外処理の目的】
例外に対する対処を行うことで、致命的になりうる状態からの回復を図る。
【try-catch-finally文】
try 処理の記述
catch その対処(複数可能)
finally 最後に必ず行う処理(省略可能)
【throw文】
throws exception
例外を送出する
【例外クラス】
⭐︎Throwableクラス(最上位クラス)
ーErrorクラス(Throwableのサブクラス) -------> 捕捉の必要なし
ーExceptionクラス(Throwableのサブクラス) -------> 捕捉の必要あり
ーRuntimeException -------> 捕捉しなくてよい(コンパイルエラーにならない)
勉強:Androidアプリ開発者が知っておくべきこと
Androidアプリエンジニアとして今のプロジェクトに参画して
よーやく、一本改修完了したものが出来ました(^ ^)
内心めっちゃ嬉しいです!!!!!!
改修している中で、スマホアプリ開発はどんな点を考慮して設計やコーディングを行わなければならないのか(今までがデスクトップのアプリばかりなので)特徴を知りたかったので、検索していたら見つかったのが以下のサイト⬇️
参考にさせて頂きました!
10カ条的なもの。Androidのディベロッパーサイトを参考に作成されてます。
1、データの保存
(意図していない中断でもデータがしっかり保存されている)
2、生のデータのままやりとりしない事
3、ユーザーが違和感を覚えるような動作はしない、ユーザーの操作を妨げない
4、処理に時間がかかる場合はスレッドを使用する事
5、ひとつのActivityになんでも詰め込もうとしない事
6、全体的な調和を保つためにテーマを使用する事
7、多解像度に対応させる事
8、通信速度が遅い場合でも必ず確認をする事
9、特定のハードウェアのみに依存しない事
10、バッテリーの消耗を考慮する事
スマホアプリ独自の観点、いくつかありますね。
改めて、設計もコーディングも全てユーザーに対する思い遣りだと思いました❇️
様々な面を考慮しているアプリに出会えたら心温まりそうです笑
そんなアプリを作れるようになります。