2015年1月15日木曜日

Redmine 2.5 の markdown のテーブル内のセルに改行を入れる

どっちみち標準ではテーブルの中で改行が使えないのだが、
textileを使っている場合、昔から知られている対応がある。

単純に <br> タグが使えればいいのだが、
標準では有効なタグ以外はしまっちゃおうね〜、となっている。
で、その「有効なタグ」に <br> タグを追加する方法がこちら。

http://redmine.jp/faq/wiki/use-html-tag-in-wiki/

しかし、Redmine2.5から使用可能となったmarkdown(experimental)では、
この方法が使えない。
対応しても無視される。
どうやら、このファイルはtextileの場合のみ有効なようなのである。

experimentalだからって甘えてんじゃねえ!と憤ってみてもしょうが無いので、
どうにかする方法を考えてみるとする。

実はこのmarkdownのモジュール、
Redcarpetからの継承クラスとしてオリジナルレンダラを実装している。
それが以下のソースファイルである。

lib/redmine/wiki_formatting/markdown/formatter.rb

オリジナルレンダラの実装方法は、以下の記事に解説してある。

k0kubun's blog : Railsでカスタムmarkdownを実装する
http://k0kubun.hatenablog.com/entry/2013/09/19/223400

要は、オリジナルレンダラとして定義されている HTML クラスに、
ここに書いてある postprocess というメソッドを追加して、自力で対応すればいい。

しかし、HTMLタグ自体はここで処理されるまでにしまっちゃわれているので、
"[]"を使ってオリジナルタグ "[br]" を実装する方法で行ってみる。

と言うわけで、 HTML クラスに以下のメソッドを追加し、Redmineを再起動する。

def postprocess(full_document)
  full_document.gsub(/\[br\]/, '<br>')
end
単純に [br] って書かれてたら <br> に置換してるだけ。

あとは適当なところで [br] タグを試して見て下さい。改行されています。



2013年12月5日木曜日

OSX10.9 Mavericks に chef を入れる

有名な魔法の呪文でさくっと入れようと思ったが、

$ curl -L http://www.opscode.com/chef/install.sh | sudo bash   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                 Dload  Upload   Total   Spent    Left  Speed100  6789  100  6789    0     0  13186      0 --:--:-- --:--:-- --:--:-- 13208No builds for platform: 10.9Please file a bug report at http://tickets.opscode.comProject: ChefComponent: PackagesLabel: OmnibusVersion: Please detail your operating system type, version and any other relevant details

え、Mervirickは対応してないだと…。
うーん、gemで入れてもいいんだけどなんかもにょるので、ちょっとググってみた。

https://tickets.opscode.com/browse/CHEF-4678

すでにチケットに上がってるというかdupeしまくっとるなw
えーと、いくつかのworkaroundがチケットに上がってるね。
 Bakh Inamov added a comment - 14/Nov/13 6:57 PM
Downloaded https://opscode-omnibus-packages.s3.amazonaws.com/mac_os_x/10.7/x86_64/chef-11.8.0_1.mac_os_x.10.7.2.sh and ran w no issues
これを試してみたが特に問題なかった。なんか22Mくらいあるけどこのファイル。

つまり上記リンクからファイルをダウンロード。Macのターミナルでsudo使って実行すればすごい勢いでインストールされる。

2013年11月28日木曜日

GitLab6系でMerge Requestが作れない

実際に使ってるのはGitLab6.2.4ですが。

えーと、GitLabで普通にMerge Requestを作ってみようとしたんだけど、
Source Brancheとしてさっきコミットしたブランチが表示されない。
というか、リポジトリ作成してから始めて作ったブランチと、
masterおよびdevelopくらいしか表示されてない。

よく見ると、commitsのページでも存在してるはずのブランチが選択出来ない状態。
どうもドロップダウンに全く反映されていない様子。

なにこれ?と思ってググったところ、
https://github.com/gitlabhq/gitlabhq/issues/4864
これが見つかった。
この中のこの投稿
I checked on various projects and it seems that all of them a broken now, If I push a new branch to any of them, it is never displayed, not in the project home page (as a link to create a new MR), not in the branch dropdown in Commits tab and not in the MR branch dropdown (which I guess is probably the same a in the Commits tab).
It seems to be a cache issue because when I cleared the cache (cd /home/git/gitlab && sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production), the branch is now correctly shown in the dropdown menu.
I will make more test to check what goes on.
Where is the code for this dropdown, maybe I could tried to debug it on my setup?
ここに書いて有るとおり、railsのキャッシュをクリアするとちゃんと表示されるようになった。
え、まさかいちいちキャッシュクリアしないと反映されないとかじゃないよね…。
と思って続きを見ていって見る。

Clearing cache works because everything is generated on the first run thereafter, but any new commits afterwards will still not appear, because they are not processed. So my hunch would still be that the update hook doesn't work as intended.
Good idea would be to check all possible logs as well - maybe the hook does fire, but there is an internal error processing it.
ああうん。やっぱそうだよね。
キャッシュをクリアした後、一回全部作り直されるからちゃんと動いたように見えるが、
updateのフックがパーミッションの関係でちゃんと実行されてないので、
それ以降のブランチはやっぱり反映されないってか。

このトピックを読んでいくと、要点は以下の様な感じ。


  • キャッシュクリアすれば直る。
  • redisとgitlabを再起動しても直るし、しばらくは再現しなくなる。
  • しばらくすると再現するようになる。
  • 5.4でも同じようなバグがあり、とりあえずキャッシュクリアでなんとかしてた。
  • リポジトリのhooksからgitlab-shellへのリンクがおかしい場合も起こるが、これはリンクを正しくすれば直る。
  • gitlab-shellからredisへ接続する情報に関しても確認が必要。
  • 6.0時点でキャッシュクリアによって再現しなくなったが、6.1にupgradeしたら再現した。
  • 今の時点でもこのIssueは閉じられていない(完全には解決してない)


とりあえずのwork aroundとしては

  • キャッシュクリアする
  • gitlab関係を全部再起動する


で症状は治まるっぽい。
しばらく様子を見て、最悪cronでキャッシュクリアを回すしか無いか…。

2013年10月29日火曜日

arch already exists in fat dylib

タイトルのエラーが突然出てきた。
CleanしてもBuildしても出てくる。なんだこれは。
とりあえずググるといつもの通りのStack over flowの記事がヒット。

http://stackoverflow.com/questions/18392902/arch-already-exists-in-fat-dylib-in-build-log

以下意訳。
「いきなり "arch already exists in fat dylib" とかすごい勢いでビルドログに出力されて困ってるんですけどどうしたらいいですか?」
「ろくな情報もねえのに分かるかよ。こんなもんオフトピだ」

で即クローズされてる。もうちょっと優しくしてあげてよ…。

自分はAppCode使ってるので、ちょっとXcodeでビルドしてみるかーと思ってやってみたら、バックグラウンド処理を動かそうと思って書いた以下のコードで "Initializer element is not a compile-time constant" というエラーが。
static UIBackgroundTaskIdentifier bgTask = UIBackgroundTaskInvalid;
この "UIBackgroundTaskInvalid" だけど、定義はこうなっている。
typedef NSUInteger UIBackgroundTaskIdentifier;
UIKIT_EXTERN const UIBackgroundTaskIdentifier UIBackgroundTaskInvalid  NS_AVAILABLE_IOS(4_0);
つまり、バージョンが決まらないと定義が決まらないので、この定数っぽいシンボルは実は実行時でないと実際に参照出来ないわけだ。エラー内容もそういう内容。

というわけでこれを直してAppCodeでビルドしてみると、タイトルのエラーも無くなり一件落着。

これはあれか、コード解析処理でなんか変な事になってるって事なのかな…。
最初に出したSOFのURLの人も、jenkinsでビルドしてて出たって言ってるので、サードパーティ環境でのみ出るのかもしれない。

日本語の記事が一つも引っかからなかったのでここに記す。
これ気付かないとドはまりする案件だと思うので皆さん気を付けて下さい。

2013年2月4日月曜日

Package file was not signed correctly

掲題は「パッケージファイルに正しく署名されていません。」の英語版。

前回のエントリーで書いた内容では解決されない場合、パッケージ側に問題がある。
何をやっても現象の再現する機種が存在する訳だ。
で、まず確認すべきは

「再現する実機のLogcatを取る」

である。インストール時に「PackageParser」というタグでエラーが出ているはず。
出てない場合はご愁傷様という他ないが…。
あと再現する実機を入手するのが以外と大変かもしれない。

大抵はこのエラーの原因となるファイルを取り除くことで解決する。
以下のGoogleGroupの投稿では、xmlファイルがなんかおかしくなったと有る。

http://productforums.google.com/forum/#!category-topic/android-market/technical-help/JzAgJ414CQc

なんでこんな事が起こるかというのはさっぱり不明の様だが、掲題のフレーズで検索すれば、英語圏では山ほど同様の現象は起きているらしい。

他にはこちらの投稿。

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/gAUqJkCuAvE

証明書の期限は大丈夫か?という内容。

大体このあたりに原因があるらしい。

2013年2月1日金曜日

パッケージファイルに正しく署名されていません

今回の記事はただのメモ。
 
要点だけ先に書くと、「アンインストールしてインストールし直す」だけです。
あなたがユーザーならまずこれを試してからクレームを入れるようにしてください。
これでダメなら、リリースモジュールに問題が有ると思っていいでしょう。
その場合、開発者の方は本記事の最後を見て下さい。
ユーザーの方は出来ればTwitterとかメールで直接教えてあげると感謝されますよきっと。

まず前提。
Androidアプリのリリースをするためには署名を行わなければならない。
これは、GooglePlayアップロードしたアプリを勝手に差し替えられないためである。

この仕組みのため、最初にアプリをアップロードする時に使った署名用の鍵を無くすと、そのアプリは更新が出来なくなる。

・・・という仕組みがAndroidでは利用されている。たぶんiPhoneも大体同じだが。

で、困ったことに、ダウンロード済みアプリの署名がおかしくなる場合があるらしい。
この時、アプリの更新をGooglePlayから行おうとすると、掲題のエラーではじかれてしまう。

これに関しての参考URLがこちら。

モノクロメカニズム: GALAXY NoteにカスタムROM≪ROCKET ROM v22≫を焼いてみた

こちらにはプリインストールアプリが上記現象でアップデート出来ないことが言及してある。

Logging Quest

自動探索RPG(放置型RPG)らしい。アプリの説明に、
【更新時に「正しく署名されていないパッケージファイルです」エラーが出る場合】
原因を調査しましたが、アプリ、端末を問わず、稀に発生する現象のようです。以下をお試しください。
*
ホームからメニューを開き、アプリケーション、アプリケーションの管理、と選択(機種により若干異なります)。「マーケット」を選択して「データを消去」「キャッシュを消去」を行う。

* 端末をシャットダウンし、再起動してみる。
* SDカードを取り外して更新してみる。
改善されない場合は、アプリ側では残念ながら対策不能のようです。
アンインストールし、再インストールすれば、更新できるようですが、既存のセーブデータは消えてしまいます。
申し訳ありませんが、よろしくお願いいたします。
 と書かれている。苦労されたのだろう。心中お察しします。

お部屋でモバイル: Androidでプリインストールの更新がうまくいかないとき

こちらもプリインストールアプリでこの現象が起こったときの対処法です。


2012年8月21日火曜日

ProGuardによるライブラリとしてのJARの難読化(2)

というわけで昨日の続き。
実際にProGuard4.8を使ってライブラリJARを難読化してみます。


 これはProGuardの起動直後の画面。
左側に各設定項目が並んでいます。
右下の「Next」を押すと、各設定項目間を進んでいきます。正直いらん。




 「Input/Output」の設定画面。
ここではInputとして難読化対象のJARなどを指定し、
どこにOutputするかを設定します。
また、前提となるライブラリとかもココで指定します。

ココで重要なのは
  • 実際に使用しているAndroidのバージョンに応じたandroid.jarをライブラリとして指定する
ことです。デフォルトではjavaの共通ライブラリが指定されているのですが、それは消しましょう。
android.jarに含まれています。
android.jarはAndroidSDKの「platforms」の中にあるよ。
他にも自作JARで使用しているライブラリがあるならココで指定しておけば取り込まれます。

一応注意だけど、「Input」として指定するのと、「ライブラリ」として指定するのは意味が違います。
「Input」したクラスは全て処理されて「Output」に吐き出されます。
「ライブラリ」として指定したクラスは解析に利用されるだけで処理対象にはなりません。


とりあえずこれだけ設定すれば、処理を行う事は出来るのですが、
デフォルトのままだと全部Shrinkされて何も無いJARが出力されてしまうので、
いくつか設定が実際必要。


 というわけでShrinkingの設定画面です。
Shrinkingとは、不要なクラスを削除してライブラリを小さくしてくれる処理なのですが、
今回のようにライブラリ「だけ」でShrinkすると、実際に使ってるクラスひとつもねーじゃん!となり、
全部のクラスが排除されます。慈悲は無い。
(本来はアプリケーションのエントリポイントからクラスの参照ツリーが形成されて、残すクラスが決定される)

というわけで、「Keep」の設定が必要になるわけです。
この画面の上側の設定項目は標準状態のままで問題ないので、
下の方にある「Keep additional classes and class members」を設定します。

ここでは二つ指定しています。
消しについては気にしないで下さい。
それぞれ
「Class example.android.library.**」「Class example.android.util.io.**」と書いてあることにします。
書式については該当のエディットボックスにカーソル持って行くとバルーンヘルプが出るのでそれを読んで下さい。

要は、ここで指定したクラスはShrink対象から除外されて、キープされる訳です。
なので、ライブラリの公開クラスを指定しておけばうまいことしてくれるようになります。

クラス指定は単純な名前指定だけでは無く、見ての通りのワイルドカード指定と、
さらにクラスの属性によるフィルタリングなどにも対応しています。
たとえば、名前自体はワイルドカードで広く指定して、その中でも「public」のクラスだけをkeepする等。
まぁ細かいことはどうでも良い場合は名前だけで良いです。



次にObfuscationの設定です。
基本的にはShrinkと同様、難読化したくないクラスをここでKeep設定しておきます。
普通はShrinkと同じ設定になるんじゃないでしょうか。
加えて、ライブラリ内で定義したクラスを公開メソッドの引数に使ってたりする場合は、それもKeepしないと外から分からなくなるので設定します。
上記画面ではちょうどそんな感じのことをしています。

注意点をまとめておくと
  • 外部で使うクラスはShrink/Obfuscation共にKeep
  • Keepしてるクラスのメソッドの引数、返値の型のクラスもKeep (ShrinkはされないのでObfuscationだけ)
  • AIDLがらみのクラスもKeepしておく。
  • 外部で使うクラスはinner classとして宣言しない。難読化まわりでハマるので。listenerとかでもtop levelクラスとして独立で定義しておく。
最後の項目で大ハマリしたのがこの記事を書くきっかけな訳だが。
実際の所、inner classは例えば「example.android.library.hoge$huga」の様に、
親クラス名に「$」付けてインナークラス名を付ければProGuardとしては参照出来るんだけど、
JARをインポートしたアプリ側からの参照がうまく出来ない。
難読化対象からは確実に外れているにもかかわらず、だ。
この辺はソース参照とclassファイル参照の違いだと思うんだけど、面倒なので独立定義にした方が良いです。
どうせアプリに公開しなきゃいけないインターフェースなので、明示的にした方がいいでしょうし。

なお、調査のためには「Print mapping」を有効にすると、どう難読化されたかを吐き出してくれます。

あとは「Optimization」とかあるけど、これは標準で良いんじゃ無いかな。
マニュアルの方にはループが過剰最適化される場合とか載ってるので、問題が有る場合とかに外した方が良いことがあるかも?

 一通りできたら「Process」ページの右下に「Process!」ってボタンがあるので、押せば設定通りに処理してくれます。
このときにエラーがあったら教えてくれるので、もしもなんか出てきたらよく読んで対処。
ちょくちょくあるのはKeep設定したクラスで記述されてるクラスがKeepされてないよ?というNoteかな。
言われたクラスもKeepしないと、ただしくKeepされません。


あとは実際にアプリの方でインポートして動作確認できれば完了。

2012年8月20日月曜日

ProGuardによるライブラリとしてのJARの難読化(1)

ProGuardすごいですね!それほどでもない。
と思ってたけどよく見たらGUIがあるじゃん、ということでやる気回復したので、
ちょっと試してみることにした。

経緯としては
  • 自社製コンポーネントをライブラリとして社外提供するお仕事発生
  • Javaでライブラリ提供とか、ソースコード丸見えも同然じゃないか…
  • EclipseでProGuard使ってたんだから、アレで難読化出来ないかな? -> 無理でした。
  • StackOverflow見たけどやっぱり「JARの難読化は出来ねえよ!」って書いてある
  • アイエエエ…
で、一度はあきらめてた。
成せばなるんだからぁ…ということで、他の難読化ツール使えないかと調べ直し。

世の中にどんな難読化ツールがあるかというのは以下のページにまとめてありました。

  • http://d.hatena.ne.jp/second_sky/20051220/1135052529
  • http://web.archive.org/web/20100430134447/http://cafebabe.jp/item/7
上のは「難読化(obfuscation)」ツールだけをまとめたリンク。
下のはクラスファイルの暗号化とか最適化とかのツールもまとめてあります。感謝。

で、お金掛かる奴はややこしいので今回はパスということで、フリーで使えそうなのは
この二つかな。
ProGuardはおなじみのアレ。EclipseでAndroid開発やってたら最近ははじめから使える奴。
二つ目はよくわからないけどabsolute free!とか書いてあるのでフリーですね。
結局使わなかったのでこれは置いておきます。

で、ProGuardを良く見直すと、当然ながら単体でも利用可能な訳ですね。
というわけで落としてきて解凍すると「proguardgui.jar」などというファイルが。
これを
java -jar proguard.gui.jar
とやって起動してみたら見事にGUIが立ち上がりました。GUIヤッター!
コマンドラインでもまぁEclipseで使ってるような設定ファイル書けば使えるんだろうけど、書式調べるのがめんどくさいのよね…。
というわけでおとなしくProGuardを使ってライブラリJARを難読化してみることにしました。
これで冒頭に戻ってきました。

 具体的な使い方は次回に詳しく書くとしましょう。
-> ProGuardによるライブラリとしてのJARの難読化(2)

2012年7月11日水曜日

iPod LibraryからのAVAudioPlayerによる再生

かなりハマって調べたのでここにまとめておく。

まず、iPhone/iPodでの音楽ファイルは、アプリケーションのリソースとして持ち込むか、iPodのライブラリにある物が扱える。
が、iPodのライブラリ内の曲は基本的に「AVPlayer」か「MediaPlayer」でしか再生出来ない。
しかし、これらのコンポーネントは非常に自由度が低いので、AVAudioPlayerなどで再生したくなったわけだ。

まず、iPodライブラリからMPMediaItemとして取得した音楽ファイルを、AVAudioPlayerで開こうとしても容赦なくエラーでぬるぽとなる。(実際にはinitに対してnilを返してくる)
これを無理矢理開くには、一旦iPodライブラリからファイルをエクスポートし、ローカルのリソースとして扱わなければならない。
このあたりの経緯は以下のwebpageにて解説されている。感謝。

iPodライブラリからのファイル書き出し その1
http://objective-audio.jp/2010/08/ipod.html
iPodライブラリからのファイル書き出し その2
http://objective-audio.jp/2010/08/ipod-1.html
ついでに参考:http://unlimapps.com/?p=41

簡単にまとめておくと、"AVAssetExportSession"を使ってiPodLibraryからファイルをexportする事になる。
しかし、素直にpresetNameを"AVAssetExportPresetAppleM4A"にした場合、mp3がexportできない。
なので、AVAssetTrackを取り出し、そこからAudioStreamBasicDescriptionを取得して、その中のファイルタイプを利用する。
presetNameはAVAssetExportPresetPassthroughを使用する。


書き出すあたりまでは上記でサンプルソースまであるので難なく行ける・・・と思ったがそうはいかない。
二つ目の記事で書かれているように、このコードはiOS5.1以降ではうまく動かない。
(記事にはiOS4.2以降では動かないかも?とある)

というわけで探しまくった結果、以下の記事を発見。


get error code -11843 while exporting mp3 file in ipod library since iOS 5.1
http://stackoverflow.com/questions/9653241/get-error-code-11843-while-exporting-mp3-file-in-ipod-library-since-ios-5-1


まさに、5.0までは動いていたのに5.1ではダメになった。ナンデ?という話。
この人は自力でworkaroundを見つけ出してくれていた。ワザマエ!


つまり、AVAssetExportSessionに設定するoutputURLの拡張子として、mp3の場合は"mov"にしなければ失敗する、ということ。

おそらくAVAssetExportSessionの内部実装でエラーのチェックが強化されたのだろう。
outputFileTypeとして"com.apple.quicktime-movie"を設定している以上、拡張子はmovで無ければならないという拡張子原理主義者がAppleに入社したとかそんな感じではないだろうか。めんどくせぇ。爆発四散するべき。

というわけで、上記の情報を元にファイルを書き出し、拡張子をmovからmp3に変えたファイルをAVAudioPlayerに食わせたところ、無事に再生できました。
なおiOSは5.1.1です。

2012年2月7日火曜日

TBi11Mで解像度別drawableが適用されない

まぁこの機種に限ったことでは無いのかもしれないけど。
TBi11MはモトローラのAndroidタブレットの事です。

で、こいつはどうもmdpiな機種の様なので、hdpiな機種とはレイアウトを分けて対応することに。
ビットマップはViewに直接張る奴と、プログラムでSurfaceViewに直接描く奴があるので、
前者は drawable-hdpi に入れて自動スケーリングを期待。
後者については drawable-nodpi に放り込んでみました。

結果、前者は良いのだが後者がダメ。
追いかけてみると、リソースから取得したビットマップが見事にスケーリングされている。
(元は128x128が85x85に)

プログラム描画処理の方は128x128前提で描いているので当然ひどいことに。
まぁ、Density見て補正すりゃいいんですが、それはここでは問題ではない。

問題は、「何故drawable-nodpiに入れたビットマップがスケーリングされてるの」ということ。
どう調べてもこの動作には納得がいかない…。

機種固有の問題なのか、Android3系の問題なのか、実は元々そうなのか。

なお、hdpiとnodpiに分けないで、全てのビットマップをnodpiに放り込むと問題無くなる。
この場合はスケーリングされない訳で。ますますわけわからん。
解像度の混在が出来ないの?

結局の所はとりあえず全部nodpiで行ってみることにしました。

2011年12月13日火曜日

ProGuardを実行したときに出たエラーの対処

ProGuardを使ったときに「Conversion to Dalvik format failed with error 1」というエラーが出た場合の話。
以下のページにWorkaroundがあるので、バッチファイルの修正を行えば行けた。

http://wada811.blog.fc2.com/blog-entry-62.html

念のため、内容をコピペしておく。以下引用。

タイトルの通り、「Conversion to Dalvik format failed with error 1」というエラーが出る場合の対処法です。
このエラーが出たらやることは基本的に一つ。Eclipseのクリーンです。
今回はそれでも改善されずにapkファイルが作れなかった場合について書いておきます。

もしかして:Android SDK Tools r12 にバージョンアップした

当てはまる人はこの記事の内容で対処できるはずです。
この問題は既に報告されているようです。
Android SDK tools revision 12 has problem with Proguard - Android - An Open Handset Alliance Project
Android SDK Tools r12 に含まれるProGuardのバージョンが古いためバグを内包しているというもの。
解決法は主に二つ

proguard.batを書き換える
ProGuardの最新版をダウンロードしてきて置き換える

proguard.batを書き換える

[Android SDK]\tools\proguard\bin

を開きます。
proguard.bat をエディターで開きます。
内容をコピーします。(おそらく書き換え禁止になっているので)
エディターを新しく開き、コピーしたものを貼り付けます。

call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %*

を

call %java_exe% -jar "%PROGUARD_HOME%"\lib\proguard.jar %1 %2 %3 %4 %5 %6 %7 %8 %9

に書き換えます。
proguard.bat というファイル名で保存して元の proguard.bat と置き換えます。
コレでapkファイルを作れるようになったと思います。
一部の人はこれでもできない場合があるらしいです。
ProGuardの最新版をダウンロードしてきて置き換える

ProGuard Java Optimizer and Obfuscator - Browse /proguard at SourceForge.net にアクセスします。
Android SDK Tools に含まれる ProGuard4.4 より新しいものを選ぶ(現在なら 4.6 が最新なので 4.6 が好ましい)
ダウンロードしたファイルを解凍します。
bin フォルダと lib フォルダで Android SDK Tools の proguard フォルダの bin フォルダと lib フォルダを置き換えます。
コレでapkファイルを作れるようになったと思います。

これでも直らない場合はお手上げです。あとは頑張ってください。

「resources.ap_ does not exist」が出る

EclipseでAndroidアプリケーションを開発しているときに、不意にハマった現象。

もしかして:Eclipseのオプションで、Android > Build > Build output > Verbose にしていないか?
今回ハマった現象はこれで、ADT14のaaptが-vオプション有りで死ぬらしい。
https://code.google.com/p/android/issues/detail?id=20395 参照。

注:これを書いている時点でADT16がリリースされていたので、もう直ってるかも。

そうでなければ以下を参照。

stackoverflow.comの記事
http://stackoverflow.com/questions/4437023/resources-ap-does-not-exist-when-compile-my-android-project

他のマシンで動作するシンプルなサンプルでも、自分の環境では冒頭のエラーで実行出来ない症状。
いくつかのWorkaroundが存在する。

1. Project > Clean を実行する(いくつかの派生がある。Clean,Delete gen,restart eclipseとか)
2. 指摘された場所に「resources.ap_」という空ファイルを作成してClean/Rebuildする
3. 不正なリソースファイル(adbの認識出来ないPNGファイルとか)を削除する。ただしこの場合は別のエラーが出ているはず。
4. aaptをアップデートした際に、順序のない書式指定文字列をビルドエラーとして扱うようになった。
ちょっとややこしい。
This was my problem as well. Basically anywhere in your strings.xml where you have any combination of %s or %d in the same string, replace them with %1$s or %2$d where the number between the % and $ is the order in which they are placed in the string. For exmaple: "Blah %d something %s" should now be "Blah %1$d something %2$s" – GuyNoir Dec 26 '10 at 20:12
Oh, you did not mention that you upgraded to SDK v8 when you encountered the problem. Yes, the SDK is more strict now when it comes to ordering format strings. :) – Zarah Jan 9 at 18:06
It can't be, we can find this problem in android sdk examples, SearchableDictionary has this problem ._. – rubdottocom Feb 22 at 16:48
5. "gen"を消してからProject > Build All を実行して、R.javaを再生成する。
6. API-Levelが間違っている。正しいLevelを選択すればよい。
7. string.xmlに問題がある。最低限必要な分を残し、一回全部消してみる。
8. Admob adsを使っている場合に
1) I was using Admob ads, and I didn't have an attrs.xml file in my res/values folder
2) I deleted a line that says "import andriod.R" from my main activity, and all my resources connected again and this ultimately made the error go away.
3) The last thing I had wrong is I had a "lib" folder instead of a "libs" folder that held my Admob jar file.
Lastly, I cleaned the project after these changes.
9. (Alt-Shift-Q then X)でなんかでてくる?他にもConsoleのproblemログをきちんと確認する。(異常なリソースファイルとかはこれでわかるかも)
結構9patchで問題が出ている場合が多いっぽい。作り方の問題か?
10. バックスラッシュをstrings.xmlに含んでいる
11. アップデート時に問題が出た場合、プロジェクトのバックアップから復元し直してみることで治るかもしれない。
12. binおよびgenを消して、リフレッシュ(F5)してみる
13. eclipseのWorkspaceの".metadata"が壊れている。Workspaceを作り直す。ただしEclipseの環境は1から作り直しになる。

2011年12月12日月曜日

ProGuardを使う

というわけで、必要になったのでProGuardを使ってみた。

基本的な情報はWebでいろいろ拾える。参考にしたのは

  • http://y-anz-m.blogspot.com/2010/10/androidlvl-securing-android-lvl.html
  • http://d.hatena.ne.jp/bs-android/20101207/1291702021
  • http://d.hatena.ne.jp/hyoromo/20101120/1290216449
このあたり。

で、いざ実践してみてハマったところとか気がついたところをまとめておく。

まず、上記参考URLの情報では、"default.properties"にパスを追加するということが書かれているのだが、これではProGuardが走らなかった。
正解は"project.properties"の方に書く。
実際に新しいプロジェクトを作成して見るとそうなっているので、そのまま持ってくるようにすれば良い。

proguard.cfg自体はEclipse上でコピー&ペーストすればOK。

んで、どっかで外部ライブラリは難読化されないと書いてた気がするんだけど、
自分で作った物はちゃんと難読化されている様子。
今回だとLVL(Licensing Verification Library)を併用しているんだけど、
そっちのクラスが難読されている様子が、mapping.txtにはき出されていた。

そして難読化してはいけないもの。
JNI関係は難読化してはいけない、というのは上記参考URLにも書いてある。
これは具体的には"native"接頭辞を付けたメソッドを宣言しているクラスをkeepに指定すれば良い。
逆にこれを難読化すると、JNIのメソッドが一切呼ばれなくなる。エラーは吐かないのでわかってないとハマるかも。
LVLは特に書かなくても動いてるなー。あとでなんか問題でてくるかも?
もしくはデフォルトで書いてある

-keep public class com.android.vending.licensing.ILicensingService

という指定で行けてるような気がする。

2011年11月28日月曜日

作ってみた。

技術的な事とかで調査した内容はTwitterではつぶやきにくいので、ブログを作ってみた。

まぁ技術的な事に限るつもりは無いけど、基本的には自分用メモって事で。

特に宣伝する気も無いのでこの文章を読む人間が居るかどうかは怪しいが…