ListViewの中にCheckBoxを入れるとsetOnItemClickListenerが動作しない

Android

ListViewの中にCheckBoxを入れるとsetOnItemClickListenerが動作しない サンプルコード有り

マニアックな話かもしれませんが、下記のスクショのように、リストビューの中に、チェックボックスを入れたい場合です。
普通にやると、チェックボックスは動作しますが、リストのタップしたところを判定して動作させるというのが動きません。

list_check.png

 android:descendantFocusability="blocksDescendants"

を利用するとリストをタップできるようになります。
ここでは、inspections_list.xml内に利用しています。使うところがなんかわかりにくいですよね!

    @Override
    public void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listplaceholder_inspections);
 
        CheckBox checkBox = (CheckBox) findViewById(R.id.checkbox);
 
        try {
 
            mylist = new ArrayList<HashMap<String, String>>();
 
            HashMap<String, String> map1 = new HashMap<String, String>();
            map1.put("item_name", "燃料");
            map1.put("detail", "量・漏れ");
            mylist.add(map1);
 
            HashMap<String, String> map2 = new HashMap<String, String>();
            map2.put("item_name", "エンジン");
            map2.put("detail", "かかり具合・異音");
            mylist.add(map2);
 
            ListAdapter adapter = new SimpleAdapter(this, mylist,
                    R.layout.inspections_list, new String[] {
                            "item_name", "detail", "problem_comment"
                    },
                    new int[] {
                            R.id.item_name, R.id.detail, R.id.problem_comment
                    });
            setListAdapter(adapter);
            final ListView lv = getListView();
            lv.setTextFilterEnabled(true);
            lv.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent,
                        View view, int position, long id) {
                    //リストをクリックした時の処理
                    int item_id = position;
                }
            });
 
        } catch (Exception e) { 
 
             Log.e(TAG, "Error parsing data " + e.toString());
 
        }
    }

inspections_list.xmlの内容

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="7dp" 
    android:descendantFocusability="blocksDescendants">
 
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dip"
        android:orientation="horizontal" >
 
        <TextView
            android:id="@+id/item_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/green1"
            android:textSize="18sp" />
    </LinearLayout>
 
    <TableLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
 
        <TableRow>
 
            <TextView
                android:id="@+id/detail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:padding="1dp"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textSize="18sp" />
            <CheckBox
                android:id="@+id/checkbox"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />
        </TableRow>
 
        <TableRow>
 
            <TextView
                android:id="@+id/problem_comment"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_span="2"
                android:padding="1dp"
                android:text="@string/problem"
                android:textColor="@color/orange4"
                android:textSize="13sp" />
        </TableRow>
    </TableLayout>
 
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="1dp"
        android:text="@string/problem"
        android:textColor="@color/orange4"
        android:textSize="13sp" />
 
 </LinearLayout>

listplaceholder_inspections.xmlの内容

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <ListView
        android:id="@id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:divider="#cccccc"
        android:dividerHeight="1px" 
        android:focusable="false"
        />
 
    <TextView
        android:id="@id/android:empty"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/fetching" />
 
 
 </LinearLayout>

Linux初心者がSupervisorを導入する

Linuxサーバー

CentOS 7

今回、RatchetというWebソケットのプログラムを動作させたいという目的のために、Supervisorを導入します。
(経緯はここ→Ratchetを利用してPHPでWebソケット 2 デプロイ編)

Supervisorとは、プロセスを管理してくれるツールです。
プロセスが死んでいたりしたら、復活もしてくれるようです。

Supervisor公式サイト

さて、今回はRatchetを導入することが目的なので、下記のRatchetのサイトの通りにやります。
http://socketo.me/docs/deploy

 yum install supervisor

でさくっとSupervisorをインストールします。

コンフィグファイルは、次のようにして、/etc/supervisor.conf として保存します。

 [unix_http_server]
 file = /tmp/supervisor.sock
 
 [supervisord]
 logfile          = /var/log/supervisord.log
 logfile_maxbytes = 50MB
 logfile_backups  = 10
 loglevel         = info
 pidfile          = /tmp/supervisord.pid
 nodaemon         = false
 minfds           = 1024
 minprocs         = 200
 
 [rpcinterface:supervisor]
 supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
 
 [supervisorctl]
 serverurl = unix:///tmp/supervisor.sock
 
 [program:ratchet]
 command                 = bash -c "ulimit -n 10000; cd /var/www/ratchet; php bin/push-server.php"
 process_name            = Ratchet
 numprocs                = 1
 autostart               = true
 autorestart             = true
 user                    = user1
 stdout_logfile          = /var/log/supervisor_info.log
 stdout_logfile_maxbytes = 1MB
 stderr_logfile          = /var/log/supervisor_error.log
 stderr_logfile_maxbytes = 1MB
  [program:ratchet]

にあるところが、ratchetを起動してくれたりするところですが、こうやって設定ファイルにかけるとスッキリしますよね!⊂(^-^)⊃

一点注意点は、user の部分は、rootにしていると

 CRIT Supervisor running as root (no user in config file)

上記のエラーが出るので、ユーザーを指定する必要があります。ここではuser1を指定しています。

んでもって、ドン!

 $ sudo supervisord -c supervisor.conf

これで動作しますが、設定ファイルなどを書き換えてリスタートしたいときは、そのまま上記のコマンドを実行すると

 Starting supervisor: Error: Another program is already 
 listening on a port that one of our HTTP servers is configured to use.  

というエラーが出ますので、プロセスをkillしてまた立ち上げます。
(この辺りはこのやり方であっているかどうかわかりません。)

 ps -ef | grep supervisord

とやり、出てきたプロセスの番号を確認します。

 root     17333     1  0 10:28 ?        00:00:01 /usr/bin/python /bin/supervisord -c /etc/supervisor.conf
 root     18591 18528  0 11:54 pts/10   00:00:00 grep --color=auto supervisord

上記なら、17333をkill します。

 kill -s SIGTERM 17333  

これで、動作しました![smile]

Linux初心者がHAProxyを導入する

Linuxサーバー
CentOS 7

えー、まず、私はあまりLinuxサーバーのことを中途半端にしか理解していません…。時々しか触らないからです…。
しかし、今回サーバーをやってくれる人が忙しいので、RatchetというWebsocketのプログラムを動作させるために、やむなくやりました。

Ratchetを利用してPHPでWebソケット 2 デプロイ編

Ratchetのデプロイのページに書いてあるやり方でまずやります。

http://socketo.me/docs/deploy

途中試行錯誤多いのですが、記録として残しておきます。

まず、HAProxyの公式サイトがこれっ!
http://www.haproxy.org/

うわー、わかりにくっ。。。
しかし、とりあえず、現時点(2016/12/20)での最新の安定版が1.7.1なので、次の通りにやります。

 wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.1.tar.gz
 tar -zxvf haproxy-1.7.1.tar.gz
 cd haproxy-1.7.1.tar.gz
 make install

で、この

 make

で、

 make: no rule to make target

というエラーが出て、先に進めません…。

早速涙目。。。
昔はちゃちゃっとmakeでできた気がするのに…。
サーバー担当者に聞いたところ
「yumでやりなよ!!なんでmakeとか使うの!!(怒)&angry;」
と言われました。

しかし、yumでは1.5.18しか入れられないのです…。
目的のことができるでしょうか?不安が立ち込めますね!!

とりあえず、

 yum install haproxy

でhaproxyをインスコします。
はぁー 簡単! yum やっぱ便利!!

設定ファイルを次のように作って、/etc/haproxy.cfg に保存します。

 global
 	log	127.0.0.1	local0
 	maxconn	10000
 	user	haproxy
 	group	haproxy
 	daemon
 
 defaults
 	mode			http
 	log			global
 	option			httplog
 	retries			3
 	backlog			10000
 	timeout	client		30s
 	timeout	connect		30s
 	timeout	server		30s
 	timeout	tunnel		3600s
 	timeout	http-keep-alive	1s
 	timeout	http-request	15s
 
 frontend public
 	bind		*:80
 	acl		is_websocket hdr(Upgrade) -i WebSocket
 	use_backend	ws if is_websocket #is_websocket_server
 	default_backend	www
 
 backend ws
 	server	ws1	127.0.0.1:1337
 
 backend www
 	timeout	server	30s
 	server	www1	127.0.0.1:1338

んで、できたら、haproxyを動かすぞ!と次のをドン

 $ sudo haproxy -f /etc/haproxy.cfg -p /var/run/haproxy.pid -D

すると、次のエラーが出てしまいます。

 Haproxy cant bind [0.0.0.0:80] 

ほうほう…
80番ポートはApacheが使っているから、ってことね。
httpd.confの
Listen 80

Listen 1338
にします。

ふたたび ドン!

 $ sudo haproxy -f /etc/haproxy.cfg -p /var/run/haproxy.pid -D

これで、なんとか動作しました!!!

ログの取り方などは、下記に親切に書かれています。
http://qiita.com/saka1_p/items/3634ba70f9ecd74b0860

ちなみに、HAProxyさんのブログのWebソケットの説明がわかりやすかったので、載せておきます。
http://blog.haproxy.com/2012/11/07/websockets-load-balancing-with-haproxy/

Linuxサーバー apache+rsyslogでリモートログをとる

Linuxサーバー

CentOS 5.x系のインストール・設定例です。
リモートログサーバーのIPアドレスは192.168.0.2とします。

apacheでlocal6にloggerを使ってsyslog出力し、rsyslogでログサーバーにログをTCP出力します。

インストール

リポジトリepelからrsyslog3.22をインストール、初期設定します。

 yum install rsyslog --enablerepo=epel
 vim /etc/sysconfig/rsyslog
 SYSLOGD_OPTIONS="-c3"
 service syslog stop
 service rsyslog start
 chkconfig syslog off
 chkconfig rsyslog on

Webサーバー設定例

/etc/httpd/conf/httpd.conf

ログの出力のしかたをloggerを使うように変更します。

 CustomLog "|/usr/bin/logger -p local6.info -t http-access" combined 
 ErrorLog "|/usr/bin/logger -p local6.info -t http-error"

/etc/rsyslog.conf

local6へのメッセージは/var/log/messagesに出力しないようにします。
local6へのメッセージはログサーバーに送信します

 # Use traditional timestamp format
 $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
 
 # Provides kernel logging support (previously done by rklogd)
 $ModLoad imklog
 # Provides support for local system logging (e.g. via logger command)
 $ModLoad imuxsock
 
 # Log all kernel messages to the console.
 # Logging much else clutters up the screen.
 #kern.*                                                 /dev/console
 
 # Log anything (except mail) of level info or higher.
 # Don't log private authentication messages!
 *.info;mail.none;authpriv.none;cron.none;local6.none;      /var/log/messages
 
 # The authpriv file has restricted access.
 authpriv.*                                              /var/log/secure
 
 # Log all the mail messages in one place.
 mail.*                                                  -/var/log/maillog
 
 # Log cron stuff
 cron.*                                                  /var/log/cron 
 
 # Everybody gets emergency messages
 *.emerg                                                 *
 
 # Save news errors of level crit and higher in a special file.
 uucp,news.crit                                          /var/log/spooler
 
 # Save boot messages also to boot.log
 local7.*                                                /var/log/boot.log
 
 # httpd logs
 local6.*                                             @@192.168.0.2

ログサーバー設定例

local6への出力を/var/log/messagesに出力しないようにします。
apacheログは/var/log/rsyslog/httpd/以下に出力します

/etc/rsyslog.conf

 # Use traditional timestamp format
 $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
 
 # Provides kernel logging support (previously done by rklogd)
 $ModLoad imklog
 # Provides support for local system logging (e.g. via logger command)
 $ModLoad imuxsock
 
 # Log all kernel messages to the console.
 # Logging much else clutters up the screen.
 #kern.*                                                 /dev/console
 
 # Log anything (except mail) of level info or higher.
 # Don't log private authentication messages!
 *.info;mail.none;authpriv.none;cron.none;local6.none                /var/log/messages
 
 # The authpriv file has restricted access.
 authpriv.*                                              /var/log/secure
 
 # Log all the mail messages in one place.
 mail.*                                                  -/var/log/maillog
 
 
 # Log cron stuff
 cron.*                                                  /var/log/cron
 
 # Everybody gets emergency messages
 *.emerg                                                 *
 
 # Save news errors of level crit and higher in a special file.
 uucp,news.crit                                          /var/log/spooler
 
 # Save boot messages also to boot.log
 local7.*                                                /var/log/boot.log
 
 
 $ModLoad imtcp
 $InputTCPServerRun 514
 
 $template access_log, "%msg:2:$%\n"
 $template error_log, "%fromhost-ip%%msg%\n"
 
 $template access_log_file, "/var/log/rsyslog/httpd/%hostname%-%fromhost-ip%-access_log.%$NOW%"
 $template error_log_file, "/var/log/rsyslog/httpd/%hostname%-%fromhost-ip%-error_log.%$NOW%"
 
 if $syslogfacility-text == 'local6'  and $syslogtag == 'http-access:' then -?access_log_file;access_log
 if $syslogfacility-text == 'local6' and $syslogtag == 'http-error:' then ?error_log_file;error_log

なお、ログファイルパスの前に「-」を付けると非同期、付けないと同期動作になります

LinuxにZend Debuggerをインストールする

PHP

下記環境で動作確認しています。
Fedora Core 8/Apache 2.2.9/PHP 5.2.6

Zend Debuggerの取得

  1. 下記サイトからZend Debuggerをダウンロードします。
  2.  http://www.zend.com/en/downloads/
    
    • ユーザー登録、ログインが必要です。
    1. PHPのバージョンにあったライブラリを下記パスに配置します。
    2.  /usr/lib/php/modules/ZendDebugger.so
      

      phpの設定

      1. /etc/php.iniの設定を変更します。
      2.  ; this is to see output while debugging
         implicit_flush = On
        
        • これでデバッグ中のHTML出力を随時確認できるようになります。
        1. /etc/php.d/zend_debugger.iniというファイルを作成し、以下のように記述します。
        2.  ;enable zend debugger
           zend_extension="/usr/lib/php/modules/ZendDebugger.so
           zend_debugger.allow_hosts=127.0.0.1/32, 192.168.1.0/24
           zend_debugger.expose_remotely=always
          
          • Red Hat系のphpはスレッドセーフではないようで、ライブラリのパスはzend_extension_tsではなく、zend_extensionで指定します。
          1. apacheを再起動して変更内容を反映します。

          参考サイト

          http://www.thierryb.net/pdtwiki/index.php?title=Using_PDT_:_Installation_:_Installing_the_Zend_Debugger#Installing_Zend_Debugger_server