2014/10/20

Android:知っておきたい標準API part.2

Intro

Android標準APIの中で知っておくと便利なものがいくつかある.
3rdParty製ライブラリを使うのもいいけれど, 標準で事足りるならそうしたい.
紹介するAPIについてはSupportLibraryを含んでおり, Javaパッケージは対象外.

Data structure

Property

android.util.Property<T, V>
Added in API level 14
URL: http://developer.android.com/reference/android/util/Property.html

A property is an abstraction that can be used to represent a mutable value that is held in a host object. The Property’s set(Object, Object) or get(Object) methods can be implemented in terms of the private fields of the host object, or via “setter” and “getter” methods or by some other mechanism, as appropriate.

ホストオブジェクトが持つ変更可能な値を表現するのに使える抽象的なプロパティ.

Usage

public abstract class FloatProperty<T> extends Property<T, Float> {
    public FloatProperty(String name) {
        super(Float.class, name);
    }

    /**
     * A type-specific override of the {@link #set(Object, Float)} that is faster 
     * when dealing with fields of type <code>float</code>.
     */
    public abstract void setValue(T object, float value);

    @Override
    final public void set(T object, Float value) {
        setValue(object, value);
    }
}

public static final Property<View, Float> X = new FloatProperty<View>("x") {
    @Override
    public void setValue(View object, float value) {
        object.setX(value);
    }

    @Override
    public Float get(View object) {
        return object.getX();
    }
};

CircularArray

android.support.v4.util.CircularArray<E>
URL: http://developer.android.com/reference/android/support/v4/util/CircularArray.html

A circular array implementation that provides O(1) random read and O(1) prepend and O(1) append

リングバッファ. O(1).

TypedValue

android.util.TypedValue
Added in API level 1
URL: http://developer.android.com/reference/android/util/TypedValue.html

Container for a dynamically typed data value. Primarily used with Resources for holding resource values.

動的型付けされたデータコンテナ. 主にリソース値を保持するために使用される.

Usage

// テーマの背景色取得
TypedValue t= new TypedValue();
getTheme().resolveAttribute(android.R.attr.colorBackground, t, true);
int id= typedValue.resourceId;
int color= getResources().getColor(id);

// dp⇒px換算
int padding = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()); 

Pair

android.util.Pair<F, S>
Added in API level 5
URL: http://developer.android.com/reference/android/util/Pair.html

Container to ease passing around a tuple of two objects. This object provides a sensible implementation of equals(), returning true if equals() is true on each of the contained objects.

“組”を表現するクラス. 格納する型は自由. オブジェクトをペアで管理したい場合に便利. Pair.equals()は”組”となっている双方のオブジェクトと等価である場合にtrueを返す.

Usage

Pair<String, String> pair = Pair.create("android3.0", "Honeycomb");
Log.d(TAG, pair.first);  // android3.0
Log.d(TAG, pair.second);  // Honeycomb

SparseArray

android.util.SparseArray<E>
Added in API level 1
URL: http://developer.android.com/reference/android/util/SparseArray.html

SparseArrays map integers to Objects. Unlike a normal array of Objects, there can be gaps in the indices. It is intended to be more memory efficient than using a HashMap to map Integers to Objects, both because it avoids auto-boxing keys and its data structure doesn’t rely on an extra entry object for each mapping.

スパースアレイ. SparseArrayはintをキーにしたマップオブジェクト. 通常の配列とは異なりインデックスに”隙間”を許容する. SparseArrayはHashMapよりも効率が良い.

Note that this container keeps its mappings in an array data structure, using a binary search to find keys. The implementation is not intended to be appropriate for data structures that may contain large numbers of items. It is generally slower than a traditional HashMap, since lookups require a binary search and adds and removes require inserting and deleting entries in the array. For containers holding up to hundreds of items, the performance difference is not significant, less than 50%.

SparseArrayはキーのルックアップにバイナリサーチを使用するため膨大なデータに対してのパフォーマンスはHashMapに劣る. エントリ数が100程であればパフォーマンス差は50%以下に収まる.

To help with performance, the container includes an optimization when removing keys: instead of compacting its array immediately, it leaves the removed entry marked as deleted. The entry can then be re-used for the same key, or compacted later in a single garbage collection step of all removed entries. This garbage collection will need to be performed at any time the array needs to be grown or the the map size or entry values are retrieved.

コンテナはキーの削除に最適化されている. エントリが削除された場合, すぐに配列をコンパクションするのではなく, 削除マーキングのみを行う. 削除マーカーのついたエントリは再利用されるかGCのタイミングで一括削除される. このGCはArrayのサイズ拡張やサイズ取得の際に実行される.

It is possible to iterate over the items in this container using keyAt(int) and valueAt(int). Iterating over the keys using keyAt(int) with ascending values of the index will return the keys in ascending order, or the values corresponding to the keys in ascending order in the case of valueAt(int).

ketAt(int)やvalueAt(int)を使えば, 配列内をイテレートできる.

Mapインターフェイスの利用を決める前にSparseArrayの利用を検討する.
SparseArrayのキーはint型に限定されており, SparseArrayはint型のキーを持つMap<Integer, Object>と置換可能.
Mapインターフェイスと比べ, SparseArrayは汎用性を犠牲にする代わりに高いパフォーマンスを実現している.
Map

Usage

SparseArray<String> sparseArray = new SparseArray<String>();
sparseArray.put(1, "value");
String str = sparseArray.get(1);

ArrayDeque

java.util.ArrayDeque<E>
Added in API level 9
URL: http://developer.android.com/reference/java/util/ArrayDeque.html

Resizable-array implementation of the Deque interface. Array deques have no capacity restrictions; they grow as necessary to support usage. They are not thread-safe; in the absence of external synchronization, they do not support concurrent access by multiple threads. Null elements are prohibited. This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue.

容量制限のない, 非スレッドセーフな, nullを許可しない, リサイズ可能なDeque実装. よくある”使う分だけキャパシティが増える”部類のArray. StackやLinkedListよりも高速に動作する.

Most ArrayDeque operations run in amortized constant time. Exceptions include remove, removeFirstOccurrence, removeLastOccurrence, contains, iterator.remove(), and the bulk operations, all of which run in linear time.

ArrayDequeへの操作は”ならし定数時間(amortized constant time)”で処理される.
remove, removeFirstOccurrence, removeLastOccurrence, contains, iterator.remove(), やbulkオペレーションは線形時間で処理される.

The iterators returned by this class’s iterator method are fail-fast: If the deque is modified at any time after the iterator is created, in any way except through the iterator’s own remove method, the iterator will generally throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

このクラスから得られるiteratorのメソッドはfail-fastに動作する. iterator取得後にdequeが変更されたり, iteratorのremoveメソッドを呼んだりするとConcurrentModificationExceptionを投げる. 並列で同時変更されたような場合にも即座にイテレート処理が失敗する.

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

ただし, 一般的に言われているものと同じく, 非同期への確実な保証は無く, fail-fastによるConcurrentModificationExceptionスローはベストエフォートで行われることに注意.

This class and its iterator implement all of the optional methods of the Collection and Iterator interfaces.

このクラスとiteratorは, CollectionおよびIteratorインタフェースのメソッドを実装している.

Pools

android.support.v4.util.Pools
URL: https://developer.android.com/reference/android/support/v4/util/Pools.html

Pools.SimplePool
非スレッドセーフなオブジェクトプール.
Pools.SynchronizedPool
スレッドセーフなオブジェクトプール.
public class MyPooledClass {
    private static final SynchronizedPool sPool =
            new SynchronizedPool(10);

    public static MyPooledClass obtain() {
        MyPooledClass instance = sPool.acquire();
        return (instance != null) ? instance : new MyPooledClass();
    }

    public void recycle() {
         // Clear state if needed.
         sPool.release(this);
    }
    . . .
}

Processor

Linkify

android.text.util.Linkify
Added in API level 1
URL: http://developer.android.com/reference/android/text/util/Linkify.html

Linkify take a piece of text and a regular expression and turns all of the regex matches in the text into clickable links. This is particularly useful for matching things like email addresses, web urls, etc. and making them actionable. Alone with the pattern that is to be matched, a url scheme prefix is also required. Any pattern match that does not begin with the supplied scheme will have the scheme prepended to the matched text when the clickable url is created. For instance, if you are matching web urls you would supply the scheme http://. If the pattern matches example.com, which does not have a url scheme prefix, the supplied scheme will be prepended to create http://example.com when the clickable url link is created.

文字列と正規表現を受け取り, 正規表現にマッチするテキストをリンカブルテキストに置き換える. 一般的にはeメールアドレスやWebアドレスなどに対して使用される. パターンはURLスキームの接頭語にマッチする必要がある. もしスキームを持たずにマッチさせた場合, リンカブルテキストを生成する際に付与させる必要がある. 例えばWebアドレスにマッチさせたい場合はhttp://を指定する. example.comをパターンマッチさせた場合は, リンカブルテキストを作成する際にhttp://example.comとなるようにhttp://を頭に付与する.

Linkify.TransformFilter

android.text.util.Linkify.TransformFilter
Added in API level 1
URL: http://developer.android.com/reference/android/text/util/Linkify.TransformFilter.html

TransformFilter enables client code to have more control over how matched patterns are represented as URLs. For example: when converting a phone number such as (919) 555-1212 into a tel: URL the parentheses, white space, and hyphen need to be removed to produce tel:9195551212.

TransformFilterを使用すると, 特定のパターンにマッチした文字列のURL表現をコントロールできる.
例えば, (919) 555-1212にマッチした文字列に対してスペースなど余分なものを削除してtel:9195551212とすることができる. Linkifyはtechboosterに詳しくある http://techbooster.org/android/ui/13512/

Rfc822Tokenizer

android.text.util.Rfc822Tokenizer
Added in API level 1
URL: http://developer.android.com/reference/android/text/util/Rfc822Tokenizer.html

This class works as a Tokenizer for MultiAutoCompleteTextView for address list fields, and also provides a method for converting a string of addresses (such as might be typed into such a field) into a series of Rfc822Tokens.

このクラスは, アドレスリストフィールドのMultiAutoCompleteTextView用のTokenizerとして機能する. また(フィールドに入力されるような)アドレス文字列を一連のRfc822Tokenに変換するメソッドを提供する.

Rfc822Token

android.text.util.Rfc822Token
Added in API level 1
URL: http://developer.android.com/reference/android/text/util/Rfc822Token.html

This class stores an RFC 822-like name, address, and comment, and provides methods to convert them to quoted strings.

Rfc822TokenにはRFC822-likeのname, address, commentが格納され, これらをquoted stringに変換するメソッドも提供する.

Rfc822Token[] tokens 
        = Rfc822Tokenizer.tokenize("Foo Bar (something) <foo@google.com>");
assertNotNull(tokens);
assertEquals(1,tokens.length);
assertEquals("foo@google.com",tokens[0].getAddress());
assertEquals("Foo Bar",tokens[0].getName());
assertEquals("something",tokens[0].getComment());

Patterns

android.util.Patterns
Added in API level 8
URL: http://developer.android.com/reference/android/util/Patterns.html

Commonly used regular expression patterns.

よく使われるいくつかの正規表現Patternが定義されている(IANA top-level domains, Phone number(looks like.), web url etc…).

Usage

m = Patterns.EMAIL_ADDRESS.matcher(str).matches();
assertTrue("メールアドレスチェック", m);

m= Patterns.TOP_LEVEL_DOMAIN.matcher("com").matches();
assertTrue("トップレベルドメインチェック", m);

m = Patterns.WEB_URL.matcher("http://www.google.com").matches();
assertTrue("WebURLチェック", m);

m = Patterns.WEB_URL.matcher("ftp://www.example.com").matches();
assertFalse("不正なプロトコル", m);

m = Patterns.IP_ADDRESS.matcher("1234.5678.9.0").matches();
assertFalse("不正なIP", m);

m = Patterns.PHONE.matcher("(123) 456-7890").matches();
assertTrue("電番チェック", t);

Others

AndroidException

android.util.AndroidException
Added in API level 1
URL: http://developer.android.com/reference/android/util/AndroidException.html

Base class for all checked exceptions thrown by the Android frameworks.

Android Frameworkが投げたことを意味する例外. AndroidExceptionを継承したサブクラスは次の通り.

IntentFilter.MalformedMimeTypeException
This exception is thrown when a given MIME type does not have a valid syntax.
IntentSender.SendIntentException
Exception thrown when trying to send through a PendingIntent that has been canceled or is otherwise no longer able to execute the request.
PackageManager.NameNotFoundException
This exception is thrown when a given package, application, or component name cannot be found.
PendingIntent.CanceledException
Exception thrown when trying to send through a PendingIntent that has been canceled or is otherwise no longer able to execute the request.
RemoteException
Parent exception for all Binder remote-invocation errors
Settings.SettingNotFoundException
-
DeadObjectException
The object you are calling has died, because its hosting process no longer exists.
TransactionTooLargeException
The Binder transaction failed because it was too large.

LogPrinter

android.util.LogPrinter
Added in API level 1
URL: http://developer.android.com/reference/android/util/LogPrinter.html

Implementation of a Printer that sends its output to the system log.

System logを出力するPrinterの実装. LogCat内部で使用されている.

EventLog

android.util.EventLog
Added in API level 8
URL: http://developer.android.com/reference/android/util/EventLog.html

Access to the system diagnostic event record. System diagnostic events are used to record certain system-level events (such as garbage collection, activity manager state, system watchdogs, and other low level activity), which may be automatically collected and analyzed during system development.

システム診断イベントレコードへのアクセスクラス. システム診断イベントにはシステムレベルのイベント(GC, ActivityManagerState, watchdog, 低次レイヤーイベントなど)が含まれている. このイベントは自動収集されてシステム開発に活かされる.

This is not the main “logcat” debugging log (Log)! These diagnostic events are for system integrators, not application authors.

これはLogcatのようなアプリのためのログシステムではない.

Events use integer tag codes corresponding to /system/etc/event-log-tags. They carry a payload of one or more int, long, or String values. The event-log-tags file defines the payload contents for each type code.

イベントには整数タグコードが使用され, /system/etc/event-log-tagsに対応している. ペイロードは1つ以上のint, long, Stringの値で構成され, event-log-tagsファイルには各タイプコードに対応するペイロードの内容が定義されている.

EventLogはadb logcatのeventsバッファから収集するか, DDMSのイベントログタブから参照できる.

IntentSender

android.content.IntentSender
Added in API level 4
URL: http://developer.android.com/reference/android/content/IntentSender.html

A description of an Intent and target action to perform with it. The returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.

Intentを実行するIntentSender. IntentSenderのオブジェクトを他アプリケーションに渡すことで, あなたのアプリケーションに変わって他アプリがIntentを後から実行できるようになる.

By giving a IntentSender to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity). As such, you should be careful about how you build the IntentSender: often, for example, the base Intent you supply will have the component name explicitly set to one of your own components, to ensure it is ultimately sent there and nowhere else.

IntentSenderを他アプリケーションに渡すことはIntent実行に必要な権限やアイデンティティまで渡すことと同義である. よくある方法としては, 自身のコンポーネントを指定した明示的IntentをセットしたIntentSenderを渡して, Intentを受け取った自コンポーネントで想定されたSenderからのリクエストかをチェックする.

A IntentSender itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application’s process is killed, the IntentSender itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of IntentSender (same operation, same Intent action, data, categories, and components, and same flags), it will receive a IntentSender representing the same token if that is still valid.

IntentSender自体はSystemによって記述されるTokenを単純に参照するものである. つまり, IntentSenderを生成したプロセスがkillされてもなお有効であることを意味する. もしアプリ起動後に再度同じIntentSender(同じoperation, intent action, data, category, component, flag)を取得した場合, 有効であるなら同じtokenを受け取ることになる.

Instances of this class can not be made directly, but rather must be created from an existing PendingIntent with PendingIntent.getIntentSender().

このクラスは直接生成するのではなく, PendingIntent.getIntentSender()から取得すること.

CancellationSignal

android.os.CancellationSignal
Added in API level 16
URL: http://developer.android.com/reference/android/os/CancellationSignal.html

Provides the ability to cancel an operation in progress.

処理のキャンセル要求を表現するクラス. これをサポートしたクラスにシグナル送信することでキャンセル要求を発出できる. ContentProviderや, AsyncTaskLoaderがこれをサポートしている.

参考: Android:CancellationSignalで処理を中断する

// Client
try {
    Cursor cursor = getContentResolver().query(
            Uri.parse("content://yuki.mycontentprovider"),
            new String[] { "_id" }, null, null, null, mCancelSignal);
} catch (OperationCanceledException ex) {
    // do something.
}

// ContentProvider
@Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder,
        CancellationSignal cancellationSignal) {
    SQLiteDatabase db = mDataBaseHelper.getReadableDatabase();
    Cursor c = db.query(false, "test", projection,
            selection, selectionArgs, null, null, sortOrder, null,
            cancellationSignal);
    ... 略 ...
}

以上.