たぼさんの部屋

いちょぼとのんびり

T020) 計算:javascriptをじかに記述するとき

point

assetsにhtmlファイルを配置しないで直接 WebView.loadUrl()でjavascriptを記述する

  1. javascriptの使用を許可する
  2. Interfaceを追加する:引数にjavascriptからandroidへの呼び出しobjectを指定
  3. javascript呼び出しファイルを指定する
  4. javascriptをコール
  5. javascript側からの呼び出しオブジェクトで処理

webview.getSettings().setJavaScriptEnabled(true);

webview.addJavascriptInterface(new JsObject(), "android");

loadData()

コンストラクタへ記述

webview.loadData("", "text/html", null);	//必要

loadUrl(script)

String script = "javascript:android.getAnswerFromJS(eval("+editable+"));";
webview.loadUrl(script);

f:id:donsuka_kk:20121123214352p:plain

Main.java

package com.example.t020_js;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class Main extends Activity {
	Context context;
	LinearLayout base;
	JS_WebView js;
	protected static TextView kotae;
	Button btn;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// TODO Auto-generated method stub
		context = getApplicationContext();
		base = new LinearLayout(context);
		setContentView(base);
		base.setOrientation(LinearLayout.VERTICAL);

		TextView title = new TextView(context);
		title.setText("javascriptをじかに記述");
		base.addView(title);

		kotae = new TextView(context);
		kotae.setTextSize(40);
		kotae.setText("こたえ");
		base.addView(kotae);

		final EditText et = new EditText(context);
		base.addView(et);

		btn = new Button(context);
		btn.setText("計算します");
		base.addView(btn);
		/*
		 * 計算用a
		 * baseにaddviewはしない
		 */
		//JS_WebView js
		js = new JS_WebView(context);
		// listener
		btn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				js.getAnswer(et.getText());
				
				btn.setText("計算しました");
			}

		});
	}

}

JS_WebView.java

package com.example.t020_js;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.text.Editable;
import android.util.Log;
import android.webkit.WebView;

@SuppressLint("SetJavaScriptEnabled")
public class JS_WebView{
	WebView webview;
	public JS_WebView(Context context) {
		webview = new WebView(context);
		// Javascript 利用
		webview.getSettings().setJavaScriptEnabled(true);
		// javascriptInterface
		// 第2引数で指定した名前で、Javascriptからオブジェクトにアクセスできます。
		webview.addJavascriptInterface(new JsObject(), "android");		//--(1)
		webview.loadData("", "text/html", null);	
		//コンストラクタ内でload記述しておくこと:getAnswerメソッド内では動作が遅延する
	}

	public void getAnswer(Editable editable) { // EditTextからの入力値を引数にするため、Editable

		Log.v("JsInterface", "getAnswer:mondai=" + editable);
		// assetsのeval.htmlを呼び出す時
//		this.loadUrl("file:///android_asset/eval.html");
//		this.loadUrl("javascript:callEval('" + editable + "')");
		
		/*
		 * 直にjavascriptを記述する
		 * javascriptのeval()関数でeditableを計算したものを
		 * 引数としてwindow.android.getAnswerFromJSメソッドを呼び出す
		 * 上記(1)でインターフェース名をandroidで指定しているため。:window.android
		 * あるいは、windowは省略してもいい。(thisでも可)
		 */
		
		String script = "javascript:android.getAnswerFromJS(eval("+editable+"));";
		webview.loadUrl(script);
	}

	Handler mHandler = new Handler();
	//javascriptからの呼び出しを受け取るオブジェクトーー1)で指定
	class JsObject {
		// Javascriptから呼び出されるメソッド
		public void getAnswerFromJS(final String answer) {
			mHandler.post(new Runnable() {
				public void run() {
					// 計算結果をログ出力
					Log.d("TAG", answer);
					Main.kotae.setText(answer);
				}
			});
		}
	}
}