WebView.goBack

goBackで一つ前のページに戻ることができる・・・。

WebView | Android Developers

resの下にmenuフォルダつくって、その下にmain.xmlを用意し、

今回はメニューにgoBackのアイテムを追加・・・。

strings.xmlは、

"GoBack"と表示されるアイテム・・・。

MainActivity.javaで、

メニューの準備・・・。
R.id.menu_gobackだったら、webView.goBackで戻る・・・。

f:id:BG1:20170228105130p:plain

Yahoo!トップから、

f:id:BG1:20170228105153p:plain

スポナビトップ、

f:id:BG1:20170228105213p:plain

野球・・・。
ここで、

f:id:BG1:20170228105233p:plain

メニューのGoBackを押すと、

f:id:BG1:20170228105255p:plain

スポナビトップに戻るので、

f:id:BG1:20170228105411p:plain

もう一回押すと、

f:id:BG1:20170228105523p:plain

トップに戻る・・・。
ただし、URLバーは変わらない・・・。
shouldOverrideUrlLoadingには来ないようだ・・・。

Sample/android/WebView/goBack/src/WebView at master · bg1bgst333/Sample · GitHub

pipe

pipeは、プロセス間通信に使う名前なしパイプを生成するシステムコール・・・。

Man page of PIPE

引数には要素数2のint型配列を渡す・・・。0番目が読み込み用、1番目が書き込み用に使われる・・・。
主に、親プロセスと子プロセスの間でのプロセス間通信に使う・・・。
今回は、親プロセスも子プロセスも読み書き両方するので、これをさらに2つ用意する・・・。

pipe.cで、

pipe1は親が書き込むパイプ(子は読み込む)、pipe2は子が書き込むパイプ(親は読み込む)・・・。

fork前に自分のプロセスIDを取得・・・。

pipeでpipe1とpipe2を作成・・・。

forkします・・・。
失敗した場合はすべてのパイプを閉じて終了・・・。

forkした後の、親の処理・・・。
親子のプロセスIDを出力したら、3秒後にpipe1[1]に書き込み・・・。
"parent written!~"という感じで、~を書き込んだことを出力・・・。
で9秒待つ・・・。
その後、pipe2[0]を読み込む・・・。
"parent read!~"の後に、子が書き込んだ文字列が入っているはず・・・。
読み込んだ文字列を出力したら、子が終るまでwaitで待つ・・・。
で子のプロセスID、親のプロセスIDを出力・・・。

子はプロセスIDを出力したら、6秒後にpipe1[0]を読み込む・・・。
"child read!~"で、親からの書き込み文字列が見える・・・。
その3秒後にpipe2[1]に書き込んで、
"child written!~"で書き込んだ文字列を見せる・・・。
で5秒待って子は終了・・・。

実行すると、

$ gcc pipe.c -o pipe
$ ./pipe
pid = 14378
I am parent!, getpid = 14378, child = 14379
I am child!, getpid = 14379

最初はこうで、3秒後に、

parent written!, I am parent! Are you child?

また3秒後に、

child read!, I am parent! Are you child?

また3秒後に、

child written!, I am child! Are you parent?

また3秒後に、

parent read!, I am child! Are you parent?

で最後は、

14379 finished!
getpid() = 14378
$

こんな感じ・・・。
親が書き込んだ文字列が子供側で読めているし、子が書いた文字列も親が読めてるので、プロセス間通信になってる・・・。

Sample/unixsyscall/pipe/pipe/src/pipe at master · bg1bgst333/Sample · GitHub

インデクサ

インデクサは、プロパティを拡張したようなもので、オブジェクトのメンバに配列のような添字でアクセスできる・・・。
さらに、プロパティと同じく、getとsetでアクセス制限もできる・・・。
オブジェクトの中に、配列やリストのようなコレクションをメンバとしておいといて、それをオブジェクトの外からアクセスするようなときに使う・・・。

Class1.csを追加し、

Class1のコンストラクタで、配列の大きさsizeを引数に取る・・・。
そのsizeの分の配列intArrayを生成・・・。メンバにsizeをセットしておく・・・。

インデクサは、

<戻り値型> this[<添字型> <添字変数>]

で定義・・・。
上のgetでは、生成した配列の範囲外だったらエラーで-1を返し、範囲内ならintArray[index]の値を返す・・・。

下のsetでは、indexだけじゃなく、値が負の場合もエラー・・・。範囲内かつ値が0以上なら、値をintArray[index]に入れる・・・。

MainClass.csは、

Class1のオブジェクトc1を生成・・・。
コンストラクタに5を渡しているので、要素数5の配列が内部で生成されている・・・。

値の設定・・・。
添字が-3、添字が100、代入する値が-5の場合はエラー・・・。

c1のそれぞれの値を取得し、vに代入・・・。
添字が-2、15の場合はエラー・・・。
c1[4]は設定の時点でエラーなので値がセットされていない・・・。

c1とvの値を出力・・・。

invalid!(index < 0)
invalid!(index > size - 1)
invalid!(value < 0)
invalid!(index < 0)
invalid!(index > size - 1)
c1[0] = 1
c1[1] = 0
c1[2] = 8
c1[3] = 0
c1[4] = 0
v[0] = 1
v[1] = -1
v[2] = -1
v[3] = 8
v[4] = 0
続行するには何かキーを押してください . . .

設定でエラーが出ていないところはc1に0以外の値がセットされている・・・。
取得でエラーが出ている場合は-1がセットされている・・・。
v[4]はc1[4]の値がセットされずに取り出されたので0・・・。

Sample/cs/Indexer/Indexer/src/Indexer at master · bg1bgst333/Sample · GitHub

usingステートメント

これまで、Disposeによるリソース解放は、finallyで手動で行うような形になっていた・・・。
usingステートメントを使うと、IDisposableインターフェイス実装オブジェクトについては、finallyがなくても自動でリソース解放してくれる・・・。

CustomReader.csで、

ReadAllのtry-catch-finallyを外してみる・・・。

その代わり、MainClass.csでは、

usingの括弧の中に、CustomReaderの生成処理を書いている・・・。
そして、次のブロックの中で、ReadAllなどの読み込み処理をしている・・・。
usingブロックを抜けると、失敗しようが成功しようが、括弧の中で生成したオブジェクトのリソース解放処理Disposeは勝手に呼ばれる・・・。
ただし、usingとtry-catchは独立しているので、tryでの例外が起きそうな処理、発生した時のcatchでの例外処理は必要・・・。
なので、このようになっている・・・。

test1.txtだけの場合、

Error: ファイル 'C:\Project\Cloud\github.com\Sample\cs\usingStatement\usingState
ment\src\usingStatement\usingStatement\bin\Debug\test2.txt' が見つかりませんでし
た。
Dispose
sr1 closed!
続行するには何かキーを押してください . . .

finallyがなくてもDisposeが呼ばれている・・・。
test2.txtもあった場合は、

cr.text1 = ABCDE
cr.text2 = XYZ
Dispose
sr2 closed!
sr1 closed!
続行するには何かキーを押してください . . .

この場合もDisposeが呼ばれている・・・。

実は、StreamReaderなどのリソース生成解放処理がいるようなクラスはだいたいIDisposableが実装されている・・・。
なので、実際にはusingを使えば勝手にDisposeの解放処理が呼ばれるので、Disposeの処理を実装することはあまりないともいえる・・・。

Sample/cs/usingStatement/usingStatement/src/usingStatement at master · bg1bgst333/Sample · GitHub

IDisposable

IDisposableは、割り当てられたアンマネージドリソースを解放する機構を実装するためのインターフェイス・・・。

IDisposable インターフェイス (System)

リソースを明示的に解放しないといけないクラスにDisposeメソッドを実装し、この中で解放処理を実行するようにする・・・。

CustomReader.csを追加し、

ファイル名を2つ受け取るクラスのコンストラクタを定義・・・。

ReadAllで2つのファイルのストリームを連続して開く・・・。
開けたら、publicなtext1、text2に格納・・・。
例外ならエラーメッセージを出力・・・。
finallyでDisposeメソッドを呼び出すようにする・・・。

Disposeメソッドでは、"Dispose"と出力し、そのあとはそれぞれのストリームが開いていたら閉じている・・・。
finallyで呼ばれているので、成功でも失敗でもDisposeが呼ばれ、ストリームリソースが解放される・・・。

MainClass.csは、

"test1.txt"、"text2.txt"をCustomReaderで開く・・・。
読み込めたらtext1、text2を出力・・・。

test1.txtだけなら、

Error: ファイル 'C:\Project\Cloud\github.com\Sample\dotnet\IDisposable\IDisposab
le\src\IDisposable\IDisposable\bin\Release\test2,txt' が見つかりませんでした。
Dispose
sr1 closed!
続行するには何かキーを押してください . . .

となり、test2.txtもあれば、

Dispose
sr2 closed!
sr1 closed!
cr.text1 = ABCDE
cr.text2 = XYZ
続行するには何かキーを押してください . . .

となる・・・。
成功でも失敗でもDisposeを呼んでいる・・・。

Sample/dotnet/IDisposable/IDisposable/src/IDisposable at master · bg1bgst333/Sample · GitHub

finally

finallyは、tryブロックの中で例外が発生しても発生しなくても実行すべき処理を書く場所・・・。
今回は、2つのファイルを連続して読み込んで内容を出力・・・。
2つ目で例外が発生しても、1つ目のファイルを閉じる処理は実行するような形にする・・・。
MainClass.csで、

tryブロックで、StreamReaderで"test1.txt"を開いて、ストリームはsr1に格納・・・。
sr1.ReadToEndでテキストの内容が読み込まれてtext1に格納・・・。
Console.WriteLineでtext1の内容を出力・・・。
これを"test2.txt"でも同様に・・・。

catchは、ex.Messageを出力しているだけ・・・。

finallyは、"finally"といったん出力・・・。
そのあと、それぞれのストリームがnullでなければ、Closeで閉じて、"~ closed!"という感じで閉じたことを出力・・・。

f:id:BG1:20170226211920p:plain

test1.txtだけ存在する場合は、

text1 = ABCDE
Error: ファイル 'C:\Project\Cloud\github.com\Sample\cs\finally\finally\src\final
ly_\finally_\bin\Release\test2.txt' が見つかりませんでした。
finally
sr1 closed!
続行するには何かキーを押してください . . .

こうなる・・・。
finallyでsr2は失敗してnullなので閉じなくていいが、sr1は成功しているのでCloseで閉じている・・・。

f:id:BG1:20170226212339p:plain

test2.txtも存在する場合は、

text1 = ABCDE
text2 = XYZ
finally
sr2 closed!
sr1 closed!
続行するには何かキーを押してください . . .

こうなる・・・。
finallyでどちらもCloseで閉じている・・・。

こんな感じで成功しても失敗しても終了処理をする必要がある場合は、finallyに書く・・・。

Sample/cs/finally/finally/src/finally_ at master · bg1bgst333/Sample · GitHub

move(utility)

代入は、実質的にはオブジェクトのコピーである・・・。

obj = func(); // funcは右辺値なので一時オブジェクトをobjにコピーすることになる.

例えば、上のような場合にobjやfunc()の戻り値がint型ならまだしも、これが大きなクラスオブジェクトのコピーとなると、コピーコストも大きい・・・。
しかも、func()は右辺値であり、一時オブジェクトであるから、コピー後は不要・・・。いずれ破棄される存在・・・。コピーをすること自体無駄に思える・・・。

このように、一時オブジェクトの内容を別のオブジェクトに渡したい場合は、コピーではなく、所有権を移動する形(ムーヴ)にすればコピーコストも発生しない・・・。
C++11のutilityヘッダにあるstd::moveを使うと、あるオブジェクトから別のオブジェクトに内容をムーヴできる・・・。

右辺値参照・ムーブセマンティクス - cpprefjp C++日本語リファレンス
move (utility) - cpprefjp C++日本語リファレンス

std::moveは右辺値だけでなく、左辺値にも適用できる・・・。
今回は変数やオブジェクトなどの左辺値に対して、std::moveを使って別の変数やオブジェクトに所有権を移動する・・・。
するとどうなるか・・・。

int型のval、std::stringのstr、int型std::vectorのvec_iを宣言・・・。

val, str, vec_iに適当に値を代入したり、追加したりしてみる・・・。

いったん出力・・・。
vec_iは値だけでなくsizeも・・・。

std::moveにval, str, vec_iを渡して、戻り値をnew_val, new_str, new_vec_iとして、これらに所有権を移動する・・・。

すでに所有権のない無効なval, str, vec_iと新しい所有者new_val, new_str, new_vec_iの内容を出力・・・。

最後に、val, str, vec_iをいじってみる・・・。

実行すると、

$ g++ move.cpp -o move -std=c++11
$ ./move
val = 10
str = ABCDE
vec_i = 1, 2, 3
vec_i.size() = 3

val = 10
str =
vec_i.size() = 0
new_val = 10
new_str = ABCDE
new_vec_i = 1, 2, 3
new_vec_i.size() = 3

val = 20
new_val = 10
str = XYZ
new_str = ABCDE
vec_i[0] = 10
vec_i.size() = 1
new_vec_i = 1, 2, 3
new_vec_i.size() = 3
$

new_val, new_str, new_vec_iの方に内容が移動しているようにみえる・・・。
valの10は残っているように見えるけど、これはたまたままだ参照できているだけ・・・。
明け渡した以上、val, str, vec_iとnew_val, new_str, new_vec_iは独立している・・・。
所有権を明け渡したあとのオブジェクトに適当に値を入れたりしてみる・・・。
独立してるから、val, str, vec_iの値にnew_val, new_str, new_vec_iが引っ張られることは無い・・・。
いちおう、動くけど、実際は所有権を明け渡した後のオブジェクトの動作は未定義だか不明だか・・・。まあ、本来はやらないほうがいい・・・。

Sample/cpp/utility_move/utility_move/src/utility_move at master · bg1bgst333/Sample · GitHub