Android開発お勉強
はじめてのAndroidプログラミング第5版やってて躓いたところメモ
進捗はCHAPTER09まで終わったところ
環境:Android Studio 4.2.1
Unresolved reference: が出たらactivity_main.xmlを確認
UI作成時、ビューに付けるidを間違えてないか?
フラグメントを使うときはAndroidManifest.xmlの編集が必要
CHAPTER07から登場
こんな感じのエラーが出たら、
Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit value for
android:exported
when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.
app/manifests/AndroidManifest.xml を開いて、
<activity>タグのところに
android:exported="true" を追加
android:exported が何者なのかは公式リファレンスを参照。
あまり理解できてないけど、テキスト通りにやってるうちはインテントフィルタ(<intent-filter/>)が
あるから、深く考えずに android:exported="true" を追加しておけば問題なさそう。
Vue CLIで開発
上記の続き。vue-routerも必要だった。
ところでブログ上Vue.jsソースのハイライトが残念になるのはどうしたら良いんだろう…。
環境
vue-router
Vue.jsでSPA(シングルページアプリケーション)を作成するためのプラグイン。「このURLが来たらこのソースを表示」というのを定義していく感じ。
元のプロジェクトはVue CLIで作ってあるため vue add router でインストール。Vue CLI を使っていない場合は npm install vue-router で。
本当は vue create でプロジェクト作成時にManuallyを選択した先でRouterを設定しておくのがベストだったと思う。
変更をコミットしといたら?という警告はスルー。
ヒストリーモードの設定を聞かれるのでyesで設定。この設定でURLの方式が変わるらしい。
$ vue add router WARN There are uncommited changes in the current repository, it's recommended to commit or stash them first. ? Still proceed? Yes ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
インストールが完了すると、srcディレクトリ下にrouterディレクトリ、viewsディレクトリができている。
動作確認してみる。
$ npm run serve
トップに「Home」「About」のリンクができており、画面遷移できるようになっている。
昨日追加したボタン群が消えたな?と思ったらApp.vueが自動で書き換わっていた。
作りかけの状態からvue-routerをインストールする際は気をつけよう。
ソースを見てみる
main.js にはrouterの定義が追加されている。
ちょっとimportの並び順にもやっとするけれどひとまず放置。
import Vue from 'vue' import App from './App.vue' import { BootstrapVue, IconsPlugin } from 'bootstrap-vue' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue/dist/bootstrap-vue.css' import router from './router' Vue.config.productionTip = false Vue.use(BootstrapVue) Vue.use(IconsPlugin) new Vue({ router, render: h => h(App) }).$mount('#app')
App.vue からはHelloWorld.vueを読み込んで表示する処理がなくなり、「Home」「About」のリンクが書かれている。スタイル部分は省略。
<template> <div id="app"> <div id="nav"> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view/> </div> </template>
HelloWorld.vue を読み込んで表示する処理はviews内のHome.view にある。
<template> <div class="home"> <img alt="Vue logo" src="../assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </div> </template> <script> // @ is an alias to /src import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', components: { HelloWorld } } </script>
で、router内のindex.jsはこんな感じ。
path: にURL(http://localhost:8080以降の部分)を設定。
name: は設定しなくても実は動く。
component: にソースの場所を設定。Home のようにimportしておいてから設定しても良いし、Aboutのように直接書いても良い。
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
name: の設定を活用する場合は、<router-link>の書き方が変わる。
App.vueが以下のようになる。スタイル部分は省略。
<template> <div id="app"> <div id="nav"> <router-link to="/">Home</router-link>| <!-- nameを利用した書き方。:to は v-bind:to の略 --> <router-link :to="{ name: 'About' }">About</router-link> <!--<router-link to="/about">About</router-link> 元の書き方 --> </div> <router-view /> </div> </template>
サンプルだとかえって面倒な記述になったけれど、URLが長く複雑になる大規模な開発では効力を発揮するはず。
BootStrapVue導入
GWだし自粛中だしフロントエンド系な感じの何か作りたい。とりあえずvue.jsとBootstrap使いたい。
というとてもふわふわした考えでまずは環境構築。
環境
ubuntu 18.04
Visual Studio Code
インストール
やり方は何種類かあるみたいだけれど、インストーラーをダウンロードしてくるのが一番わかりやすい。.debだから正確にはパッケージと呼ぶべきなのかな。
ダウンロードしたらダブルクリックか apt install でインストール。
$ sudo apt install ./Downloads/code_1.44.2-1587059832_amd64.deb
アプリケーション一覧を見ると Visual Studio Code のアイコンができている。
拡張機能
Japanese Language Pack
日本語化。
インストールが完了すると右下に再起動のポップアップが現れるので、再起動すると日本語になる。
Vetur
Vue.jsのソースにハイライトをつけてくれたりエラー表示してくれたり。Vue.jsやるなら必須だと思う。
読み方は「ベター」で良いんだろうか…。
npm
Node.jsのパッケージ管理ツールみたいな説明をよく見るけれど、Node.jsに限らず大抵のWeb系ツールのインストールでお世話になる。
とにかくnpmが使えないと後のインストールがはかどらない。
1.aptでnodejs、npmをインストール
$ sudo apt install nodejs 39.6 MB を 22秒 で取得しました (1,802 kB/s) E: http://jp.archive.ubuntu.com/ubuntu/pool/main/p/python2.7/python2.7-minimal_2.7.17-1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://jp.archive.ubuntu.com/ubuntu/pool/main/p/python2.7/python2.7_2.7.17-1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://security.ubuntu.com/ubuntu/pool/main/l/linux/linux-libc-dev_4.15.0-91.92_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/libitm1_8.3.0-26ubuntu1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/libatomic1_8.3.0-26ubuntu1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/liblsan0_8.3.0-26ubuntu1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/libtsan0_8.3.0-26ubuntu1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/libmpx2_8.3.0-26ubuntu1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/libquadmath0_8.3.0-26ubuntu1~18.04_amd64.deb の取得に失敗しました 404 Not Found [IP: 160.26.2.187 80] E: いくつかのアーカイブを取得できません。apt-get update を実行するか --fix-missing オプションを付けて試してみてください。
エラーが出てしまったけれども一旦スルー。apt-get updateしてからnpmをインストール。
$ apt-get update $ sudo apt install npm $ nodejs -v v8.10.0 $ npm -v 3.5.2
aptでインストールできるバージョンはNode.jsが8.10.0、npmが3.5.2。
実際npmを使うに当たってバージョンが古いことで何が困るのかはよくわかっていない。が、とりあえず最新版をインストールしておくのが間違いないと思う。
2.nをインストール
nはnodeのバージョン管理をするものらしい。
$ sudo npm install -g n /usr/local/bin/n -> /usr/local/lib/node_modules/n/bin/n /usr/local/lib └── n@6.5.1
/usr/local/bin/n にシンボリックリンク作ったよ、向き先は/usr/local/lib/node_modules/n/bin/n だよ、nのバージョンは6.5.1だよ。とのこと。
3.nから最新のNode.jsとnpmをインストール
最新バージョンをインストールするn stable と長期サポート版をインストールするn lts がある。LTSにしてみた。
$ sudo n lts installing : node-v12.16.3 mkdir : /usr/local/n/versions/node/12.16.3 fetch : https://nodejs.org/dist/v12.16.3/node-v12.16.3-linux-x64.tar.xz installed : v12.16.3 (with npm 6.14.4) Note: the node command changed location and the old location may be remembered in your current shell. old : /usr/bin/node new : /usr/local/bin/node To reset the command location hash either start a new shell, or execute PATH="$PATH"
apt install でインストールしたnode(old)が /usr/bin/node にいて、n でインストールしたnode(new)が /usr/local/bin/node にいるらしい。
インストールしたらバージョン確認!…が、そんなものはないと言われてしまった。
$ npm -v bash: /usr/bin/npm: そのようなファイルやディレクトリはありません
ターミナルを閉じて開き直してみたら普通に見れた。
$ npm -v 6.14.4 $ node -v v12.16.3 $ n --version 6.5.1
4.aptでインストールしたNode.jsとnpmをアンインストール
紛らわしいのでaptでインストールした方のNode.jsとnpmは削除しておく。
$ sudo apt remove nodejs $ sudo apt remove npm
Vue CLI
Vue.jsでの開発環境構築を支援してくれるツール。
インストールはnpmでサクッとできる。バージョン確認は --version で。
$ sudo npm install -g @vue/cli $ vue --version @vue/cli 4.3.1
Vue CLIの説明はこちらが分かりやすかった。
qiita.com
BootStrapVue
Vue.jsのためのBootStrap。とてもわかりやすい名前。
プロジェクト作成
まずはVue CLIプロジェクトを作成。 sample の部分がプロジェクト名(ディレクトリ名)になるのでお好みで。
$ vue create sample
特にこだわりがないのでdefaultを選択。
TypeScriptやVuexなど使いたいものがある場合はmanuallyを選択して設定する。(よくわかってない)
次に、プロジェクト内にBootStrapVue と BootStrap をインストールする。
$ cd sample
$ npm install bootstrap-vue bootstrap
とりあえず実行してみる。
$ npm run serve
Vue CLI のサンプルが表示される。
使ってみる
必要なファイルをインポート。main.jsを下記のようにする。
import Vue from 'vue' import App from './App.vue' import { BootstrapVue, IconsPlugin } from 'bootstrap-vue' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue/dist/bootstrap-vue.css' Vue.config.productionTip = false Vue.use(BootstrapVue) Vue.use(IconsPlugin) new Vue({ render: h => h(App), }).$mount('#app')
サンプルページにボタンを表示してみる。公式ページの Components → Button のソースをコピペ。
<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png" /> <HelloWorld msg="Welcome to Your Vue.js App" /> <!-- BootStrapVueの書き方 --> <div> <b-button variant="primary">Primary</b-button> <b-button variant="secondary">Secondary</b-button> <b-button variant="success">Success</b-button> <b-button variant="danger">Danger</b-button> <b-button variant="warning">Warning</b-button> <b-button variant="info">Info</b-button> <b-button variant="light">Light</b-button> <b-button variant="dark">Dark</b-button> </div> <br /> <!-- BootStrapの書き方 --> <div> <button type="button" class="btn btn-primary">Primary</button> <button type="button" class="btn btn-secondary">Secondary</button> <button type="button" class="btn btn-success">Success</button> <button type="button" class="btn btn-danger">Danger</button> <button type="button" class="btn btn-warning">Warning</button> <button type="button" class="btn btn-info">Info</button> <button type="button" class="btn btn-light">Light</button> <button type="button" class="btn btn-dark">Dark</button> </div> </div> </template> <script> import HelloWorld from "./components/HelloWorld.vue"; export default { name: "App", components: { HelloWorld } }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
こうなる。
@RunWith(Enclosed.class)
久しぶりにテストクラスを書いたらしょぼいところでつまずいてしまったのでメモ。
@RunWith(Enclosed.class) とは
テストクラスを構造化したい場合に利用する。
例えばこんなクラスがあって、
public class Sample { public Sample() { } public String hoge() { return "hoge"; } public boolean huga(int num) { if(num >= 0) { return true; } return false; } }
メソッドごとにテストクラスを書きたい、みたいな場合には@RunWith(Enclosed.class)をつけてメソッドごとのインナークラスを作成すれば良い。
import static org.junit.Assert.*; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; @RunWith(Enclosed.class) public class SampleTest { /** * hogeメソッドのテスト */ public static class hogeTest { @Test public void test1() { Sample target = new Sample(); String result = target.hoge(); assertEquals("hoge", result); } } /** * hugaメソッドのテスト */ public static class hugaTest { @Test public void test1() { Sample target = new Sample(); boolean result = target.huga(0); assertTrue(result); } @Test public void test2() { Sample target = new Sample(); boolean result = target.huga(-1); assertFalse(result); } } }
実行時には全部実行するか特定のテストクラスだけ実行するかを選べる。
つまずきポイント
インナークラスがないのにのに@RunWith(Enclosed.class) をつけてしまうとテストが動かない。
import static org.junit.Assert.*; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; @RunWith(Enclosed.class) //構造化していない(インナークラスがない)のに記述 public class SampleTest { @Test public void hoge_test1() { Sample target = new Sample(); String result = target.hoge(); assertEquals("hoge", result); } @Test public void huga_test1() { Sample target = new Sample(); boolean result = target.huga(0); assertTrue(result); } @Test public void huga_test2() { Sample target = new Sample(); boolean result = target.huga(-1); assertFalse(result); } }
エラーだったりExceptionが発生したりはせず、でも実行数は0という事態になる。
ubuntuにeclipseをインストール【再】
久しぶりにubuntuでeclipseを起動したら何やら挙動不審…。
というわけでインストールし直す。
環境
何が悪かったのか
インストール時の作業はこちら。 hotate-issimo.hatenablog.com
Ubuntuソフトウェアからインストールしたところ、編集できないディレクトリ /snap にインストールされてしまった。そこをなんとか日本語化しようと色々やったのが駄目だった気がする。
最初から自由に編集できるディレクトリにインストールしておけばよかったのでは…!
おそらく、何らかカスタマイズするるつもりのツールはUbuntuソフトウェアからインストールしては駄目なんだろうな。
アンインストール
Ubuntuソフトウェアを起動し、eclipseの削除を選択。
削除できたことを確認してみる。
$ ls /snap -a . bin gimp gnome-characters gtk-common-themes .. core gnome-3-28-1804 gnome-logs README core18 gnome-calculator gnome-system-monitor $ ls /home/useraaa/ -a . .gnupg .ssh Music .. .java .sudo_as_admin_successful Pictures .ICEauthority .local .swt Public .bash_history .m2 .thunderbird Templates .bash_logout .mozc .tooling Videos .bashrc .mozilla .viminfo bk .cache .pki Desktop eclipse-workspace .config .pleiades Documents examples.desktop .eclipse .profile Downloads snap
/snap/eclipse は削除されたけれど、ユーザーディレクトリ内にある eclipse-workspace はそのまま残っていた。 後々問題になると嫌なので、中身を別フォルダに退避して削除した。
$ rm -r eclipse-workspace $ ls -a . .gnupg .ssh Music .. .java .sudo_as_admin_successful Pictures .ICEauthority .local .swt Public .bash_history .m2 .thunderbird Templates .bash_logout .mozc .tooling Videos .bashrc .mozilla .viminfo bk .cache .pki Desktop examples.desktop .config .pleiades Documents snap .eclipse .profile Downloads
インストール
インストーラー取得
こちらからインストーラーを取得。最新の2019-12が出ていたのでこちらをインストールする。 www.eclipse.org
ダウンロードしたインストーラー.tar.gzを展開すると、中身はこんな感じ。
インストール
eclipse-inst を実行
EnterPrise Java Deveropers を選択
特にこだわりはないので、デフォルトのまま INSTALL
JDKがインストールされていない状態だと、上の『Java1.8+VM』欄は空白かも?
Accept Now を選択
Accept を選択
もろもろチェックをつけて Accept Selected を選択
インストールが完了したら、LAUNCH で起動してみる。
インストール成功! なんだかスプラッシュ画面格好いいな!
日本語化
プラグイン取得
中身はこんな感じ
設定
デフォルトのままインストールしていれば、eclipseのホームは ユーザーディレクトリ/eclipse/jee-2019-12/eclipse になるはず。
あとはプラグインの readme_pleiades.txt のとおりに設定していけばOK。
plugins、features ディレクトリーをコピー
$ cp -r /home/useraaa/Downloads/plugins /home/useraaa/eclipse/jee-2019-12/eclipse $ cp -r /home/useraaa/Downloads/features/ /home/useraaa/eclipse/jee-2019-12/eclipse
eclipse.ini の末尾に2行追記
-Xverify:none -javaagent:/home/useraaa/eclipse/jee-2019-12/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
起動してみる
$ /home/useraaa/eclipse/jee-2019-12/eclipse/eclipse -clean
できたー!
ちなみに…
-javaagent をフルパスで指定していないと起動時にこんなエラーになる。気をつけよう!
Error opening zip file or JAR manifest missing : plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar Error occurred during initialization of VM agent library failed to init: instrument Gtk-Message: 23:07:39.604: GtkDialog mapped without a transient parent. This is discouraged.
メニューから起動できるようにする
ここにeclipseが表示されるようにしたい。
デスクトップエントリーというものをどうにかすれば良いらしい。
デスクトップエントリー作成
キー項目の意味なんかはこちらを参考にした。 wiki.archlinux.jp
$ cd /home/useraaa/.local/share/applications/ $ vim eclipse.desktop
eclipse.desktopの中身はこんな感じで。
[Desktop Entry] Type=Application Name=Eclipse Exec=/home/useraaa/eclipse/jee-2019-12/eclipse/eclipse Icon=/home/useraaa/eclipse/jee-2019-12/eclipse/icon.xpm Terminal=false
保存してメニューを見てみるとアイコンができていた。やったぜ!
つまずき箇所
Pathという項目があるから、ここにeclipseのパスを書いてExecとIconはそれぞれのファイル名だけ書けばいけるんだろうなー(下記の状態)、と思ったけれどそんなことはなかった。
[Desktop Entry] Type=Application Name=Eclipse Path=/home/useraaa/eclipse/jee-2019-12/eclipse/ Exec=eclipse Icon=icon.xpm Terminal=false
デスクトップエントリーが正しく書けていないとメニューに表示されないようなので、うまくいかない場合は記述内容を見直そう。
読書:プログラマが知るべき97のこと
啓発本?的なものが読みたいなと思い手に取ってみた。
2010年に初版発行と古い本だけれども、普遍的なことが語られているので特に古さは感じない。手元にあるのが2018年に出た12刷だったりするので、けっこう人気みたい。
個人的に特にグッときたのはこのあたり
『07 共有は慎重に』
同じような処理を安易に共通化すると依存関係が生じて、1行変更するだけでも影響範囲が広がっちゃうよ、というお話。
まさに今この状況になっている。業務Aのために処理を追加する必要があるけども業務Bと業務Cには影響が出ちゃいけない、みたいな。
きちんと仕様を理解していない人がほぼ同じ処理でしょ、くらいのノリで共通化してはいけない。あと、仕様を理解している人は全力で共通化を止めて欲しい、共通化すればコード量削減になるしまあ良いか、と流されてはいけない。
『37 バグレポートの使い方』
「バグの発生方法と頻度」「本来の仕様」「実際の動作」は必ず書こう、というお話。
現場ではあまり明文化されておらず、自分の中でもやもやしていたことが説明されていてスッキリした。
バグの発生方法が分からないけれども障害チケットが起票されたからには調査しないわけにもいかず…で調べてみたら起票者のミスだったり。この時は用意したテストデータが不正だったのが原因なんだけれども、このデータを使いました!というのが書かれていればもっと早く解決できたはず。
他にも、他チームにヘルプで入った際に、バグなのはわかったけれどどうなるのが正解なんだ…と途方に暮れてしまったり。ちゃんと仕様が分かっている箇所なら本来の仕様を省略してあっても困らないけれど、新規参入の人でも最低限ゴールが見える状態になっているのが望ましいのかなと思う。
当たり前の事、と言われればそうかもしれないけれど、当たり前の事を当たり前にやっているのかが大切なわけで…気を引き締めよう。