2017年5月27日土曜日

【Android7.1】Architecture componentsの調査。AppCompatActivityでLifecycleを利用する

  • 公開日:2017年05月27日

記事概要

Google I/O 2017でandroid-architecture-componentsが発表されました。
なかなか良さそうなライブラリだったので、導入して動かしてみました。

この記事は、android-architecture-componentsを触って感じたことを記載した記事です。

環境

  • buildToolsVersion 25.0.3
  • android.arch.lifecycle 1.0.0-alpha1

lifecycleとは

ActivityやFragmentのライフサイクルに合わせてデータを管理できるライブラリです。
ドキュメントを読んでgoogle code labのサンプルを実装した感じでは、以下のような感想を持ちました。

良い点
  • オブジェクトをActivityやFragmentのライフサイクルに関連づけられるのが良い。onDestory()等の処理が楽になりそう。アプリの停止や生存チェックが減りそう。
  • SNSや通知アプリなどのpub, subを利用するアプリが作りやすくなりそう。RxJavaのFlowableを使うとよりよくなりそう。
  • 縦画面と横画面の作り分けが楽になる。これが一番大きい。
  • Roomは、ibatisに似ている。経験者はすぐに使いこなせるのではないだろうか。RxJavaと連携もできる。
悪い点
  • Observerクラス増えすぎ。どのライブラリもObserverとSubscribeで溢れている。可読性がさらにひどくなる。。
  • 開発者に要求されるハードルがまた上がる。

触った印象では、難しくはないので、考え方に慣れることが大事なのかなと思いました。

実装

1.0.0-alpha1のLifecycleActivityはFragmentActivityを継承しているクラスなので、AppCompatActivityクラスを継承したActivityクラスでは利用できません。かといってLifecycleActivityをそのまま利用するのは機能不足すぎで話になりません。しかも、This class is a temporary implementation detail until Lifecycles are integrated with support library.とあるように、LifecycleActivityは一時的な実装なので利用する意味がありません。
なので、以下のように改造します。

変更前
{project_folder}/MainActivity.java

public class MainActivity extends AppCompatActivity implements HomeFragment.OnFragmentInteractionListener, {

    public static final String TAB_HOME = "TAB_HOME";
    public static final String TAB_COLLECTION = "TAB_COLLECTION";
    public static final String TAB_NOTICE = "TAB_NOTICE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    // something...
}

変更後
{project_folder}/MainActivity.java
public class MainActivity extends AppCompatActivity implements LifecycleRegistryOwner, HomeFragment.OnFragmentInteractionListener, {
    private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);

    @Override
    public LifecycleRegistry getLifecycle() {
        return mRegistry;
    }

    public static final String TAB_HOME = "TAB_HOME";
    public static final String TAB_COLLECTION = "TAB_COLLECTION";
    public static final String TAB_NOTICE = "TAB_NOTICE";

    public static final String TAB_HOME = "TAB_HOME";
    public static final String TAB_COLLECTION = "TAB_COLLECTION";
    public static final String TAB_NOTICE = "TAB_NOTICE";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    // something...
}

LifecycleRegistryOwnerをimplementsしてLifecycleRegistryのインスタンスをもたせます。これで、AppCompatActivityでも利用可能になります。
あとはViewModelProvidersを使えば、ViewModelのオブジェクトを管理できます。

Activityに付加したFragmentでViewModelを管理する場合は、以下のように実装します。

{project_folder}/HomeFragment.java
public class HomeFragment extends Fragment {
    public static final String TAG = "HomeFragment";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        homeModel = ViewModelProviders.of(getActivity()).get(HomeModel.class);
    }

    // something...
}

これにより、画面の回転などでonCreate()の再呼び出しをしてもViewModelを継承したモデルから値を取得することが可能になります。

結論

android-architecture-componentsはsupport libraryと同様、デファクトのライブラリになりそうな気がします。

この他にも、通知やDBでも活躍できそうなので、色々と試していきたいですね。

PICK UP

運営サイト


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2017年5月20日土曜日

[git] squashでコミットをまとめる

  • 公開日:2016年05月20日

記事概要

gitのsquashを使ってコミットをまとめる時のやり方。ターミナルコマンドを使います。

環境

  • git version 2.6.4

やりたいタスク

直近4つのコミットを一つにまとめます。
対象は色々な修正を加えたsample.txtです。

terminal

// コマンド
git log --oneline

a108a12 sample/feature completed.
ba18359 deleted comment.
a7711e0 updasted comment.
adf6be6 added comment.
2ca3f88 first commit

直近a108a12からadf6be6までの4つのコミットをまとめて、直近a108a12のコメントに変更します。
開発現場でよくあるパターンです。

順序

rebaseコマンドで直近の4つのコミットを選択します。

terminal

// コマンド
git rebase -i HEAD~4

pick adf6be6 added comment.
pick a7711e0 updasted comment.
pick ba18359 deleted comment.
pick a108a12 sample/feature completed.

# Rebase 2ca3f88..a108a12 onto 2ca3f88 (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

古いコミット順で表示されるので、注意してください。一番古いコミット以外をsに変更します。

terminal

pick adf6be6 added comment.
s a7711e0 updasted comment.
s ba18359 deleted comment.
s a108a12 sample/feature completed.

一番古いコミット以外をsに変更します。最初(一番古い)のコミットはsにしてはいけません。sを指定したコミットの内容が、前のコミットに統合(melt)されるイメージです。時系列が逆なので最初は理解しにくいですが、仕様なので慣れてください。
修正したら:wqで上書き保存します。

コミット内容が表示されます。

terminal

# This is a combination of 4 commits.
# The first commit's message is:
added comment.

# This is the 2nd commit message:

updasted comment.

# This is the 3rd commit message:

deleted comment.

# This is the 4th commit message:

sample/feature completed.

残したいコミットメッセージ以外を削除します。もちろんメッセージを変更しても問題ありません。

terminal

# This is a combination of 4 commits.
# The first commit's message is:

# This is the 2nd commit message:


# This is the 3rd commit message:


# This is the 4th commit message:

sample/feature completed.

変更したら:wqで上書き保存します。

terminal

Successfully rebased and updated refs/heads/master.

成功です。ログを確認します。

terminal

// コマンド
git log --oneline

4a709e3 sample/feature completed.
2ca3f88 first commit

綺麗にログがまとまりました。

ログの内容をすでにpull requestしている場合は、force pushすれば強制的に上書きできます。(他の人がファイルをいじってないことを確認しましょう)

まとめ

gitはとても便利なのですが、ググっても間違った情報が引っかかるケースが多いと思います。
周りの人に聞いたり、公式サイトを利用して正しく効率的なやり方を身につけてください。

PICK UP オススメ書籍

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2017年5月6日土曜日

【Unity5.6.0f3】error CS0234: The type or namespace name `CrossPlatformInput' does not exist in the namespace.

  • 公開日:2017年05月06日

記事概要

Unityの学習中に発生したエラーの解決メモ。

環境

  • macOS Sierra
  • Unity5.6.0f3

発生

Unityのチュートリアルでキャラクターを配置したらerror CS0234: The type or namespace name `CrossPlatformInput' does not exist in the namespaceが発生しました。

原因

エラーの通りCrossPlatformInputがインポートされていないためです。

修正方法

AssetsにCrossPlatformInputを追加します。

fig1:CrossPlatformInputを追加

AssetsにCrossPlatformInputが追加されていることを確認します。

コンパイルが可能になり、動作が確認できるようになります。

fig3:play

動作が確認できました。

PICK UP オススメ書籍

運営サイト(railsで作成しています)


この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加

2017年5月5日金曜日

【Rails5.1.0】 Rails5.0.1からRails5.1.0にアップグレードする。

  • 公開日:2017年05月05日

記事概要

ようやくRails5.1.0がリリースされたのでアップグレードしました。まとめ記事です。

環境

  • centos6.5
  • Rails5.0.1 → Rails5.1.0
  • ruby2.3.0
  • rbenv
  • unicorn
  • whenever

はじめに

Rails5.1.0は、Rails5.0.x系と比較すると変更点が多いです。以前の記事で5.0.x系との差異を記載しているのでそちらを参考にしてください。

移行用の作業branchの作成

以前の記事で記載しているように、2ヶ月ほど前にRails5.1.0 beta1で、移行テスト済みなので一気に作業をやっていきます。
Railsのバージョンアップをする場合は、betaの段階で1度テストをしておくことをお勧めします。

gitでrails5.1.0移行用の作業ブランチを作成します。

terminal

cd {project_folder}
git branch feature/rails5.1.0

checkoutでブランチを切り替えます。

terminal

git checkout feature/rails5.1.0

準備完了です。

Gemfile修正

まずGemfileを修正します。

{project_folder}/Gemfile

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '5.0.1'

↓

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '5.1.0'

gem 'rails', '5.1.0'に修正し、updateします。

terminal

// update
bundle update 

bundle updateは、全ての依存関係をインストール・ダウンロードし直すことができます。

Bundle updated!が表示されれば成功です。5.0.1に対応してあれば、bundle updateはひっかからないはずです。

Upgrade 設定ファイル

Gemファイルの導入が完了したら、rails app:updateで設定ファイルを更新します。

terminal

bundle exec rails app:update

ファイル更新の有無を聞かれるので、更新が必要なファイルのみ変更します。
私の環境では以下のようにしました。

  • config/routes.rb → 更新しない
  • config/application.rb → 更新しない
  • config/secrets.yml → 更新する
  • config/cable.yml → 更新する
  • config/puma.rb → 更新する
  • config/environments/development.rb → 更新する
  • config/environments/production.rb → 更新する
  • config/environments/test.rb → 更新する
  • config/initializers/assets.rb → 更新する
  • config/initializers/new_framework_defaults.rb → 更新しない
  • bin/setup → 更新しない
  • bin/update → 更新しない

更新後は、git diffでファイルを比較して必要な設定だけ元に戻します。

config/environments/production.rb

Rails5.1.0では、config.read_encrypted_secrets = trueが追加されました。
暗号の管理方法が変わりました。

既存のsecrets.ymlでも動くので、Encrypted secretsの導入は少し待ってからの方が良いかもしれません。これだと管理が煩雑になって、まだデメリットの方が多い気がします。

Rails5.1.0 Encrypted secretsの対応

暗号の管理方法が変更されたので対応します。terminalを開きます。

terminal
bin/rails secrets:setup

config/secrets.yml.key
append  .gitignore
create  config/secrets.yml.enc

You can edit encrypted secrets with `bin/rails secrets:edit`.
Add this to your config/environments/production.rb:
config.read_encrypted_secrets = true

これだけです。パスワードの入ったsecrets.yml.keyファイルは、.gitignoreに自動で追加されます。 config/secrets.yml.encはgitで管理可能です。pushしてもOKです。

また、config/environments/production.rbにconfig.read_encrypted_secrets = trueが追加されていることも確認してください。
あとは、本番でconfig/secrets.yml.keyのuploadを忘れないようにしましょう。開発環境で有効にする必要はないとは思いますが、本番と同じにしたい人はconfig.read_encrypted_secrets = trueを追加しても良いと思います。

secrets.yml.keyは紛失しないように忘れずに別管理にします。(この辺がセキュリティのためとはいえ納得いかないとこですね。面倒くさい。)

Rails5.1.0 rails-ujs対応

rails-ujsを導入すれば、jquery_ujsが不要になります。jqueryの処理に依存している人は、jqueryの処理も書き換える必要があります。時間をとって乗り換えましょう。

config/environments/development.rb
# Use jquery as the JavaScript library
#gem 'jquery-rails'

gem 'rails-ujs'

インストールします。

terminal

// update
bundle update 

Installing rails-ujs 0.1.0

インストールしたら、application.jsを修正します。

assets/javascript/application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .

↓

//= require rails-ujs
//= require turbolinks
//= require_tree .

せっかく書き換えるなら、今だとTypeScriptに変更するのがいいのではないでしょうか。

Rails5.1.0起動

アプリを起動します。

terminal

rbenv exec bundle exec rails s -b 0.0.0.0
=> Booting WEBrick
=> Rails 5.1.0.beta1 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
[2017-03-20 14:24:05] INFO  WEBrick 1.3.1
[2017-03-20 14:24:05] INFO  ruby 2.3.0 (2015-12-25) [x86_64-linux]
[2017-03-20 14:24:05] INFO  WEBrick::HTTPServer#start: pid=10639 port=3000

コンソールにRails 5.1.0 applicationが表示され、画面が表示されれば成功です。

だいたいここまでで1時間くらいです。あとは、テストコードを実行してデグレを確認します。

terminal

bundle exec rspec

Finished in 1 minute 58.72 seconds (files took 7.84 seconds to load)
230 examples, 0 failures, 14 pending

問題ありませんでした。DEPRECATION WARNINGで修正可能なエラーは今のうちに修正します。Rails5.2.0の対応も済ませてしまいましょう。

capistrano

capistranoも修正します。config/secrets.yml.keyにもSymbolic linkが作成されるようにします。

config/deploy.rb

set :linked_files, %w{config/database.yml}

↓

# Default value for :linked_files is []
set :linked_files, %w{config/database.yml config/secrets.yml.key}

ググるとupload処理をconfig/deploy.rbに記述しているケースをちょくちょく見かけます。この場合、ファイルがないとdeploy:checkが通らなくなるので、やらない方が良いと思います。ファイルは直接アップロードしておくのがcapistranoの仕様になってます。フォルダは自動生成してくれますが、ファイルはしてくれません。

リリース

capistrano3を使っていつも通りリリースすればOKです。少し時間がかかります。一通りの動作確認はしておきましょう。

まとめ

Rails5.0.1からRails5.1.0のアップデートは、それなりに手間がかかると思います。特にフロントエンドが複雑なWEBアプリだと苦戦するかもしれません。
私は既にRails5.1.0にアップロードしましたが、Fix版が出て安定してからでも良いかなと思いました。

あとはそろそろ、Ruby2.4.0への更新とリファクタリングも済ませてしまうと良いでしょう。

あとはdockerがいい感じに枯れてきたので、そろそろ本番で使っても良いかもしれないですね。

以上です。

PICK UP オススメ書籍

運営サイト(railsで作成しています)


関連記事

この記事がお役にたちましたらシェアをお願いします

このエントリーをはてなブックマークに追加
Related Posts Plugin for WordPress, Blogger...