WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Log.d("display", "w:" + display.getWidth());
Log.d("display", "h:" + display.getHeight());
w:320 h:480
onCreate 時には、まだレイアウトの初期化が行われないため View の width/height からは 0 が返ってきます。調べてみると WindowManager を経由して取得した Display クラスから onCreate 時に取得できました。
こちらは View の onSizeChanged イベントから取得する方法です。
Ruby 1.9 上の Sequel で sqlite3 からマルチバイト文字列を含んだレコードを取得し to_json しようとすると
Encoding::UndefinedConversionError: "\xE2" from ASCII-8BIT to UTF-8
というエラーが出力されます。
String#force_encoding で、いちいち utf-8 しないといけないのかと思ったところ、きちんと Sequel の plugin にエンコーディングを変換できるものが提供されていました。
class User < Sequel::Model plugin :force_encoding, 'utf-8' end
カラム名を created_at, updated_at にしておくと、 save メソッドを呼び出したときに自動的に作成、更新時間を更新してくれるみたいです。カラム型は timestamp で確認しています。
さらに追加時にも更新時間を入れたい場合には timestamps プラグインを利用して、オプションを渡してあげるとよいです。
DB = Sequel.connect("sqlite://test.db")
class User < Sequel::Model
plugin :timestamps, :update_on_create => true
end
DB.transaction do
User.new(:name => 'aaa').save
User.new(:name => 'bbb').save
end
既存システムで、すでに別のカラム名が使われている場合には下のオプションを渡してあげると変更できます。
plugin :timestamps, :create => 'created_on', :update => 'updated_on'
Module: Sequel::Plugins::Timestamps [Sequel: The Database Toolkit for Ruby]
モデルすべてに適用したい場合は Sequel::Model で定義してあげるとよいみたいです。
class Sequel::Model plugin :timestamps, :update_on_create => true, :create => 'created_on', :update => 'updated_on' end class User < Sequel::Model; end
まずサーバーセッションを有効にするには起動ファイルである config.ru で use します。
use Rack::Session::Pool
引数にオプションをつけてセッションの有効期限を変えたりします。
あとはクライアントから呼び出されたアクション(コントローラー)で session_options に :drop オプションを渡してあげると削除されます。
get '/' do (session[:count] = (session[:count] || 0) + 1).to_s end get '/clear' do request.session_options[:drop] = true end
http://localhost:4567/ をたたくとリクエストした数だけカウント数が画面に表示され、 /clear を叩いてから再度 / を叩くと、セッション ID が新たに割り当てられ 1 に戻ります。 :renew を渡すと新たなセッション ID を割り振りつつ、前の情報をマージしてくれます。
session.clear は単純に中身の Hash オブジェクトをクリアするだけで、セッション ID はそのままでした。
Ruby にある軽量 ORM Sequel を簡単に触ったことはあるのですが、マイグレーションもできるということで試してみました。
$ sudo gem install rake $ sudo gem install sequel $ sudo gem install sqlite3-ruby
+app_root/ +Rakefile +db/ +migrate/ +001_migrate.rb +002_migrate.rb
#!/usr/bin/env ruby
Class.new(Sequel::Migration) do
def up
create_table :users do
primary_key :id
varchar :name, :size => 32, :unique => true
varchar :salt, :size => 32, :null => false
varchar :hashed_password, :size => 64, :null => false
varchar :mail_address, :size => 128, :null => false
timestamp :created_at
timestamp :updated_at
end
add_index :users, :name
end
def down
drop_index :users, :name
drop_table :users
end
end
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
Class.new(Sequel::Migration) do
def up
create_table :tags do
primary_key :id
varchar :name, :size => 32
end
from(:tags).insert(:name => 'あとでやる')
from(:tags).insert(:name => '明日から本気出す')
end
def down
drop_table :tags
end
end
クラスを匿名で生成していますが、意味づけを行う場合は名前をきちんとつけたほうが良いかもしれません。
Rake は引数を渡すと ENV 変数に書き込まれるので、これでバージョンを指定できます。
#!/usr/bin/env ruby
require 'rubygems'
require 'rake'
require 'sequel'
require 'sequel/extensions/migration'
namespace :db do
desc "migrate database"
task :migrate do
target = target.to_i if (target = ENV['target'])
current = current.to_i if (current = ENV['current'])
DB = Sequel.connect("sqlite://db/app.sqlite3")
Sequel::Migrator.apply(DB, './db/migrate', target, current)
end
end
最新版 (version 2) にする
$ rake db:migrate
バージョンを 1 に戻す
$ rake db:migrate target=3
わざわざ rake しなくても、コマンドから migrate できます。 -m でマイグレーションファイルを格納しているディレクトリを指定、 -M でバージョンを指定します。
$ sequel -m ./db/migrate sqlite://db/keyself.db -M 1
マイグレーションとは関係ありませんが、 model をつくる場合は最低限なものであればこれだけです。
class User < Sequel::Model; end
users テーブルと関連づけられ、様々な操作が行えます。手軽にデータベースを操作したい場合に使っていきたいと思う ORM です。
Android で画面操作を行っているときに電話がかかってくると、処理が停止されてしまいます。しかし停止させず処理を継続させたい場合にはサービスという概念が用意されており、これを利用することで処理をバックエンドで続けてくれるとのこと。
実装方法はいくつかあるのですが、今回は AIDL ファイルに Java インターフェースを定義して、コールバックを受け取れるバインダという種類を選択してみました。なお AIDL ファイルに記述したインターフェースは ADT によって、インターフェースを実装したクラスが自動的に生成されます。
まず AIDL ファイルに定義するインターフェースの引数、戻り値に指定できるものとして以下の制約があるとのことです。
新しく Parcelable インターフェースというものが出てきたのですが、すごく適当にいうと Serializable の Android 用みたいなものです。 Java の Serializable は冗長なので、 Android ではリモート通信間に使うものには Parcelable インターフェースを実装するルールのようです。
で、今回 Parcelable インターフェースを実装した ValueObject を渡そうとしたところ意外にハマってしまったのでメモしておきます。
example.dto.Hoge クラスが Parcelable インタフェースを実装しているものとします。(インターフェース実装は省略します)
Hoge クラスと同じ example.dto パッケージに Hoge.aidl ファイルを作成します。
package example.dto; parcelable Hoge;
ここでは Hoge クラスが parcelable であることを宣言します。
続いてコールバックを受け取るリスナを example.service パッケージに定義します。
package example.service;
import example.dto.Hoge;
interface HogeCallbackListener {
void receive(in Hoge hoge);
}
ここでは先ほど Hoge.aidl で定義した Hoge クラスを import し、インターフェースの引数に in を指定しました。なお public をつけるとおこられます。これで利用するための準備は整いました。
この後に AndroidManifest ファイルに Service を定義したり、 Activity や Service にコードを記述したりと面倒な作業が待っています。
http://developer.android.com/intl/ja/guide/developing/tools/aidl.html