awacleberryの備忘録

アナログ人間のデジタル日記。

【Android】WebView にキャッシュをさせない方法

サイト更新後すぐに反映させたい場合などに、WebView がキャッシュを表示してしまうと困る。

WebView にキャッシュをさせないようにするには、CacheMode に LOAD_NO_CACHE を指定する。

WebView wv = (WebView)this.findViewById(R.id.webview);
wv.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);

【Android】View の id とエントリ名の変換

エントリ名から id を取得

hoge というエントリ名から、R.id.hoge という id の数値を取得するなら、

int viewId = getResources().getIdentifier("hoge", "id", getPackageName());

この viewIdfindViewById(viewId) できる。for で連番しているエントリ名などから View を取得するのに便利。

id からエントリ名を取得

逆に、id の数値からエントリ名を取得するなら、

String viewIdStr = getResources().getResourceEntryName(viewId);

View から getId() とかで id さえ取得していれば、それを上記のようにエントリ名へ変換して正規表現でチェックとかできる。

他のリソース

View の id 以外でもできる。

int strId = getResources().getIdentifier("hoge", "string", getPackageName());

注意点

getIdentifier について、ドキュメント曰く、

Note: use of this function is discouraged. It is much more efficient to retrieve resources by identifier than by name.

オススメできない方法とのこと。

getIdentifier

Mac の ターミナルで tree を表示

tree をインストー

brew install tree

tree を表示

当該ディレクトリで、

tree

パスを指定するなら、

tree .

など。日本語が文字化けする際は、

tree . -N

でOK。表示するディレクトリの深さをしていするなら、

tree -L LEVEL

次のような感じに表示される。

.
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets
│   ├── fonts
│   ├── images
│   ├── javascripts
│   └── stylesheets
├── eyeglass-exports.js
└── package.json

パスを書く必要がある際には便利。他、使いそうなオプションは、

オプション
-a 隠しファイルも表示
-d ディレクトリのみ表示
-P 正規表現にマッチするものを表示
-F ディレクトリ末尾にスラッシュを表示
-o 書き出し

Android の apk 出力で Unsupported major.minor version 52.0 エラー

出力する apk ファイルの量が多いので、コマンドラインから gradle 使ってビルドをすることが多いけど、今回急に次のエラーが出て戸惑った。

A problem occurred evaluating project ':app'.
> java.lang.UnsupportedClassVersionError: me/tatarka/RetrolambdaPlugin : Unsupported major.minor version 52.0

結論だけ言えば、java8 を使えば解消される。 以下が詳しくて助かった。

Androidアプリのビルドで「Unsupported major.minor version 52.0」のビルドエラーが発生する

webpack をサクッと使う手順


webpack の基本操作 にて述べた方法で、効率良く開発環境を整える手順を改めてまとめておく。

要件は、

  • js モジュールの統合と単一書き出し
  • sass の 統合と css 単一書き出し
  • compass の読み込み
  • js, css のミニマイズ
  • js, css の map ファイルの生成
  • ES6 -> ES5 トランスパイル(コンパイル
  • jquery の読み込み
  • watch で変更を監視

完成後のディレクトリ構成(ビルド前)は次のようになる。

project/
    ├── _css
    │     ├── entry.sass
    │     └── sub.sass
    ├── _js
    │     ├── entry.js
    │     └── sub.js
    ├── css
    ├── js
    ├── node_modules
    ├── package.json
    ├── webpack_index.html
    └── webpack.config.js
  • ビルド前の各モジュールは _(アンダースコア)から始まるディレクトリに入れる
  • ビルド後のファイルは、それぞれ js, css ディレクトリに格納される
  • webpack_index.html は確認用の html

0. ディレクトリとテストファイルの準備

# 各ディレクトリ
mkdir {_css,_js,css,js}
# テスト用 html
echo '<html><link rel="stylesheet" media="all" href="./css/style.css"><body><h1></h1></body><script src="./js/bundle.js"></script></html>' > webpack_index.html
# entry.scss
echo '@import "compass"; @import "sub"; h1 { @include inline-block; color: #f00; }' > _css/entry.scss
# sub.scss
echo '@import "compass"; h1 { background-color: #000; }' > _css/sub.scss
# entry.js
echo 'var $ = require("jquery"); $(function(){$("h1").text(require("./sub.js"));});' > _js/entry.js
# sub.js
echo 'module.exports = "OK";' > _js/sub.js
  • webpack_index.html ではビルド後の js と css の読み込みの他、h1 タグを用意しておく
  • entry.scss では sub.scss を読み込む他、h1 を赤字に、また compass で inline-block にする
  • sub.scss では h1 の背景を黒にする
  • entry.js では jquery の読み込みの他、sub.js の出力を h1 にセットする
  • sub.js は “OK” を返す
  • ビルド後のイメージは次の感じ

スクリーンショット 2017-06-01 6.41.20.png

1. package.json を作る

-y オプションを付けて対話をせずに、初期化する。

npm init -y

2. devDependencies に追加する

npm install --save-dev webpack babel-loader babel-core babel-preset-es2015 node-sass style-loader css-loader sass-loader extract-text-webpack-plugin compass-mixins

それぞれ、

  • webpack 本体

    • webpack
  • ES6 対応

    • babel-loader
    • babel-core
    • babel-preset-es2015
  • sass 対応
    • node-sass
    • style-loader
    • css-loader sass-loader
  • sass -> css 書き出し対応
    • extract-text-webpack-plugin
  • compass 対応

3. dependencies に追加する

npm install jquery --save

4. package.json を修正

...
"private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --optimize-minimize"
  },
...
  • プライベート用にして警告排除
  • "private": true
  • ビルドファイルのミニマイズ設定
  • "build": "webpack --optimize-minimize"

5. webpack.config.js を置く

var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = [
    /**
     * js
     */
    {
        entry: "./_js/entry.js",
        watch: true,
        output: {
            path: path.join(__dirname, './js'),
            filename: "bundle.js"
        },
        module: {
            loaders: [{
                test: /\.js[x]?$/,
                exclude: /node_modules/,
                loader: 'babel-loader?presets[]=es2015'
            }]
        },
        devtool: 'source-map'
    },
    /**
     * Sass
     */
    {
        entry: './_css/entry.scss',
        watch: true,
        output: {
            path: path.join(__dirname, './css'),
            filename: 'style.css'
        },
        module: {
            loaders: [{
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract({
                    use: [{
                            loader: 'css-loader'
                        },
                        {
                            loader: 'sass-loader',
                            options: {
                                includePaths: ['node_modules/compass-mixins/lib']
                            },
                        }
                    ],
                    fallback: 'style-loader'
                })
            }]
        },
        plugins: [
            new ExtractTextPlugin('style.css')
        ],
        devtool: 'source-map'
    }
];

6. ビルドして確かめる

npm run build

実行後、webpack_index.html をブラウザで開き、

スクリーンショット 2017-06-01 6.41.20.png

と表示されれば、js, sass ともにビルドができている。

また、js/bundle.js, css/style.css はそれぞれミニマイズされていて、かつ同階層に map ファイルも出力されていれば問題ない。

webpack の基本設定

webpack を初めて触ったので、調べたことなどを備忘録として残しておく。webpack のインストールから、ES6, jQuery, Sass, compass の対応まで。

1. npm の準備

package.jsonを作る。

npm init

2. ローカルに webpack をインストー

package.json に書き込みたいので、--save-dev オプションをつける。

npm install webpack --save-dev

No repository field. と怒られた場合、一先ず、package.json"private": true を追加すれば警告は消える。

ドキュメントに依ると、

If you set “private”: true in your package.json, then npm will refuse to publish it.

This is a way to prevent accidental publication of private repositories. If you would like to ensure that a given package is only ever published to a specific registry (for example, an internal registry), then use the publishConfig dictionary described below to override the registry config param at publish-time.

要は公開用のリポジトリじゃなく、プライベートなリポジトリのみで使うっていう設定。これを指定すれば、repository field の指定がなくても許される。

3. ローカルにパスを通す

このままだと、webpack コマンドは動かないので、パスを通す。

export PATH=$PATH:./node_modules/.bin

以下でバージョンが確認出来る。

webpack -v

もちろん、パスを通す必要がないなら、直接、

node_modules/.bin/webpack -v

でも良い。

4. webpack でビルドをテストする

適当に、sub.js を作る。

module.exports = ["a", "b", "c"]; 

module.export は return 的なやつ。これを app.js で読み込み、出力する。

console.log(require("./sub.js")); 

これを bundle.js としてビルドする。

webpack app.js bundle.js

実行すると、

Version: webpack 2.6.1
Time: 81ms
    Asset     Size  Chunks             Chunk Names
bundle.js  2.78 kB       0  [emitted]  main
   [0] ./sub.js 34 bytes {0} [built]
   [1] ./app.js 34 bytes {0} [built]

こんな感じの実行結果と bundle.js が書き出されている。

この bundle.js を実行すると、次のような結果になる。

[ 'a', 'b', 'c' ]

なお、npm の実行時にこれも一緒にビルドして欲しいので、build: の項目を設け、そこに追加する。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack app.js bundle.js"
  },

そうすれば、

npm run build

でビルドしてくれる。

5. webpack.config.js からビルドする

そもそも webpack 実行時に js のビルドも自動的にしてほしいので、webpack.config.js にその設定を書く。

まずは、package.jsonbuild: 項目を webpack だけにして、

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },

以下のように webpack.config.js を作成。entryoutputfilename 指定する。

module.exports = {                                                     
    entry: "./app.js",
    output: {
    filename: "bundle.js"
    }
}

そうすれば、先ほどと同様に、

npm run build

でビルド出来る。ディレクトリパスを別途指定するなら、path モジュールを読み込んで、

var path = require('path');
module.exports = {                                                     
    entry: "./js/modules/app.js",
    watch: true,
    output: {
        path: path.join(__dirname, './js'),
        filename: "bundle.js"
    }
}

のようにする。

6. watch モードにする

ファイルを監視させて、変更時に自動ビルド。コマンドラインから設定するなら、

webpack --watch

一方、webpack.config.js で指定するなら、watch: を設けて、true にする。

module.exports = {
  watch: true,
  entry: "./app.js",
  ...省略...

7. jquery を使う

まずは、npm で jquery をダウンロード。プロダクトでもつかうので、 オプションは --save

npm install jquery --save
var $ = require("jquery");
$(function(){

});

件の通り、$ に jquery をつっこむだけ。

8. ES6 に対応させる

ES6 を ES5 にコンパイルというかトランスパイルというか、とにかく変換する場合は、babel-loader を使う。

開発用なので、オプションは --save-dev でインストールする。

npm install babel-loader babel-core babel-preset-es2015 --save-dev

webpack.config.js に以下を追加する。

...省略...
  module: {
    loaders: [{
      test: /\.js[x]?$/,
      exclude: /node_modules/,
      loader: 'babel-loader?presets[]=es2015'
    }]
  }
...省略...

正規表現で node_modules を除く js 系の拡張子を対象にしている。

試しに app.js を次のように書き換え、

/*jshint esversion: 6 */
var $ = require("jquery");
$(function(){
    "use strict";
    const hoge = "!!!!";
    $("body").text(hoge);
});

ビルドすると、bundle.js では、

...省略...

/*jshint esversion: 6 */
var $ = __webpack_require__(0);
$(function () {
    "use strict";

    var hoge = "!!!!";
    $("body").text(hoge);
});

...省略...

const -> var の変換がされている。

9. js を minimize する

圧縮したいなら、packege.jsonbuild:--optimize-minimize のオプションをつける。

ただ、このままだとデバッグし難いので、更に --devtool source-map のオプションもつけて、デベロッパーツールから圧縮前を見れるようにする。

...省略...
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --optimize-minimize --devtool source-map"
  },
...省略...

これで、Chrome デベロッパーツールの Sources タブに webpack:// のディレクトリが表示される。

source-map は webmap.config.js でも指定できる。

末尾に devtool: の項目を追加し、source-map を指定する。

...省略...
  module: {
    loaders: [{
      test: /\.js[x]?$/,
      exclude: /node_modules/,
      loader: 'babel-loader?presets[]=es2015'
    }]
  },
  devtool: 'source-map'
...省略...

10. Sass の設定をする

まずは、必要なモジュールをインストール。

npm install --save-dev node-sass style-loader css-loader sass-loader extract-text-webpack-plugin

css の出力も可能にするため、extract-text-webpack-plugin も入れている。

webpack.config.js の exports の対象をオブジェクト({})からオブジェクトの配列([{},{}])形式にして、次のように変更する。

var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = [
    /**
     * js の設定
     */
    {
        entry: "./js/modules/app.js",
        watch: true,
        output: {
            path: path.join(__dirname, './js'),
            filename: "bundle.js"
        },
        module: {
            loaders: [{
                test: /\.js[x]?$/,
                exclude: /node_modules/,
                loader: 'babel-loader?presets[]=es2015'
            }]
        },
        devtool: 'source-map'
    },
    /**
     * Sass の設定
     */
    {
        entry: './css/modules/style.scss',
        watch: true,
        output: {
            path: path.join(__dirname, './css'),
            filename: 'app.css'
        },
        module: {
            loaders: [{
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract('css-loader!sass-loader')
            }]
        },
        plugins: [
            new ExtractTextPlugin('app.css')
        ],
        devtool: 'source-map'
    }
];

これで、複数指定ができる。なお、出力先のディレクトリなども整理してある。

11. compass を使う場合

まずは、compass-mixins をインストール。

npm install --save-dev compass-mixins

sass-loader の includePaths に compass-mixins/lib を指定して読み込ませる。

    /**
     * Sass の設定
     */
    {
        entry: './css/modules/style.scss',
        watch: true,
        output: {
            path: path.join(__dirname, './css'),
            filename: 'app.css'
        },
        module: {
            loaders: [{
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract({
                    use: [{
                            loader: 'css-loader'
                        },
                        {
                            loader: 'sass-loader',
                            options: {
                                includePaths: ['node_modules/compass-mixins/lib']
                            },
                        }
                    ],
                    fallback: 'style-loader'
                })
            }]
        },
        plugins: [
            new ExtractTextPlugin('app.css')
        ],
        devtool: 'source-map'
    }

下の config ファイルを参考にさせてもらった。

https://github.com/iliran11/react-cordova-boilerplate/blob/2b68ade24c9a56512140ff2c3419d401afd0737b/bin/get-webpack-config.js


参考 - Webpackを使って、Sassをコンパイルする方法 2017年4月版