WebViewでWeb Workerを使用する方法 [Android]
目次
1. 作るもの
2. 初期設定
3. 画面設計
4. HTML/JSファイル
5. コーディング
1. 作るもの
WebViewでWeb Workerを使用して「シングルタスクのJavaScript」をマルチスレッドのように動作させます。今回はバックグラウンドでプログレスバーを動かします。
WebViewで正しく設定を行わないと「Failed to construct 'Worker' cannot be accessed from origin 'null'.]」というエラーが発生してWeb Workerが使用できませんのでご注意下さい。
2. 初期設定
APIレベル
今回はWebViewコントロールを扱うのでAndroidの動作可能なAPIレベルは21(Android5.0/Lollipop)にしています。
設定方法はAndroid Studioで左のTreeViewにあるGradle Scriptsのbuild.gradleの「minSdkVersionを21」にします。
3. 画面設計
WebViewとButtonを各1つ、配置します。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="HTMLを表示する" />
</LinearLayout>
<WebView
android:id="@+id/webView"
android:layout_width="368dp"
android:layout_height="447dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
</android.support.constraint.ConstraintLayout>
4. HTML/JSファイル
HTML/JSをリソースに追加するにはWebViewの基本操作をご覧下さい。
[index.html]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
// ワーカーの生成
var my_worker = new Worker('myworker.js');
// プログレスバー
var pgs;
function run(){
var len = 10000;
// 毎回、プログレスバーを生成する
document.getElementById("pg_parent").innerHTML = '<progress id="MyProgress" style="width:180px;"></progress>';
pgs = document.getElementById("MyProgress");
pgs.max = len;
pgs.value = 0;
// ワーカーを実行する
my_worker.postMessage({'max':len});
}
// workerからのメッセージ
my_worker.onmessage = function (event) {
var type = event.data.type
if (type == 1){
pgs.max = event.data.max;
pgs.value = event.data.pos;
}else{
document.getElementById("pg_parent").innerHTML =
document.getElementById("pg_parent").innerHTML + '<br>完了しました。';
}
}
</script>
</head>
<body>
<p></p>
<div id="pg_parent"></div>
<p></p>
<input type="button" onclick="run();" value="実行する">
</body>
</html>
[myworker.js]
onmessage = function (event) {
var max = event.data.max;
// 適当な重い処理
for(var i=0;i<max;i++){
postMessage({'type':1,'max':max,'pos':i});
}
postMessage({'type':2});
};
5. コーディング
Workerを使用するには
setAllowFileAccessFromFileURLsをtrue
にします。
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
// リソースからファイルを生成する(/data/data/パッケージ名/files/)
public boolean setRawResources(Context context , int resourcesID, String fileName){
boolean result = false;
// リソースの読み込み
InputStream is = context.getResources().openRawResource(resourcesID);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte [] buffer = new byte[1024];
try{
// 1024バイト毎、ファイルを読み込む
while(true) {
int len = is.read(buffer);
if(len < 0) break;
baos.write(buffer, 0, len);
}
}catch (Exception e){
e.printStackTrace();
return result;
}
// ファイルの生成
File file = new File(context.getFilesDir() + "/" + fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(baos.toByteArray());
result = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if(fos != null){
try{
fos.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
return result;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
WebView webView = findViewById(R.id.webView);
// リソースからファイルを生成する(/data/data/パッケージ名/files/に作成)
setRawResources(MainActivity.this, R.raw.index, "index.html");
setRawResources(MainActivity.this, R.raw.myworker, "myworker.js");
// キャッシュクリア
// ※開発時のみ有効にする
webView.clearCache(true);
// JavaScriptを有効にする
webView.getSettings().setJavaScriptEnabled(true);
// WebChromeClientを設定する
// ※コレを設定しないとJSのalertは表示されない
webView.setWebChromeClient(new WebChromeClient());
// Web Workerを使用可能にする
webView.getSettings().setAllowFileAccessFromFileURLs(true);
// ファイルを読み込む
webView.loadUrl("file:///" + MainActivity.this.getFilesDir() + "/index.html");
}
});
}
}
スポンサーリンク
関連記事
| 前の記事: | WebViewでJavaとJavaScript間で相互通信する [Android] |
| 次の記事: | WebViewの<input type="file">でカメラ、画像からデータを取得する [Android] |
公開日:2018年06月03日
記事NO:02673
プチモンテ ※この記事を書いた人
![]() | |
![]() | 💻 ITスキル・経験 サーバー構築からWebアプリケーション開発。IoTをはじめとする電子工作、ロボット、人工知能やスマホ/OSアプリまで分野問わず経験。 画像処理/音声処理/アニメーション、3Dゲーム、会計ソフト、PDF作成/編集、逆アセンブラ、EXE/DLLファイルの書き換えなどのアプリを公開。詳しくは自己紹介へ |
| 🎵 音楽制作 BGMは楽器(音源)さえあれば、何でも制作可能。歌モノは主にロック、バラード、ポップスを制作。歌詞は抒情詩、抒情的な楽曲が多い。楽曲制作は🔰2023年12月中旬 ~ | |









