読者です 読者をやめる 読者になる 読者になる

新しいノートブック

Android大好き

Android Studio 2.3にアップデートするとandoird-aptがエラーを吐く対応

Gradle2.2より、アノテーションプロセッサがサポートが組み込まれています。 これによって、Gradle2.3よりandroid-aptプラグインのサポートが公式に廃止されています。

build.gradle

android-aptプラグインを削除します。

dependencies {
  classpath 'com.android.tools.build:gradle:2.3.0'
//  classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  classpath 'me.tatarka:gradle-retrolambda:3.2.5'
}

app/build.gradle

android-aptに依存するライブラリを使用していた場合は、依存設定も変更する必要があります。 annotationProcessor構文を使用するには、必ず最新のGradleバージョンにアップデートしてください。

dagger2の設定

// apply plugin: 'com.neenbedankt.android-apt'
...
dependencies {
  compile "com.google.dagger:dagger:2.9"
  annotationProcessor "com.google.dagger:dagger-compiler:2.9"
  provided 'javax.annotation:jsr250-api:1.0'
}

参考URL

Raspberry Pi3にsambaを導入

sambaの導入

sudo apt-get update
sudo apt-get install samba

設定ファイルの変更

設定ファイルは/etc/samba/smb.confになります。まずはバックアップしておく。

sudo cp -p /etc/samba/smb.conf /etc/smb.conf.orig

共有ディレクトリを追加。ファイル下部に設定を追記していく。

ログインしたユーザがpathに対しての書き込み権限が無い場合、ファイルの書き込みが出来ないので注意。force userが設定されている場合は、ログイン・ゲストにかかわらずforce userの権限による。

sudo vim /etc/samba/smb.conf

# 設定例
[share] # ディレクトリの表示名
   comment = Network Logon Service # ディレクトリ説明欄に表示される文章
   path = /mnt/hdd1/storage # 実際に参照されるディレクトリパス
   guest ok = yes # ゲストユーザを許可
   writable = yes # 書き込み許可
   force user = pi # ファイル作成時のオーナー

sambaを再起動

sudo service smbd restart
sudo service nmbd restart

自動起動の設定

sudo update-rc.d samba defaults

Macからアクセス

cmd + KもしくはFinderメニューの表示 > サーバへ接続...を選択。 サーバアドレスにsmb://IPアドレスと入力します。

Windowsからアクセス

エクスプローラのアドレス欄に¥¥IPアドレスと入力します。

参考URL

Raspberry Pi3で外付けHDDをマウントする

RaspberryでNASを構築するため、外付けHDDをマウントします。 今回はこちらのHDDを使用しました。
I-O DATA HDD 外付けハードディスク 4TB USB3.0

HDDの接続

外付けHDDをUSB接続し認識されているか確認。

# ディスクをリスト表示
sudo fdisk -l | grep /dev/sda

/dev/sda1      34     262177     262144  128M Microsoft reserved
/dev/sda2  264192 7814036063 7813771872  3.7T Microsoft basic data

USB給電タイプの場合、Raspberryからの供給電力に制限があり、必要電力に足りなくなる場合があるので注意が必要です。 Raspberry側のconfigを弄ることで供給電力の変更もできますが、設定次第で動作が不安定になることもあるので、ここらへんは購入前に調査しておく必要があります。

HDDをフォーマット

パーティションファイルシステムの設定を行います。

# パーティションテーブルの設定を行います
sudo fdisk /dev/sda

# d でパーティションを削除
Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

# p で現在の状態を確認
Command (m for help): p
Disk /dev/sda: 3.7 TiB, 4000787030016 bytes, 7814037168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: F3BA4D9C-C2F7-43FF-837C-D3BFBFBF5C1D

# n でパーティションを作成 その後の設定で何も入力しない場合全てデフォルトとなる
Command (m for help): n
Partition number (1-128, default 1):
First sector (34-7814037134, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-7814037134, default 7814037134):

Created a new partition 1 of type 'Linux filesystem' and of size 3.7 TiB.

# p でもう一度確認 パーティションが追加されています
Command (m for help): p
Disk /dev/sda: 3.7 TiB, 4000787030016 bytes, 7814037168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: F3BA4D9C-C2F7-43FF-837C-D3BFBFBF5C1D

Device     Start        End    Sectors  Size Type
/dev/sda1   2048 7814037134 7814035087  3.7T Linux filesystem


# w で変更を書き込みます
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.

ext4でフォーマットする

ext4でフォーマットするとLinuxシステムでの読み込みがNTFSより早くなります。その代わりWindowsで認識できなくなります。

sudo mkfs.ext4 /dev/sda1

Creating filesystem with 976754385 4k blocks and 244195328 inodes
Filesystem UUID: fa16b72b-a2d0-4331-9693-e417727f3b53
Superblock backups stored on blocks:
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
    4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
    102400000, 214990848, 512000000, 550731776, 644972544

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done   

マウントする

/etc/fstabにデバイスを登録することにより、起動時に自動マウントすることができます。 またデバイスのパスではなくUUIDを登録しておくことにより、デバイスのパスが変更されてもマウントすることが可能です。

マウントポイントを作成

必要に応じてマウントポイントを作成します。今回は/mnt/hdd1としました。

sudo mkdir /mnt/hdd1

UUIDを調べる

# ブロックデバイスの情報を表示する
sudo blkid /dev/sda1
/dev/sda1: UUID="fbab8a4f-3211-4b03-b53a-1579c93054aa" TYPE="ext4"

fstabを編集

fstabでの設定が正しくない場合、再起動時にemergency modeで起動されます。 ハマるとずっと起動できないといったことになるので、必ずバックアップをとっておく。 また、オプションにnofailを指定することで、エラーの設定項目を無視して起動してくれる。

# バックアップをとっておく
cd /etc
sudo cp fstab fstab.bak

# fstabを編集しマウント設定を追加
sudo vim fstab
# デバイス名 マウントポイント ファイルシステム オプション dump指定 fsck指定
UUID=fbab8a4f-3211-4b03-b53a-1579c93054aa /mnt/hdd1 ext4 nofail 0 0

# 再起動
sudo reboot

確認

マウントされていることを確認します。

df | grep /mnt/hdd1
/dev/sda1       3845578572   69632 3650141680    1% /mnt/hdd1

参考URL

RxJava私的メモ

Observableの生成

・from
IterableなオブジェクトからObservableを生成。

Observable.from(T[] array)  
Observable.from(Iterable<? extends T> iterable)  
Observable.from(new String[]{"a", "b", "c"})  

・create
OnSubscribeを指定してObservableを生成。

Observable<String> o = Observable.create(subscriber -> {
            subscriber.onNext("Hello");
            subscriber.onNext("world!");
            subscriber.onCompleted();
        });

・range
要素の範囲を指定してObservableを生成。

Observable<Integer> o = Observable.range(1, 5);  

・just
引数で直接Observableを生成

Observable<Integer> o = Observable.just(1, 2, 3);  

subscribeOnとobserveOn

・subscribeOn
ObservableのonSubscribe を実行するスレッドを変更する。
subscribeOnはどのタイミングで呼んでも全てのオペレータに適用される。

・observeOn
以降のオペレータでのコールバックを処理するスケジューラをきめる。

・指定しない場合
Observableの実装や叩いたOperator(map()やfilter()などのメソッド)によりますが、基本的に現在のスレッド(subscribe()を呼び出したスレッド)で「同期的に」実行されます。

Schedulers

指定したオペレータをどのスレッドで実行するかを指定できます。
最初はSchedulers#newThreadとAndroidSchedulers#mainThreadから入ると良いと思います。

・#io
I/O処理のためのScheduler。

・#computation
計算処理のためのScheduler。イベントループ 処理コールバックなど。

・#immediate
現在のスレッドで作業するためのScheduler。処理を割り込んで実行させます。

・#newThread
新規にスレッドを生成します。

・#trampoline
擬似的なマルチタスクとして実行します。

・AndroidSchedulers#mainThread()
メイン(UI)スレッドで実行します。 (RxAndroidを導入する必要あり)

ライフサイクル

意識しないといけないのはsubscribeメソッドが発行するSubscription。

・ライフサイクルに合わせてunsubscribeする
SubscriberのonNext, onErrorでunsubscribeが呼ばれる。
非同期のSubscriptionは投げっぱなしにするとリークするので適所でunsubscribe!

・複数のSubscription
CompositeSubscriptionを利用します。Subscriptionが発行される都度CompositeSubscription#addする。
こちらもライフサイクルに合わせてunsubscribeする。

error operators

通常はsubscribe内でonErrorを実装する. subscribe内がonNextだけの実装になっている場合は,
下記のメソッドを実装する必要がある.
・onErrorReturn
Observableチェインのなかで発生したErrorをキャッチして、大体のObjectに変換することでsubscriberにErrorが渡されるのを防ぐことができます。

・onErrorResumeNext
Observableチェインのなかで発生したErrorをキャッチして、その中で再度Observableを呼び出すことで、エラー時に代替のStreamを返すことができます。

ハマりどころ

onErrorにコンテキストの参照をもたせるとリークする

既存処理をRxに移行する

// 非同期処理に乗せるAPIからのデータ取得メソッド
public List getDataFromApi() {…}

// 戻り値の型をObservableでラップ
public Observable<List> getDataFromApi() {…}

参考URL

RxJava Javadoc 2.0.7

Raspberry Pi3で固定IPを設定する

ローカルIPを固定する

Linuxのネットワーク設定は通常下記に記載されているかと思います。 /etc/network/interfaces

とりあえず開いてみると…

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and ‘man dhcpcd.conf’

上の方になにやらコメントが書いてあり、 固定IP設定するならdhcpd.confを編集しろだそうです。

一番下の下記を記入(数値は適当に置き換えてください)

$ sudo vi /etc/dhcpcd.conf  
interface eth0  
static ip_address=192.168.11.10  
static routers=192.168.11.1  
static domain_name_server=192.168.11.1  

SSHのポートを設定

デフォルトは22に設定されています

$ sudo vi /etc/ssh/sshd_config

Port 22
49152 ~ 65535の間で任意のポート番号を指定します

ssh の再起動

$ sudo /etc/init.d/ssh restart

接続

Terminalから下記を叩きます

$ssh pi@IPアドレス -p ポート番号

リフレクションで生成した文字列に何かの参照の跡のようなものがぶちこまれてる件

リフレクションでモデルクラスから直接GETリクエストを作っちゃうようなケース。
お尻に全然知らないパラメータがくっついてました。

原因

同じ症状にぶち当たってる人を発見した。
http://stackoverflow.com/questions/34647546/a-weird-field-appear-in-android-studio どうやらAndroid Studio 2.0でInstrant Runをサポートするための参照が追加されてるようだ。

備考

Class<? extends Object> clazz = obj.getClass();
clazz.getDeclaredFields();

上記の配列をデバッガで確認すると、

public static transient volatile com.android.tools.fd.runtime.IncrementalChange.{…}.hoge.$change

という参照が確認出来る。

対策

File > Settings > Build, Execution, Deployment > Instant Run
Enable Instant Run to hot swap code/resource change on deploy(default enabled)
チェックを外す

もしくはUSBを抜く。繋いでる時だけ発生するので最初はわけ分からなかった。

リフレクションのご利用は計画的に。

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