Freelineとはなにものか
これはAndroidその2 Advent Calendar 2016の23日目の記事です。
はじめに
昨今Androidのbuildまわりの話は結構盛り上がっているなーと感じます。 Androidのbuildをしてるとマシンリソースをもっていかれて他の作業に支障がでたりすので、自分のマシン以外に誰も使ってないマシンをbuildサーバ的に使ったり、GCPなどのクラウドリソースを使ったりすることで解消する方法が様々出てきています。 それ自体は最高だな!自分も職場では使っていくぞ!という気持ちで実際空いてるiMacを使ってbuildしたりしています。
一方でbuild自体が高速で終わればbuild中に何分間も他のことができない!みたいな状況はないのではないかとも思います。 また個人開発として考えた時に、札束で叩く選択肢はなかなか取りづらいよなーと思ったりもします。 そこでひとつの解決策として良さそうなのが今回紹介するalibaba/freelineです。
Freelineとは
概要
githubのREADEMEの導入部分を引用すると下記のように紹介されています。
Freeline is a fast build and deployment tool for Android. Caching reusable class files and resource indices, it enables incrementally building Android apps, and optionally deploying the update to your device with hot swap.
Developed and used by Ant Fortune (about us) Android Team, Freeline has been significantly saving time in daily work. Inspiring by Buck and Instant Run but faster than ever, Freeline can finish an incremental build in just a few seconds. No more recompile and reinstall again and again before seeing your modifications, Freeline brings life-changing development experience for Android.
要点だけまとめるとこんな感じです。
- ホットスワップを可能にするぜ!
- BuckとInstant Runにインスパイアされているが、それらよりもより早く動作するぜ!
- FreeLineはAndroid開発生活に変革をもたらすぜ!
完全に意訳ですが、ノリとしてはこれぐらいハッピーな感じで書かれてるんじゃないかと勝手に理解しました。
詳細
特徴
また下記の項目の変更に対応しているようです。
Java | drawable, layout, etc. | res/values | native so | |
---|---|---|---|---|
add | √ | √ | √ | √ |
change | √ | √ | √ | √ |
remove | √ | √ | x | - |
他にもたくさんあるようですが、RADEMEに記載されているので興味がある方はご覧ください。
まだまだな点
- 初回だけちょっと遅い
res/values
の削除には対応できていない- 抽象クラスのインクリメンタルビルドはできない
- Kotlinはサポートしていない
最近の国内でのKotlin熱を考えるとサポートしてないのはちょっとつらいかもしれないですね。
Freelineの使い方
githubにsampleプロジェクトがあるので、それを使ってみます。 手順はこれだけ。
git clone git@github.com:alibaba/freeline.git cd freeline/sample ./gradlew initFreeline python freeline.py
実際にコマンドの実行をしているところを動画に収めたのでご覧ください。 (本当はttyrecとttygifを使ってgif化したかったのですが、謎のエラーでttyrecが使えず今回の記事では諦めましたorz)
— futabooo (@futabooo) 2016年12月23日
なんかtaskが並行実行されてる雰囲気がわかっていただければ幸いです。 既存の自分のプロジェクトに導入する場合はbuild.gradleへの記述などありますが、READEMEに書いてあるので簡単に導入可能です。
おわりに
手元にある大きめのプロジェクトはkotlinが入っていたりしてうまく動かなかったので、Freelineでどれだけ早くなるのか比較を書くことができずに終わってしまいました。 この記事をみてFreelineを試した方にぜひ比較結果をコメントもらえたらなーと思っています。
またほとんどFreelineのREADMEを紹介するだけになってしまいましたが、今回本当に紹介したかったのは下記の記事です。 中国語で書かれており、内容の把握に骨が折れますがFreelineがどのように実装されているのか詳細な紹介がされています。 Androidのフレームワークの知識が必要なため僕自身グーグル先生とともに解読中です。
参考
Amazon Kindle本のセールのAndroid界隈の本をまとめてみた
はじめに
全部Kindle本です。Androidで検索すればもっといっぱい出てきますが、有名ドコロだけ集めてみました。 半分ぐらい持ってなかったので買っちゃいました。
AndroidのKindle本
Google Androidプログラミング入門 改訂2版 (アスキー書籍)
50 Android Hacks 開発現場ですぐに役立つヒントとコード (アスキー書籍)
良いAndroidアプリを作る139の鉄則
Smashing Android UI レスポンシブUIとデザインパターン
Android Pattern Cookbook マーケットで埋もれないための差別化戦略
Android Security 安全なアプリケーションを作成するために
これはちょっと番外編だけど。 Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築
開発中のアプリのSQLiteDBを取得する
よく忘れるし、書くのがめんどいのでスクリプトにして見ました。
gist6154e60df4009a142a19
効率化できたのかは謎。
AndroidManifestのapplicationタグにクラスを2つ指定したくなった時にやったこと
もともとActiveAndroidを使っていたので下記のようなManifestでした。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.nilab.dribbbleviewer" > <uses-permission android:name="android.permission.INTERNET"></uses-permission> <application android:name="com.activeandroid.app.Application" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <meta-data android:name="AA_DB_NAME" android:value="sqlite.db" /> <meta-data android:name="AA_DB_VERSION" android:value="1" /> <activity android:name="com.nilab.dribbbleviewer.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
ここからVolleyのシングルトンクラスを追加しようと下記クラスを追加(参Android working with Volley Library)
package com.nilab.dribbbleviewer; import android.app.Application; import android.text.TextUtils; import com.activeandroid.ActiveAndroid; import com.activeandroid.Configuration; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.Volley; public class AppController extends Application { public static final String TAG = AppController.class.getSimpleName(); private RequestQueue mRequestQueue; private ImageLoader mImageLoader; private static AppController mInstance; @Override public void onCreate(){ super.onCreate(); mInstance = this; } public static synchronized AppController getInstance(){ return mInstance; } public RequestQueue getRequestQueue(){ if(mRequestQueue == null){ mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } return mRequestQueue; } public ImageLoader getImageLoader(){ getRequestQueue(); if(mImageLoader == null){ mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache()); } return mImageLoader; } public <T> void addToRequestQueue(Request<T> req, String tag){ req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); getRequestQueue().add(req); } public <T> void addToRequestQueue(Request<T> req) { req.setTag(TAG); getRequestQueue().add(req); } public void cancelPendingRequests(Object tag) { if (mRequestQueue != null) { mRequestQueue.cancelAll(tag); } } }
ここから結局ManifestとApplicationクラスを継承したクラスを下記のように書き換えて動きました。
Manifestはapplicationタグの中を書き換え。
<application android:name="com.nilab.dribbbleviewer.AppController" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <activity android:name="com.nilab.dribbbleviewer.MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
AppControllerはonCreateの中と新たにメソッドを一つ追加。
public class AppController extends Application { @Override public void onCreate(){ super.onCreate(); Configuration.Builder builder = new Configuration.Builder(getBaseContext()); builder.setCacheSize(1024*1024*4); builder.setDatabaseName("sqlite.db"); builder.setDatabaseVersion(1); ActiveAndroid.initialize(builder.create(), true); mInstance = this; } @Override public void onTerminate(){ super.onTerminate(); ActiveAndroid.dispose(); }
以上。
美しくないですね。。。
AndroidStudio0.5.4でFacebookSDKを追加する方法
環境
OSX 10.9.2
AndroidStudio 0.5.4
FacebookSDK 3.8.0
FacebookSDKにかかわらず、ライブラリーを追加する場合は大抵この方法でしょう。
1.FacebookSDKを設置
FinderでコピペでAndroidStudioにも反映されます。
追加後は下記のようなフォルダ構成です。
/Users/futabooo/AndroidStudioProjects/Iwaeme/libraries/facebook
2.settings.gradleを編集
settings.gradleを編集します。
後半部分を追加。
include ':app', ':libraries:facebook'
3.build.gradleを編集
開発するプロジェクトの方のbuild.gradelを編集します。
最後の1行を追加。
dependencies { compile 'com.android.support:support-v4:19.+' compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':libraries:facebook') }
4.確認
Sync Project with Gradle Filesを押下して設定を反映させたのち、
下記のように補完が聞けば追加に成功しています。
GooglePlayで公開するためのkeystoreを作成する
ターミナルで下記コマンドを適宜書き換えて実行。
色々質問飛んでくるので全部入力すれば、カレントディレクトリにkeystoreファイルが作成される。
keytool -genkey -v -keyalg RSA -keystore 証明書ファイル名.keystore -alias 証明書別名 -validity 有効期限の日数
AndroidのEditTextにフォーカスがある時にキーボードの全画面表示を抑制する
XML上で、EditTextのプロパティで下記の1行を追加
<EditText android:imeOptions="flagNoExtractUi | flagNoFullscreen" />
flagNoExtractUiはAPIレベル1使えるオプション
flagNoFullscreenはAPIレベル11から使えるオプション
今後はflagNoFullscreenだけ使っていればいいと思いますが、
いまだにAndroid2.3とかもシェアがあるので両方指定しとく。
ただこのオプション、端末側の設定で強制的に効かなくすることもできるようなので、
端末によってはフルスクリーン表示が抑制できないかもしれません(´・ω・`)
更に、フルスクリーン表示しなくすることで下のViewが見えなくなって入力してる文字がみえなくなるかも。
その時の解決方法まではまた今度。