2011-07-31
たった50行のソースコードで,「関数電卓」のAndroidアプリを作成する方法
java, shortcoding, 小ネタ, javascript, Android, ブックマークレット |
「Hello, World」のAndroidアプリが作れるなら,「関数電卓」のプログラムを今すぐリリースできる。
実装に必要なソースコードは,たった50行。
計算画面のキャプチャ(関数計算として,2の10乗を計算しようとしている):
結果画面のキャプチャ(計算結果が正しく表示された):
ほかに,sin, cos, logなど自由に利用可能。
このアプリを実装するための50行のソースコードを,以下に掲載する。
※ちなみに,Hello, Worldを動かすまでの手順は下記URLを参照。
今から1時間で,Androidアプリの開発環境を構築し,Windows上でサンプルを動作させる手順
関数電卓のソースコード
「Hello, World」プロジェクト内の,適当なアクティビティの内容を書き換える。
package com.example; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.webkit.*; import android.widget.*; // 関数電卓を表示するアクティビティ public class AndroidHelloWorldActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 縦レイアウトを動的に作成 final LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); setContentView(layout); // 数式の入力欄を作成 final EditText editText = new EditText(this); editText.setText("1+1"); layout.addView(editText); // 計算実行ボタンを作成 Button button = new Button(this); button.setText("計算実行"); layout.addView(button); // 計算実行ボタンにベントをセット final Activity this_activity = this; button.setOnClickListener(new OnClickListener(){ public void onClick(View v) { final String eval_text = editText.getText().toString(); final WebView wv = new WebView(this_activity); this_activity.setContentView(wv); wv.getSettings().setJavaScriptEnabled(true); // ページの表示終了イベント発生時に,計算結果を表示 wv.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { // ブックマークレットのJSとして評価 wv.loadUrl( "javascript:(function() { " + "document.getElementsByTagName('body')[0].innerHTML = (" + eval_text + "); })()" ); } }); // 仮のページを開く wv.loadUrl("http://code.google.com/android"); } }); } }
これで49行。
あとは,AndroidManifest.xml 中のmanifestタグ内に,以下の 1 行を書き加える。
コーディングは,合計50行になる。
<uses-permission android:name="android.permission.INTERNET" />
これで終了。Androidの関数電卓アプリが完成。
ツッコミどころ
ツッコミどころは多いが,,
一応,初めは javax.script.ScriptEngine を使って,
ちゃんとまっとうに Java のコードで eval() する予定だった。
(静的型付け言語のJavaでeval()しようとしている時点でまっとうではないが・・・)
JavaからJavaScriptを呼び出すサンプル
http://blog.goo.ne.jp/hiuchida/e/b8bd0a9d606b47af9eef89791eea88cf
JDK6よりJavaスクリプトAPIが追加されました(JavaScript APIではない)。
JSR-223に準拠していればjavax.scriptにあるスクリプトAPIを使ってどんなスクリプト言語でも実行できるはずですが、今のところJavaScriptの実装(Rhinoをベースにしたもの)しかないようです。
上記URLのコードは,JDK6で正常に動作した。
ところが,いざこのコードをAndroidアプリ中で動かそうとしたら,
必要なライブラリをインポートできない。
Android SDKはJDK5がベースなので,まだscriptingに非対応なのだ。
Issue with javax.script
http://www.coderanch.com/t/512996/java/java/javax-script
- I'm working in Eclipse for Android, and initially I was unable to even import javax.script.
- So this is an Android app? Android is based on Java 1.5 - which does not support javax.script.
Is it possible to reference the javax.script.ScriptEngine library when developing an android application? If not is there anyway possible to evaluate a javascript expression in android?
- javax.script.ScriptEngine is not a default part of android
代替案として,WebViewコンポーネントを経由して,ブックマークレット形式でJavaScript文字列をeval(実行)する方法が紹介されていた。
is it possible to send a javascript string to an invisible WebView and have it evaluate the string
- Yes, via addJavascriptInterface() and sending the browser a javascript: URL, akin to a bookmarklet.
Injecting JavaScript into a WebView
http://lexandera.com/2009/01/injecting-javascript-into-a-webview/
- “How can I manipulate the contents of a WebView?”
- very simple: wait for the original page to finish loading, then inject your own JavaScript code into it by calling webview.loadUrl(“javascript:your-code-here”) when your webvew’s onPageFinished() event is triggered.
- alert() and confirm() JavaScript functions will not work
なお,WebViewコンポーネントはインターネット接続するので,Manifest.xml中に宣言が必要。
今日のAndroid - WebViewを使ってみるCommentsAdd Star
http://d.hatena.ne.jp/emergent/20090209/1234189265
- Androidアプリでインターネット接続するためには、作成する前にすることがある
- 解決方法は、AndroidManifest.xmlにpermissionの一文を入れること
そういうわけで,Androidアプリ上でユーザが打ち込んだ任意の数式は,
WebViewコンポーネントに渡され,Webkitによって計算される。
数式を打ち込む際には,下記のページを参考にできる。
なお,構文解析をしておらず,数式のパース失敗時の動作保証も何もないので,
これは「遊び」レベルのアプリと言える。
(利用は自己責任で)
しかし,構文解析などの高度なロジックを組むことなく,
簡単に関数計算アプリが作れてしまう,という点は面白い。
実際,任意の関数計算機能をユーザに提供する,という目的は果たせているのだし。
(HTMLとJavaScriptだけで済むじゃないかという声が聞こえてきそうだが・・・)
補足
もし,まともに(ただの)電卓アプリを実装したい場合,下記のURLが参考になるだろう。
しかし,おそろしく手間がかかる。
サンプルアプリでおぼえる実践的Android入門
http://codezine.jp/article/detail/5957
- 四則演算だけができる「MyCalc」というアプリのサンプルコード
- 設計としては,状態遷移図をちゃんと描く
- デザインパターンのStateとSingletonを駆使して,数百行規模の実装
AndroidでリフレクションとJavaCCを試す(後編)
http://labs.s-cubism.com/blog/2009/07/10/141/
- Javaで「数式のコンパイラ」を実装し,そのコンパイラに数式を解釈させる方法
- Javaの「コンパイラコンパイラ」として,JavaCCを活用している
関連する記事:
たった2ファイルで,HTML+JS製のネイティブAndroidアプリを作る手順 (動作するサンプルコード付き。WebViewの活用方法) - 主に言語とシステム開発に関して
http://d.hatena.ne.jp/language_and_engineering/20120710/CreateAndroidAppByHtml5JavaScript
AndroidやiOSの「ハイブリッドアプリ」で,JavaScriptとネイティブ・コードが連携する仕組みを図解 (おまけ:HTML側で施すべき,クロスプラットフォーム対策) - 主に言語とシステム開発に関して
http://d.hatena.ne.jp/language_and_engineering/20120713/p1
jQuery Mobile と HTML5 で、Androidのネイティブアプリを作成する手順 - 主に言語とシステム開発に関して
http://d.hatena.ne.jp/language_and_engineering/20120717/CreateAndroidNativeAppsByJQueryMobile
- 1251 https://www.google.co.jp/
- 598 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=4&ved=0CDwQFjAD&url=http://d.hatena.ne.jp/language_and_engineering/20110731/p1&ei=S3MvT5vKDOuZiAfH-tnqAg&usg=AFQjCNHu6hm1-Ib7pW4QRqxq3brs6YpG4A&sig2=wcAEXBCwvE4tjVbnI32sdA
- 379 http://www.google.co.jp/url?sa=t&rct=j&q=android アプリ ソース&source=web&cd=5&ved=0CEgQFjAE&url=http://d.hatena.ne.jp/language_and_engineering/20110731/p1&ei=UYefTsrgMfGziQf41PW7Bg&usg=AFQjCNHu6hm
- 365 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=10&sqi=2&ved=0CHgQFjAJ&url=http://d.hatena.ne.jp/language_and_engineering/20110731/p1&ei=ucgfT_LtMoHdmAXQro3XDg&usg=AFQjCNHu6hm1-Ib7pW4QRqxq3brs6YpG4A
- 326 http://www.google.co.jp/url?sa=t&rct=j&q=android 電卓 ソース&source=web&cd=5&sqi=2&ved=0CD0QFjAE&url=http://d.hatena.ne.jp/language_and_engineering/20110731/p1&ei=KI2ETvzmPO3zmAW9nMko&usg=AFQjCNHu6hm1-Ib7
- 292 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CDIQFjAB&url=http://d.hatena.ne.jp/language_and_engineering/20110731/p1&ei=vbQ5T5-TM4TprQew1Ky7CA&usg=AFQjCNHu6hm1-Ib7pW4QRqxq3brs6YpG4A&sig2=WjxDvB502AaQpRIIWn73Ww
- 272 http://search.yahoo.co.jp/search?p=Android+アプリ 電卓 ソース&aq=-1&oq=&ei=UTF-8&fr=top_ga1_sa&x=wrt
- 250 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cts=1331053972503&ved=0CDkQFjAC&url=http://d.hatena.ne.jp/language_and_engineering/20110731/p1&ei=hEVWT66zGcjAmQWRn7zvCQ&usg=AFQjCNHu6hm1-Ib7pW4QRqxq3brs6YpG4A&sig2=fntRX40-IHLpw
- 243 http://www.google.co.jp/url?sa=t&rct=j&q=アンドロイド アプリ 電卓 ソース&source=web&cd=3&sqi=2&ved=0CD8QFjAC&url=http://d.haten
- 222 http://search.yahoo.co.jp/search?p=アンドロイド+開発+コード集&aq=-1&ei=UTF-8&xargs=12KPjg1u9StIGmmvmnN-mZDrDaoAtP0cHwsd5sCpIIXYZL8wZlROJ5LPKfwD1JTUhX3V-D2PHg9IYmHA.%