<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>mojavy.com</title>
    <link>http://mojavy.com/blog</link>
    <description></description>
    <pubDate>Fri, 29 Mar 2013 21:53:15 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Rubotoを使ってRubyでAndroidアプリをかく</title>
      <link>http://mojavy.com/blog/2013/03/29/ruboto/</link>
      <pubDate>Fri, 29 Mar 2013 21:53:15 JST</pubDate>
      <category><![CDATA[android]]></category>
      <category><![CDATA[ruby]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2013/03/29/ruboto/</guid>
      <description>Rubotoを使ってRubyでAndroidアプリをかく</description>
      <content:encoded><![CDATA[<p><img alt="ruboto" src="/images/ruboto-200.png" /></p>
<p>最近iOSアプリ界隈では<a href="http://www.rubymotion.com/">RubyMotion</a>や<a href="http://mobiruby.org/">MobiRuby</a>が盛り上がってきてますが、Androidでも<a href="http://ruboto.org/">Ruboto</a>をつかえば簡単にrubyで開発することができるようになります。</p>
<p>そもそもjavaで実装された処理系であれば大抵javaクラスの呼びだしは簡単にできるようになっているので、jrubyやjythonでandroidアプリを開発することは以前から可能でした。
しかし、以下のような問題があって実際にやるとなるとそれなりに面倒なものでした。</p>
<ol>
<li>jrubyやjythonをdalvikvm用バイナリ(dex)にコンパイルするのに時間がかかる<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></li>
<li>androidのjavaでは使えない機能を使って処理系を実装してある場合があるので、何らかの方法で回避する必要がある</li>
<li>スクリプトのソースファイルの配置やパスの設定を自分でやる必要があり、パッケージングが面倒 </li>
<li>アプリのフットプリントが大きくなる<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup></li>
</ol>
<p>Rubotoをつかえばこのあたりの面倒をみてくれるので、ほとんどjavaを書く必要がなくなります。Ruboto自体は結構前からありますが、ここ1年くらいでもろもろの機能が充実してきて大分実用的になってきた感があります。</p>
<p>以下Rubotoの使用方法について簡単に紹介します。</p>
<h2 id="_1">インストール</h2>
<div class="pygments_borland"><pre>gem install ruboto
gem install jruby-jars
</pre></div>

<p>また、<code>ANDROID_HOME</code>環境変数の設定と、android sdkの <code>tools/</code> と <code>platform-tools/</code>にはあらかじめパスをとおしておきます</p>
<h2 id="_2">雛形の生成</h2>
<div class="pygments_borland"><pre>ruboto gen app --package org.rubyandroid.new_demo

# 以下のようにしてより詳細に設定することもできます
# ruboto gen app --package org.rubyandroid.new_demo --path ./myapp --name MyApp --target android-17 --min-sdk android-10 --activity MainActivityName
</pre></div>

<h2 id="_3">ビルドとインストール</h2>
<p>rakeからビルドできるようになっています。また、rubyスクリプトの更新はコンパイル不要で反映できます。
あとは普通にrubyを書くだけです。</p>
<div class="pygments_borland"><pre>cd new_demo
rake
rake install

#
# edit ruby scripts..
#

rake update_scripts
</pre></div>

<h2 id="rubygems">rubygemsを使う</h2>
<p>通常の<code>Gemfile</code>と同じ内容を、<code>Gemfile.apk</code>という名前のファイルに書いてプロジェクトのルートディレクトリに置いておけば、<code>rake</code>した際に<code>libs/bundle.jar</code>を生成してapkにいれてくれます。</p>
<p>詳細は以下の例を参考にしてください。
<a href="https://github.com/ruboto/ruboto/wiki/Tutorial%3A-Using-an-SQLite-database-with-ActiveRecord">https://github.com/ruboto/ruboto/wiki/Tutorial%3A-Using-an-SQLite-database-with-ActiveRecord</a></p>
<h2 id="_4">補足</h2>
<p>rubotoではjrubyの実行環境は別途Ruboto Core platformというapkで提供されています。そのためアプリ本体にruby処理系を同梱する必要がなく、省サイズでコンパイルも速くなるというメリットがあります。しかし、このやり方だとRuboto Core platformを別途インストールしてもらう必要がでてきてしまい、実際にGoogle Playで配布するようなアプリでは受け入れ難いと思います。</p>
<p>これを回避する方法も提供されていて、プロジェクトを生成する際に<code>--with-jruby</code>というオプションをつければjrubyを同梱したapkをビルドできるようになりますが、この場合は前述のメリットはうけられなくなります。ただ、コンパイル時間に関しては、rubyスクリプトだけを触っている限りは、dexの再コンパイルは必要ないのでそれほど気にならないと思います。</p>
<h2 id="_5">まとめ</h2>
<ul>
<li>androidで素のjrubyを使うのは茨の道ですが、rubotoを使えば非常に簡単にrubyを使えるようになります</li>
<li>jrubyなので普通のrubygemsやjavaでかかれたライブラリもそのまま使えます</li>
<li>javaで開発した場合はコンパイル〜再インストールが毎回必要になりますが、<code>.rb</code>の更新反映は高速にできるので開発効率があがります</li>
<li>まだそれほど使い込んでないので思わぬはまりどころがあるかもしれません</li>
</ul>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>dxが分割コンパイルに対応してないので回避しづらい&#160;<a href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
<li id="fn:2">
<p>ファイルサイズも実行時のメモリ使用量も&#160;<a href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">&#8617;</a></p>
</li>
</ol>
</div>]]></content:encoded>
    </item>
    <item>
      <title>細かすぎて伝わらないAndroid開発のはまりどころまとめ その1</title>
      <link>http://mojavy.com/blog/2012/11/07/android-pitfalls/</link>
      <pubDate>Wed, 07 Nov 2012 12:00:00 JST</pubDate>
      <category><![CDATA[android]]></category>
      <category><![CDATA[tips]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2012/11/07/android-pitfalls/</guid>
      <description>細かすぎて伝わらないAndroid開発のはまりどころまとめ その1</description>
      <content:encoded><![CDATA[<p><img alt="android" src="/images/android-logo.png" /></p>
<p>これまでandroidアプリを開発しててはまったことがたまってきたのでまとめておきます。順不同です。
その2はまたねたがたまってきたらたぶんそのうち。</p>
<h2 id="_1">目次</h2>
<div class="toc">
<ul>
<li><a href="#_1">目次</a></li>
<li><a href="#onanimationendviewnullpointerexception">onAnimationEndでviewの階層を操作するとNullPointerExceptionでおちる</a></li>
<li><a href="#animation">Animationが動かない</a></li>
<li><a href="#windowmanageraddview">WindowManagerにaddViewしたときの挙動</a></li>
<li><a href="#activity">Activityが横向きでスタートした場合と縦向きでスタートしたときで表示倍率が違う</a></li>
<li><a href="#oncreate">onCreateが何回もよばれる</a></li>
<li><a href="#popupwindow">popupWindowのサイズが変わらない</a></li>
<li><a href="#httpurlconnection-0byteresponse">HttpURLConnectionが 0byteのresponseを返す</a></li>
<li><a href="#orgapachehttpimplclientdefaulthttpclient">org.apache.http.impl.client.DefaultHttpClientがすごく遅い</a></li>
<li><a href="#eclipseandroid-plugin">eclipseのAndroid pluginが動かなくなった</a></li>
<li><a href="#webview">WebViewで表示されるコンテンツが小さすぎる</a></li>
<li><a href="#javalangruntimeexception-stub">java.lang.RuntimeException: Stub!</a></li>
<li><a href="#jarandroid">jarとして配布するandroidライブラリ内にリソースを埋め込むことはできない</a></li>
<li><a href="#android-maven-plugin-mvn-eclipseeclipse-eclipse">android-maven-plugin から mvn eclipse:eclipse でeclipse用にエクスポートすることはできない</a></li>
</ul>
</div>
<h2 id="onanimationendviewnullpointerexception">onAnimationEndでviewの階層を操作するとNullPointerExceptionでおちる</h2>
<p>Viewをフェードアウトして親Viewからremoveする、というような動作をしたい場合に、普通にonAnimationEndの中でremoveViewとかするとNullPointerExceptionでおちます。onAnimationEndの中でViewの階層構造を操作するような処理をしてはだめらしいです。回避するには、Handlerをつかってタイミングをずらしてやるとよいです。</p>
<ul>
<li>参考: <a href="http://stackoverflow.com/questions/5569267/nullpointerexception-that-doesnt-point-to-any-line-in-my-code">http://stackoverflow.com/questions/5569267/nullpointerexception-that-doesnt-point-to-any-line-in-my-code</a></li>
</ul>
<h2 id="animation">Animationが動かない</h2>
<p>AnimationさせるViewには親Viewが存在している必要があります。WindowManagerはViewではないので、WindowManagerにaddViewしたViewをアニメーションさせたい場合は空のRelativeLayoutとかにaddViewしてから、RelativeLayoutのほうをWindowManagerにaddViewしてやる必要があります。</p>
<h2 id="windowmanageraddview">WindowManagerにaddViewしたときの挙動</h2>
<p>WindowManagerにもaddViewできますが、通常のViewとは挙動が違います。</p>
<ul>
<li>背景透過はWindowManager.LayoutParam.format に TRANSLUCENT をセットすればよいです。</li>
<li>dimでフェードインできますが、その際のdurationを変更する方法は分かりませんでした。</li>
<li>BACKボタンはきかなくなります。自分でKeyEventを処理してやる必要があります。android.widget.PopupWindowのdispathKeyEventのソースが参考になります。</li>
</ul>
<h2 id="activity">Activityが横向きでスタートした場合と縦向きでスタートしたときで表示倍率が違う</h2>
<ul>
<li>参考：<a href="http://d.hatena.ne.jp/acidgraphix/20110126/1296018143">http://d.hatena.ne.jp/acidgraphix/20110126/1296018143</a></li>
</ul>
<h2 id="oncreate">onCreateが何回もよばれる</h2>
<p>回転やキーボード表示のタイミングでもonCreateがよばれます。AndroidManifest.xmlでconfigChangesを設定することで回避できます。</p>
<ul>
<li>参考: <a href="http://stackoverflow.com/questions/2606470/unexpected-resume-of-package-name-while-already-resumed-in-package-name-err">http://stackoverflow.com/questions/2606470/unexpected-resume-of-package-name-while-already-resumed-in-package-name-err</a></li>
</ul>
<h2 id="popupwindow">popupWindowのサイズが変わらない</h2>
<p>popupWindowのsetWidth, setHeightは次回以降の表示サイズしか変えられません。既に表示しているポップアップウィンドウのサイズはそのままです。invalidateしても無駄です。</p>
<h2 id="httpurlconnection-0byteresponse">HttpURLConnectionが 0byteのresponseを返す</h2>
<p>コネクションプールとkeepaliveがらみで問題が発生する場合があるみたいです。SDKのバージョンとウェブサーバ側の設定も影響します。
<code>System.setProperty("http.keepAlive", "false")</code> で回避はできるようです。これに遭遇したときは、org.apache.http.impl.client.DefaultHttpClientの方を使うことにしたので詳細は追ってません。</p>
<ul>
<li>参考: <a href="http://stackoverflow.com/questions/1440957/httpurlconnection-getresponsecode-returns-1-on-second-invocation">http://stackoverflow.com/questions/1440957/httpurlconnection-getresponsecode-returns-1-on-second-invocation</a></li>
</ul>
<h2 id="orgapachehttpimplclientdefaulthttpclient">org.apache.http.impl.client.DefaultHttpClientがすごく遅い</h2>
<p>httpsでリクエストを投げると、ウェブサーバ側の負荷が高いわけでもネットワークが細いわけでもないのに、返ってくるまでなぜか数秒かかる場合があります。こちらもkeepaliveがらみの問題っぽいです。これもウェブサーバ側の設定が影響します。
試した限りでは以下のような状況でした。</p>
<ul>
<li>setHeader("Connection", "close") しても効果なし</li>
<li>setKeepAliveStrategyでdurationを 0とか1にしても効果なし</li>
<li>Connection closeしないウェブサーバならすぐレスポンスが返ってくる</li>
<li>httpならすぐレスポンスが返ってくる</li>
</ul>
<p><a href="http://hc.apache.org/httpclient-3.x/sslguide.html">ここ( http://hc.apache.org/httpclient-3.x/sslguide.html )</a> のKnown limitations and problemsをみるとそれっぽい既知の問題があるようですが、根が深そうだったので詳細は追ってません。</p>
<h2 id="eclipseandroid-plugin">eclipseのAndroid pluginが動かなくなった</h2>
<p>なぜかeclipseでAndroid pluginが動かなくなるときがありました。詳細をメモるのを忘れてしまいましたが、以下の手順で直ったような気がします。</p>
<ol>
<li>Android Support Libraryをアンインストール</li>
<li>eclipse再起動</li>
<li>新しいAndroidプロジェクトを作るとダイアログでライブラリのインストールを促されるのでそれに従う</li>
<li>android プラグインをアップデート</li>
</ol>
<h2 id="webview">WebViewで表示されるコンテンツが小さすぎる</h2>
<p>通常ビューのスケールとWebViewのスケールは別です。setScaleで調整する必要があります。
これはたぶんiOSでも同様かと。</p>
<h2 id="javalangruntimeexception-stub">java.lang.RuntimeException: Stub!</h2>
<p>android.jar内のコードはdalvikvmの外で実行することはできません。問答無用でタイトルの例外が飛びます。
エラーメッセージはもうちょいなんとかならなかったのか。</p>
<p>参考</p>
<ul>
<li><a href="http://stackoverflow.com/questions/7247502/using-android-jar-in-java-project-runtimeexception-stub">http://stackoverflow.com/questions/7247502/using-android-jar-in-java-project-runtimeexception-stub</a></li>
<li><a href="http://www.slideshare.net/miyatay/abc2011w">http://www.slideshare.net/miyatay/abc2011w</a></li>
</ul>
<h2 id="jarandroid">jarとして配布するandroidライブラリ内にリソースを埋め込むことはできない</h2>
<p>リソースIDを列挙しているRパッケージはjarにそのまま入れることはできますが、そのリソースIDは不正なものとなります。
ライブラリにリソースを含めたい場合は、ソースも含めたプロジェクトをまるごと配布するしかないようです。</p>
<p>ごく小さなアイコン画像だけとかであればバイナリデータをソース中に埋め込んでしまう、というのも手です。
iOSならBundleという仕組みがあります。</p>
<h2 id="android-maven-plugin-mvn-eclipseeclipse-eclipse">android-maven-plugin から mvn eclipse:eclipse でeclipse用にエクスポートすることはできない</h2>
<p>androidでもmavenは使えますが、androidのmavenプロジェクトは通常の方法(mvn eclipse:eclipse)ではeclipseにインポートできません。
以下のファイルを手動でつくってみたらとりあえずいけました。</p>
<ul>
<li>.classpath</li>
</ul>
<div class="pygments_borland"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="nt">&lt;classpath&gt;</span>
        <span class="nt">&lt;classpathentry</span> <span class="na">kind=</span><span class="s">&quot;src&quot;</span> <span class="na">path=</span><span class="s">&quot;src/main/java&quot;</span><span class="nt">/&gt;</span>
        <span class="nt">&lt;classpathentry</span> <span class="na">kind=</span><span class="s">&quot;src&quot;</span> <span class="na">path=</span><span class="s">&quot;gen&quot;</span><span class="nt">/&gt;</span>
        <span class="nt">&lt;classpathentry</span> <span class="na">kind=</span><span class="s">&quot;con&quot;</span> <span class="na">path=</span><span class="s">&quot;com.android.ide.eclipse.adt.ANDROID_FRAMEWORK&quot;</span><span class="nt">/&gt;</span>
        <span class="nt">&lt;classpathentry</span> <span class="na">kind=</span><span class="s">&quot;con&quot;</span> <span class="na">path=</span><span class="s">&quot;com.android.ide.eclipse.adt.LIBRARIES&quot;</span><span class="nt">/&gt;</span>
        <span class="nt">&lt;classpathentry</span> <span class="na">kind=</span><span class="s">&quot;output&quot;</span> <span class="na">path=</span><span class="s">&quot;bin/classes&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/classpath&gt;</span>
</pre></div>

<ul>
<li>.project</li>
</ul>
<div class="pygments_borland"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="nt">&lt;projectDescription&gt;</span>
        <span class="nt">&lt;name&gt;</span>project-name<span class="nt">&lt;/name&gt;</span>
        <span class="nt">&lt;comment&gt;&lt;/comment&gt;</span>
        <span class="nt">&lt;projects&gt;</span>
        <span class="nt">&lt;/projects&gt;</span>
        <span class="nt">&lt;buildSpec&gt;</span>
                <span class="nt">&lt;buildCommand&gt;</span>
                        <span class="nt">&lt;name&gt;</span>com.android.ide.eclipse.adt.ResourceManagerBuilder<span class="nt">&lt;/name&gt;</span>
                        <span class="nt">&lt;arguments&gt;</span>
                        <span class="nt">&lt;/arguments&gt;</span>
                <span class="nt">&lt;/buildCommand&gt;</span>
                <span class="nt">&lt;buildCommand&gt;</span>
                        <span class="nt">&lt;name&gt;</span>com.android.ide.eclipse.adt.PreCompilerBuilder<span class="nt">&lt;/name&gt;</span>
                        <span class="nt">&lt;arguments&gt;</span>
                        <span class="nt">&lt;/arguments&gt;</span>
                <span class="nt">&lt;/buildCommand&gt;</span>
                <span class="nt">&lt;buildCommand&gt;</span>
                        <span class="nt">&lt;name&gt;</span>org.eclipse.jdt.core.javabuilder<span class="nt">&lt;/name&gt;</span>
                        <span class="nt">&lt;arguments&gt;</span>
                        <span class="nt">&lt;/arguments&gt;</span>
                <span class="nt">&lt;/buildCommand&gt;</span>
                <span class="nt">&lt;buildCommand&gt;</span>
                        <span class="nt">&lt;name&gt;</span>com.android.ide.eclipse.adt.ApkBuilder<span class="nt">&lt;/name&gt;</span>
                        <span class="nt">&lt;arguments&gt;</span>
                        <span class="nt">&lt;/arguments&gt;</span>
                <span class="nt">&lt;/buildCommand&gt;</span>
        <span class="nt">&lt;/buildSpec&gt;</span>
        <span class="nt">&lt;natures&gt;</span>
                <span class="nt">&lt;nature&gt;</span>com.android.ide.eclipse.adt.AndroidNature<span class="nt">&lt;/nature&gt;</span>
                <span class="nt">&lt;nature&gt;</span>org.eclipse.jdt.core.javanature<span class="nt">&lt;/nature&gt;</span>
        <span class="nt">&lt;/natures&gt;</span>
<span class="nt">&lt;/projectDescription&gt;</span>
</pre></div>

<ul>
<li>project.properties</li>
</ul>
<div class="pygments_borland"><pre><span class="c"># Project target.</span>
<span class="na">target</span><span class="o">=</span><span class="s">android-10</span>

<span class="c"># if it is a library</span>
<span class="c"># android.library=true</span>
</pre></div>

<p>まあ、なんというか、Androidはいろいろ残念ですね。</p>
<p>iOSはこういう仕様なのかバグなのかよくわからないようなものが少ないし、OSバージョンの入れ換わりが早くて対応バージョンも少なくて済む分、個人的な体感ではandroidアプリの工数はiOSの3割増しという感じ。</p>]]></content:encoded>
    </item>
  </channel>
</rss>
