Java

Posts filed under Java

USBテザリング設定がめんどくさいのでトグルするアプリを作ろうと思った調べ物のメモ

Filed in Android, Java, prog

 テザリングとかで検索するとノイズに死にそうになるのでAOSPのソース読んだ方が早かった件。
/packages/apps/Settings/src/com/android/settings/TetherSettings.java 541

private void setUsbTethering(boolean enabled) {
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm.setUsbTethering(enabled) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
mUsbTether.setChecked(false);
mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
return;
}
mUsbTether.setSummary("");
}

 この辺をパク......もといインスパイヤ......いやいや参考にすればよさそう。
***16:45追記***
 ConnectivityManager$setUsbTethering(boolean)はhideっぽい。。。

java.util.ListIteratorのドキュメントが嘘つきな件(´・ω・`)その後

Filed in Android, Java, prog

 javadocよく読んでたら

リストの反復子により、プログラマがいずれかの方向にリストをトラバースし、繰り返し処理時にリストを変更して、反復子の現在の位置をリストで取得することができます。ListIterator には現在の要素がありません。 そのカーソル位置は、previous() の呼び出しによって返された要素と、next() の呼び出しによって返された要素との間に常にあります。長さ n のリストの反復子は、次のキャレット (^) で示されるような、n+1 個の可能なカーソル位置を持ちます。

                  Element(0)   Element(1)   Element(2)   ... Element(n-1)

カーソルの位置: ^ ^ ^ ^ ^
 なるほど。Iteratorは要素を指してるわけじゃないのね(´・ω・`)
 嘘つきとか言ってごめんねjavadoc。

java.util.ListIteratorのドキュメントが嘘つきな件(´・ω・`)

Filed in Android, Java, prog

 なんかはまったのでメモ。

あるときバグがあった

 とある要素の次の要素とか前の要素の情報を知りたくて、ListIteratorが使えるコンテナだったのでListIteratorを使ってhasNext()、next()、hasPrevious()、previous()してたんですが、prebious()は前の要素を取ってくるのにnext()が次の要素をとってこない。
 そういえばイテレーションするときもnext()の返り値を使うのでそんなものかと思ったんですが、previous()と対称性が取れていないのが気に入らない。

そうだドキュメントを読もう!

 最近ドキュメントちゃんと読んでなくて苦労したのでjavadocを見に行ったら。

next

E next()

リスト内の次の要素を返します。このメソッドは、リストを反復するために繰り返し呼び出される場合と、前後に移動するために previous の呼び出しと組み合わされる場合があります。next と previous の呼び出しを交互に行うと、繰り返し同じ要素が返されます。

定義:
    インタフェース Iterator<E> 内の next

戻り値:
    リストの次の要素
例外:
    NoSuchElementException - 繰り返し処理で次の要素がない場合

 と書いてある。次の要素ちゃうやないかヾ(#`Д´)ノ
 一方previousは
previous

E previous()

リストの前の要素を返します。このメソッドは、リストを逆方向に反復するために繰り返し呼び出される場合と、前後に移動するために next の呼び出しと組み合わされる場合があります。next と previous の呼び出しを交互に行うと、繰り返し同じ要素が返されます。

戻り値:
    リストの前の要素
例外:
    NoSuchElementException - 繰り返し処理で前の要素がない場合

 と書いてある。その通り動いているので何も言えない(´・ω・`)
 javadocが正しいとするとAndroidのCopyOnWriteArrayListが返すListIteratorがおかしい。

そしてAndroidへ

 例によってICSのr1のソースを見てみるとCopyOnWriteArrayListのListIteratorはCowIteratorが返すらしい。CowIteratorのnextとpreviousの実装が以下の通り。

@SuppressWarnings("unchecked")
public E next() {
if (index < to) {
return (E) snapshot[index++];
} else {
throw new NoSuchElementException();
}
}
@SuppressWarnings("unchecked")
public E previous() {
if (index > from) {
return (E) snapshot[--index];
} else {
throw new NoSuchElementException();
}
}

 と、まさしく実装の通り動いてたということのようです。

おぼれる者はJDKをも掴む

 AndroidのListIteratorがjavadocに沿ってないのはわかった。じゃあJDKどうなの?
 これでJDKが同じ動きだとしたら僕はjavadocのことを許せそうにないよ......。
 ということでJDK6のソースを落としてきてCopyOnWriteArrayListこんにちわ。COWIteratorとか似たような名前のクラスを見つけて覗いてみたら。

public E next() {
if (! hasNext())
throw new NoSuchElementException();
return (E) snapshot[cursor++];
}
public E previous() {
if (! hasPrevious())
throw new NoSuchElementException();
return (E) snapshot[--cursor];
}

 神は死んだ。。。
 前にも誤訳的な何かがあったりしたしもうそろそろjavadocが信じられなくなってきたよママン。。。

追記

 JavaのIteratorは要素を指しているわけじゃないそうです。

Intent投げて返りが欲しいときの注意点

Filed in Android, Java, prog

 画像をギャラリーから取ってこようと思ってstartActivityForResult使ってごにょごにょやってたらonActivityResultが呼ばれたり呼ばれなかったりしたので調べてみたことをメモ。
 適当なActivityを起動して結果を貰いたいときにはstartActivityForResultを使う。

// 画像取得ボタンの実装
// Intentの帰りを受けるためにActivityクラス内で定義する
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 画像取得
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0);
}

 受け取る方は受け取りたいActivityにonActivityResultを書いとくと読んでもらえる。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK) {
Uri uri = (Uri)data.getData();
String imgFileName = uri.getPath();
(略)
}
}

 で、適当に作って適当に遊んでたらなんとなく動いたのでコードとか誰ともかぶらなさそうなのに変えようと思って変えてみた。

// 画像取得ボタンの実装
// Intentの帰りを受けるためにActivityクラス内で定義する
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 画像取得
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0xDEADBEAF);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0xDEADBEAF && resultCode == RESULT_OK) {
Uri uri = (Uri)data.getData();
String imgFileName = uri.getPath();
(略)
}
}

 でもこれだとonActivityResultが呼ばれない。なんでやねん。
 で、差を見て理由がわからなかったので調べてみた。
 まずstartActivityForResultのコードを見てみた。ソースはAOSPから拾ってきたICSのr1。
 ※markdownで書いてる都合上4スペースを1タブで変換してます。
Activity.java: startActivityForResult

Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}

 上記の通りstartActivityForResultではsendActivityResultで結果を返す。
 sendActivityResultが呼ばれるためにはexecStartActivityからActivityResultが返ってこないといけない。
 execStartActivityの中身を見てみると、ActivityResultオブジェクトを返すところが以下のようになっている。
Instrumentation.java: execStartActivity

final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}

 ActivityThreadが監視しているActivityMonitorの数だけ上記のコードが回されるんだけど細かいところはおいといて、returnのところを見るとリクエストコードが非負の整数でないと結果を返そうとしていない。
 リクエストコードはstartActivityForResultで渡している値なので、試したコードを再掲すると。

// 画像取得ボタンの実装
// Intentの帰りを受けるためにActivityクラス内で定義する
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 画像取得
intent.setAction(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 0xDEADBEAF);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0xDEADBEAF && resultCode == RESULT_OK) {
Uri uri = (Uri)data.getData();
String imgFileName = uri.getPath();
(略)
}
}

 ばっちりリクエストコードが負の整数!
 そりゃないぜセニョール! と思ってAndroid Developersを確認してみたら。。。
> Parameters
> intent The intent to start.
> requestCode If >= 0, this code will be returned in onActivityResult() when the activity exits.
 ばっちり書いてあった(ノ∀`)アチャー
 いつものことだけどドキュメントよく読めってことですね。サーセンwwwww

java.util.concurrentのドキュメントがひどい件(´・ω・`)

Filed in Java, prog

 ちょっとコンテナに用事があって、マルチスレッドなので色々気をつけるのもめんどくさくてjava.util.concurrentパッケージなんて調べてたんですが、APIドキュメントを読んでて意味不明な用語がありました。
日本語版Javadoc
 ConcurrentLinkedQueueの辺り。「リンクノードに基づく、アンバウンド形式のスレッドセーフなキューです」。
 アンバウンド形式って何?
 よくわからないので原文探してみた。
英語版Javadoc
 同じくConcurrentLinkedQueueの辺り。「An unbounded thread-safe queue based on linked nodes」。
 ん? 形式とかどこ? unboundedがアンバウンド形式?
 unboudedはboundedでない。詰まり有界ではないと言ってる気がする。誤訳なんちゃうのこれ。
 と思ったら結構有名みたいこの誤訳。直せよ(´・ω・`)


Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Oenology Post Formats
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Posts Calendar
Click to view/hide
2017年5月
« 12月    
 123456
78910111213
14151617181920
21222324252627
28293031  

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
アーカイブ
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
最近の投稿
Click to view/hide