新しいノートブック

Android大好き

ADT(Eclipse)プロジェクトをAndroid Studioに移行した際の'duplicate entry'

ビルドエラー

Eclipseでexportしたものをimportしてビルドしようとするとこういうやつが出ます

Error:Execution failed for task ‘:app:transformClassesWithJarMergingForDebug'. > com.android.build.transform.api.TransformException: java.util.zip.ZipException: duplicate entry: android/support/annotation/AnimRes.class

原因

クラスの競合が発生。

ほとんどの場合依存モジュールのjarが悪さしてます(support-v4とか)。 gradle的に複数の同じjarを管理するのはダメらしい。

第51章 依存関係の管理 http://gradle.monochromeroad.com/docs/userguide/dependency_management.html

依存関係を確認する

右のタブ「Gradle」から対象のモジュールを選択. Tasks > android > androidDependencies 「Run ...」を選択 下のコンソールにBuildVariants毎の依存関係が表示される

もしくは

terminalに下記をうちこむ

./gradlew androidDependencies

ライブラリの依存関係が表示されるので、重複してるものを見つける

対策

build.gradleから適所excludeするなり, 物理的に削除するなりする。

dependencies {
    compile(project(':hoge')) {
        exclude module: 'support-v4'
    }
    compile('hoge') {
        execlude module: 'support-v4'
    }
}

備考

ADTモジュールをインポートした場合、jarファイルは自動的にgradleの依存関係に置き換えられるみたい。ただし、最新のバージョンを使用するようです。

インポート時に下記のような警告が出る。

the adt project importer can identify some .jar files and even whole source copies libraries, and replace them with gradle dependencies. However, it cannot figure out which exact version of the library to use, so it will use the latest. if your project needs to be adjusted to compile with the latest library, you can either import the project again and disable the following options, or better yet, update your project.

参考URL

DroidKaigi2016に行ってきました

神戸から参加の僕は朝4時起きで始発で出発、会場付いたのが9:50分くらいでギリギリ。新幹線で色々予習しておこうと思ったけど見事に爆睡。

下記の公演に参加してきました。参加したい公演被ってたのも結構あったけど後に公開してくれるということで楽しみにしてます。

■ 1日目
・明日から使えるRxJava頻出パターン @kazyさん
・史上最速のAndroid @kmt-tさん
・僕がテスト書け書けおじさんになった経緯とその過程でやったこと @yuyakaidoさん
・最速でリリースするためのAndroidアプリデザイン @青山 直樹さん
・Dagger2とRealmを利用したモダンな開発 @北村 涼さん
・用途に合わせたアニメーションの実装方法 @住友孝郎さん
・明日、敗訴しないためのセキュアコーディング @kengoscalさん

■ 2日目
クックパッドにおけるAndroidエンジニアの役割とその変遷 @sys1yagiさん
・Customizing Theme and Style for Material Design @あんざいゆきさん
・カメラアプリはじめの一歩 @mhidakaさん
・17ヶ国の多言語対応Tips @konifarさん
Android実プロダクトへのKotlinの導入事例 @山本純平さん
Androidエンジニアになって2年の学び @宮下 竜大郎さん
・Fireside Chat About Official AndroidApp

公演内容とかは直接スライドみて頂いたほうがいいと思うので割合します。

今後取り入れたいなーと思うところを重点的に攻めたのですが、要点をわかりやすく解説してくださったので、非常に有意義な時間でした。
何より年齢の近い方が多くモチベーションになった!あと昼食普通に美味しかったです。来年もあるなら是非参加したいですね。

もっと勉強会っぽい写真撮れば良かったと反省。
帰ったらRxとKotlin勉強しよう。

f:id:sooch:20160912052305j:plain

f:id:sooch:20160912052345j:plain

複数行入力可能なEditTextで高さの初期値と最大値を指定する方法

やりたいこと

  • 文字が端までいくと自動改行する
  • EditTextの初期の高さを任意の値に
  • EditTextの最大の高さを任意の値に

やったこと

文字が端まで行くと自動改行する

  • layout_height="wrap_content"
  • inputType="textMultiLine" (初期値がこれなので省略可)

初期の高さを任意の値に

  • 行数を指定する場合minLinesを設定する
  • dpを指定する場合minHeightを設定する

最大の高さを任意の値に

  • 行数を指定する場合maxLinesを設定する
  • 数値を指定する場合maxHeightを設定する

こうなった

<EditText
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:inputType="textMultiLine"
        android:minLines="2"
        android:maxLines="5"
        android:background="@color/colorAccent"
        />

f:id:sooch:20160530232347g:plain

備考

複数行に対応しmaxLinesやmaxHeightを指定しなかった場合は、伸長可能なところまでViewが伸び、それ以降はViewの中がスクロール出来るようになる。

Canvasでベジェ曲線描画とクリッピング

ベジェ曲線とは

n個の制御点から得られるn-1次曲線です (wikipediaより)

こちらに解りやすく図解していました。
sigbus.info: 中学生でもわかるベジェ曲線

ベジェ曲線を描く

Pathクラスにベジェ曲線を描くAPIが用意されています。

前者が2次ベジェ, 後者が3次ベジェです。制御点の数が違います。

引数 : 制御点1X, 制御点1Y, 終点1X, 終点2Y
Path#quadTo (float x1, float y1, float x2, float y2)

引数 : 制御点1X, 制御点1Y, 制御点2X, 制御点2Y, 終点1X, 終点2Y
Path#cubicTo (float x1, float y1, float x2, float y2, float x3, float y3)

始点はPathの現在地になります。(デフォルト値はx0, y0)

cubicToで一角描画してみます。

  @Override
  protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      
      Paint paint = new Paint();
      paint.setStrokeWidth(2f);
      paint.setColor(Color.WHITE);
      paint.setAntiAlias(true);
      paint.setStyle(Paint.Style.STROKE);
      
      Path path = new Path();
      // スタート地点を移動
      path.moveTo(250, 0);
      // 制御点1 X, 制御点1 Y, 制御点2 X, 制御点2Y, 終点X, 終点Y
      path.cubicTo(450, 0, 500, 50, 500, 250);
      
      canvas.drawPath(path, paint);
  }

f:id:sooch:20160912221823p:plain

クリッピング

クリッピングするには矩形を描画する必要があります。
隙間があると失敗します。

  @Override
  protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
           
      Path path = new Path();
      // スタート地点を移動
      path.moveTo(250, 0);
      // 制御点1 X, 制御点1 Y, 制御点2 X, 制御点2Y, 終点X, 終点Y
      path.cubicTo(450, 0, 500, 50, 500, 250);
      path.cubicTo(500, 450, 450, 500, 250, 500);
      path.cubicTo(50, 500, 0, 450, 0, 250);
      path.cubicTo(0, 50, 50, 0, 250, 0);
      canvas.clipPath(path);
      
      Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.eventnews1082);
      canvas.drawBitmap(bitmap, 0, 0, null);
  }

f:id:sooch:20160912221825p:plain

Javaの浮動小数点比較はcompareメソッドを利用しよう

浮動小数点の比較するためのcompareメソッドが用意されています。
一致する場合は0、そうでない場合は1を返します。

// 差分なしなら0 ありなら1
int diff = Float.compare(float1, float2);
if(diff == 0) {
    // do something
}

’==’の比較がなぜだめか

NaNやInfinityな場合があったり、打ち切り誤差が生じることがあるため、 想定した結果と違ってしまう場合があります。

参考URL

下記で詳しく解説してます。
http://msugai.fc2web.com/java/class/DecimalTips.html

ミリ⇔ピクセル変換

公式は決まっていますが、解像度(DPI)によって値が変わります。
下記の式で求められます。

1辺の長さ x 解像度 / 25.4 (1インチのミリ数)
dpi / 25.4 * mm = px
25.4 / dpi * px = mm

以上(´・ω・`)

AsyncTaskについてメモ

Executor

■ AsyncTaskで選択出来る実行モード
・THREAD_POOL_EXECUTOR (パラレル実行)
・SERIAL_EXECUTOR (シリアル実行)

■ AsyncTask#execute() を実行した際の実行モード
・Gingerbread(2.x系)
THREAD_POOL_EXECUTORが採用される
・ICS以降(4.x系~)
SERIAL_EXECUTORが採用される

■ ICS以降でパラレル実行するには
AsyncTask#executeOnExecutor(Executor, Object…)メソッドを使用する
ExecutorにAsyncTask.THREAD_POOL_EXECUTORを指定

パラレル実行時のスレッドプール

下記のように設定されている模様。
並列多重度: 5 (CORE_POOL_SIZE)
最大プール数: 128 (MAXIMUM_POOL_SIZE)
キューイング数: 10 (sPoolWorkQueue)
並列処理が5多重を超えるとキューイングされる。
要求のキューイングが出来なかった場合は最大128までプールする。

GridViewを高速スクロールした際などに、プール数が128を超えてしまい、
RejectedExecutionExceptionがthrowされる
Viewの参照を渡す場合はWeakReferenceを使用する

ViewがGCで破棄されるタイミングはActivityが破棄されるタイミングであるべきなので、
AsyncTaskがViewの参照を保持しないよう、WeakReferenceを使用する。