投稿

Application と ViewModel の使い分けはどうすればいいのか?

Activity か Fragment を基点として「ある程度安定して動けばいいや」的スタイルで Android プログラミングを続けてきたので、Application はたまに使用例に従って採用していただけで、主体的に判断して使用したことはない。それで最近、ボンヤリと、Android プログラミングに関する情報を調べていたら、Activity のライフサイクルに巻き込まれない、 モデル(ビジネスロジック)的なデータは Application で扱う(格納する)べし みたいな話があって、ちょっと気になっていた。 その辺りは特に他のアイデアがなく、自分は Activity や Fragment でそのままデータを持たせていたので、onSaveInstanceState / onRestoreInstanceState で Bundle を使って退避してライフサイクルの輪廻転生をくぐり抜けられるようにしたり、SharedPreferences を使って逐次 Persistent なデータとして退避するなどして、力技で対抗していた。 Application を使えば、もうちょっと楽にできたのかなと思って気にしていたところ、 ViewModel なんてものも存在することを(今さら)知り、Application と ViewModel の使い分けってどうなんだろう? と思った。もちろん、継承関係からしてそもそも存在意義が全然違うのだろうけど、「Activity のライフサイクルの輪廻転生をくぐり抜けて過去・現在・未来の三世を通じた一貫した記憶を保つ」という意味で、Application を使うか ViewModel を使うかということに、どういう違いがあるのだろうかということだ。 まあそもそも、Application の方は、ライフサイクルというよりは、スコープ的なグローバル性やシングルトン性の方がテーマとなるのだろうし、ViewModel の方はライフサイクルまで Activity に巻き添えを食らわないというだけで、あくまでも Activity / Fragment に従属したローカルなインスタンスなんだろうけど。 書いているうちに、全然違うよね〜、誰も疑問に思わないよね〜、という気持ちになってきた……。 Model とは言っても、ViewModel で扱う...

Firebase Crashlytics

Firebase 推しの Google に従って Firebase Crash Reporting を導入したと思ったら、少し経ったら Google 都合で Crashlytics に変更を余儀なくされることになった。 Crash Reporting に比べて、結構、設定が複雑で、適当に一つ目に導入したアプリのプロジェクトを見て二つ目にも導入しようとしたら、意外と抜けていたので、公式の説明を一つ一つ確認してやるのが無難だと思った。Google の日本語のチームが糞なのか、単に日本語のサイトが糞なのかどちらかわからないが、Crashlytics の公式のページが Android を選択しても iOS の説明しか表示せず、内容以前にサイトの表示機能自体がバグバグだし、そういう問題がない場合でも Developers サイトの日本語版の情報は内容的にも大体が、古くて腐敗した有害ですらある情報だったりもするのであくまでも 英語の公式ページ を参照すべし。 また上記の通りに設定しても、依然として LogCat に Crashlytics 絡みの謎のエラーログが出ていたので、 StackOverFlow で調べた ところ、 Firebase のコンソールでアプリの署名の SHA-1/SHA-256 のハッシュ値を登録しておいてその設定 JSON ファイルを使う必要がある とのこと。鳴り物入りで Crashlytics へ変更された割には、まだ全然洗練されてないような気がするのだが……。(この件も、英語版ではちゃんと修正されていた。日本語版情報が腐っているだけの話のようだ) リンク集 firebase 全般 1: Web コンソールでプロジェクトを作成し(場合によっては App nickname と Debug signing certificate SHA-1 を登録し)、google-services.json をダウンロードして、モジュールのルートに置く; 2: プロジェクトレベルの Gradle とモジュールレベルの Gradle に一定の設定を追加する; 3: モジュールレベルの Gradle に必要な implementation 設定を追加する。 firebase-analytics モジュールレベル Gradle のimplementation 設定...

ANDROID_ID の Android 8.0 における仕様変更

ANDROID_ID が Android 8.0(Oreo: API-26)において仕様変更されたようだ。このため、従来のように ANDROID_ID がデバイス固有の ID と思って扱っていると、意図しない結果につながる。 Android ID In O, Android ID (Settings.Secure.ANDROID_ID or SSAID) has a different value for each app and each user on the device. Developers requiring a device-scoped identifier, should instead use a resettable identifier, such as Advertising ID, giving users more control. Advertising ID also provides a user-facing setting to limit ad tracking. Additionally in Android O: The ANDROID_ID value won't change on package uninstall/reinstall, as long as the package name and signing key are the same. Apps can rely on this value to maintain state across reinstalls. If an app was installed on a device running an earlier version of Android, the Android ID remains the same when the device is updated to Android O, unless the app is uninstalled and reinstalled. The Android ID value only changes if the device is factory reset or if the signing key rotates between uninstall and...

WebView と HTTPS

HTTPS の証明書の有効期限が切れていたりしてエラーになる場合、WebView では読み込みがされないという(デフォルトの)挙動結果となるようだ。 また、エラーの場合でも強制的に読むようにオーバーライドもできるようである: 👉 Android WebView not loading an HTTPS URL

縁起説

アッサジ長老がサーリプッタ長老に語ったとされる句: Ye dhammā hetuppabhavā, tesaṃ hetuṃ Tathāgato āha tesañca yo nirodho; evaṃvādī Mahāsamaṇo. なぜか「諸法(事象・現象)が縁によって生じる」と解釈され、いわゆる「縁起説」として定着している。仏教の最も基本的な思想とされているが、この句の解釈は実は違うのではないか? Ye dhammā は Tathāgato āha に係っているだけで、実質は hetuppabhavā, tesaṃ hetuṃ, tesañca yo nirodho と(四諦のうちの)三諦を言ったに過ぎない。「Ye dhammā Tathāgato āha」は単に、「如来が語られたこの法は」と言っていて、「方法(dhammā)」という単語に、事象・現象などと多義的な解釈を持たせて、何やら大げさな神秘性を帯びた体系に、仏教の位置付けを飛躍させる必要はなかったのではないかと思う。 hetuppabhavā は「原因から生まれる諸々の(複数形)もの」tesaṃ hetuṃ は「その原因(単数形)」、tesañca yo nirodho は「それら(原因から生まれた諸々のもの)が消滅するところの(原因に係る)」 つまり、全体を訳すとこうなる。 如来が語られたこの法というのは、 (一つの)原因から生じた諸々の結果(複数)と、それらの原因(単数)、 (その原因はまた)諸々の結果を消滅させる原因でもあるところのもの。 それ(その方法)を大沙門は説かれた。 結果が複数で、それら複数の結果の原因となっているものが単数であるというのが一つのポイントである( 参考 )。 そのように、神秘性の方向性なしに素直な話として解釈してみれば、その前後のコンダンニャ長老、サーリプッタ長老、モッガラーナ長老らの、最初に正見を得た時の常套句である、「生じるものは、滅する性質の云々」とイマイチ訳のわかったようなわからないようなセリフも、本来はどういうものであったかどうかが見えてくる気がする。つまり: 「諸々の結果を生じている一つの(大元となる)原因がわかれば、それは反対に諸々の結果を一挙に消滅させる鍵ともなるわけだ」 そういうやりとりだとすると、四諦→コンダンニ...

日商簿記 3 級

イメージ
今日、第 152 回の 日商簿記 3 級試験 を受験してきた。 自分は、商業高校出身でも、経済・商学系の大学出身でもない門外漢の理系人間。ゼロからの完全独学独習。勉強期間は 2 ヶ月足らず。 解答時間は 35 分程度だった。満点狙い。 3 級はおそらく、商業高校の生徒なら、多くが在学中に 2 年生くらいの時に(高得点とは限らないまでも)合格してしまうのではないだろうか? 2 級の方は経済・商学系の大学では推薦入学の要素にもなることから、商業高校の生徒でも優秀な生徒に限られるとは思うが。 使用した参考書・問題集は以下の 2 セットのみ: 公認会計士よせだあつこのパブロフ流シリーズ 『簿記教科書 パブロフ流でみんな合格 日商簿記3級 テキスト&問題集 第4版』(2019-02-20) 『簿記教科書 パブロフ流でみんな合格 日商簿記3級 総仕上げ問題集 第3版』(2019-02-20) 中央経済社の検定簿記シリーズ 『検定簿記講義 3 級 商業簿記〔2019年度版〕』(2019-02-27) 『検定簿記ワークブック 3 級 商業簿記』(2019-02-27) まとめ 今 152 回から 3 級は大きく試験範囲が変わり、自営業向けだった内容が株式会社向けとなったので、参考書・問題集はちゃんと新しいもので揃えるというのがポイント。 上に紹介した 2 セットのものは、それぞれかなり性格が異なった毛色のものを組み合わせた。おそらく、それぞれが強調する視点が異っているので、片方だけでは、独学での満点狙いは厳しかったかもしれない。 結果 満点逃しました……orz 敗因 「455」を「445」と書き写しミスしたこと「のみ」による。これが満点を奪った、たった一つのミス。 書き間違えた「445K」をベースに貸倒引当金の計算も行っているため、そこから派生した項目も影響を受けて、おそらく別の採点対象の項目も巻き添えを食ってしまい、計 -6 点となったものと思われる。 合計が合わなくなるミスであれば、気付くことはできたはずなのだが、これは貸借対照表と損益計算書の両方にセットで使われる値だったため、矛盾が発生せずに、気付くことにはならなかった。 パブロフ式の著者さんでも見直し無しで解答時間が 48 分( 参考 )のところを、自...

MySQL データベースのバックアップ

表のエクスポート MySQL で表を丸ごとファイルにエクスポートする場合は、SELECT * FROM table を応用した INTO OUTFILE file による指定が基本となる: SELECT * INTO OUTFILE '/mnt/data/tmp/sampletable.tsv' FROM Sample_Table; ファイル形式は TSV(TAB 区切りでエスケープ方式が TAB 区切り特有のルールとなっている。CSV よりも遥かにスマートなフォーマット) ファイルは上書き不可なので、既存の同名ファイルが存在してはならない。 参考: MySQL 8.0 リファレンス (出力先ファイル名や、表名などは一例) エクスポートした表のインポート 反対にエクスポートした表をデータベースにインポートして書き戻す場合は次の命令が対応する: LOAD DATA LOCAL INFILE '/mnt/data/tmp/sampletable.tsv' INTO TABLE Sample_Table; エクスポートしたファイルを編集してデータエントリーを付け加えてインポートし直すと、元から存在したエントリーについては warning となり skip されるだけなので、気にせずにエントリーの追加用途に利用できる。 また、一部エントリーを元のデータに追加するのではなく、元のデータを修正して上書き更新したい場合であれば、TRUNCATE 命令を使って一旦消去してから全体丸ごと LOAD し直せばよい: TRUNCATE TABLE Sample_Table; LOAD DATA LOCAL INFILE '/mnt/data/tmp/sampletable.tsv' INTO TABLE Sample_Table; 参考:SHOW WARNINGS LOAD の結果、追加したデータに何らかの不備があって WARNING が発生した場合は、直後に SHOW WARNINGS すれば WARNING 内容を確認することができる。 SHOW WARNINGS; データベースのバックアップ 表の定義を含めたデータベースのバックアップは mysqldump コマンドを使う。こ...

Python で Google SpreadSheets を CSV にエクスポート

OAuth2 を含めた gspread の説明は公式のリファレンス(👉 1 、👉 2 )が参考になる。 また、CSV へのエクスポートについては Stack Overflow の記事(👉 Saving a google spreadsheet as a csv )を参考にした。 from oauth2client.service_account import ServiceAccountCredentials import gspread import csv JSON_KEYFILE = 'XXX.json' SPREADSHEET = 'テスト' WORKSHEET = 'sheet1' CSV_FILENAME = 'test.csv' SCOPE = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive'] serviceAccountCredentials = ServiceAccountCredentials.from_json_keyfile_name(JSON_KEYFILE, SCOPE) gspreadClient = gspread.authorize(serviceAccountCredentials) worksheet = gspreadClient.open(SPREADSHEET).worksheet(WORKSHEET) with open(CSV_FILENAME, 'w', newline='') as csvFile: writer = csv.writer(csvFile) writer.writerows(worksheet.get_all_values())

OpenWrt on WZR-HP-AG300H: nginx

イメージ
デフォルトの uHTTPd に替えて当初は Apache を入れようとしたが、マトモに動かなかった(公式のフォーラムでもそのような話が出ていた)。それで諦めかけていたのだが、どうしても Virtual Host を実現したいので、nginx を入れてみることにした。 公式 wiki に従って(PHP は使う予定がないので、該当部分は飛ばした。)入れてみると、とても軽快で、さらに設定も /etc/nginx/nginx.conf に記載された内容で行うだけという、とてもシンプルなものだった。歴史が長過ぎて半ば妖怪化しつつあるような Apache と違って、一発で気に入った。 Virtual Host は nginx.conf で server {} を追加するのが基本。 ただし、デメリットも 2 点発生した。 デフォルトでは HTTPS に対応していない CGI に対応していない OpenWrt 用 nginx の HTTPS 化 nginx 自体は HTTPS に対応しているのだが、OpenWrt 標準の nginx モジュール(.ipk)は HTTPS 非対応でコンパイルされているため、自前で nginx モジュールをコンパイルして用意しなければならない。大変だったが(nginx の HTTPS 化そのものについては、 一箇所 しか情報が存在しなかったほど、情報が限られていた)、最終的に実現できた。 【下準備】Linux で git を使える環境を整える: apt install git-core build-essential libssl-dev libncurses5-dev unzip gawk zlib1g-dev subversion libncurses5-dev gcc-multilib flex gettext mercurial git clone して、ソースコードを用意する: git clone https://git.openwrt.org/openwrt/openwrt.git cd openwrt このままでは有無を言わさず最新のソースコードが使われてしまい、ライブラリーとのバージョンの不整合が起こるため、自分の使っている stable バージョンに絞って checkout する。 git check...

OpenWrt on WZR-HP-AG300H: SFTP サーバー

/etc/config にある設定ファイルを扱う程度ならば scp コマンドで十分だが、WWW サーバーとしてセットアップすると、ファイルのアップロード作業が頻繁に発生するようになってくるので、FileZilla のような FTP クライアントを使ってファイルのやりとりが出来るように SFTP サーバーをセットアップしておくことにする。openssh-sftp-server をインストールする。 もちろん、SSH の拡張的な SFTP ではなく、ちゃんとした FTP サーバーの方をインストールする手もある。👉 FTP servers