goo blog サービス終了のお知らせ 

marunomaruno-memo

marunomaruno-memo

[Android] 標準出力 - あて先に画面を追加する

2011年12月22日 | Android
標準出力 - あて先に画面を追加する
================================================================================

■ 標準出力のあて先に画面を追加する

標準出力(標準エラー出力も含む)のあて先は、LogCat。
たとえば、
    System.out.print("test");
としたときは、つぎと同じことになる。
    Log.i("System.out", "test");

このあて先に、画面(TextView)も追加する。

これには、PrintStream クラスを継承したクラスを作って、System.setOut() メソッドで、
標準出力オブジェクトを置き換えてやればよい。

画面でスクロールさせるために、res/layout/main.xml に ScrollView を設定してあげる
必要がある。


◆ アクティビティのクラス。

□ SystemOut01Activity.java
---
package jp.marunomaruno.android.sample;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

/**
 * @author marunomaruno
 * @version 1.0, 2011-12-14
 * @since 1.0
 */
public class SystemOut01Activity extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // 標準出力を置き換え(標準出力(LogCat)+テキストビュー)
        TextView sysout = (TextView) findViewById(R.id.sysout);
        System.setOut(new TextViewPrintStream(System.out, sysout));    // (1)
        System.setErr(new TextViewPrintStream(System.err, sysout));    // (2)
        
        // 出力する
        for (int i = -50; i < 50; i++) {
            System.out.printf("%3d|", i);    // (3)
            for (int j = 0; j < Math.abs(i); j++) {
                System.out.print("*");
            }
            System.out.println();
        }

        // 例外をスローする
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            e.printStackTrace();    // (4)
        }
    }
}
---


(1)(2) 標準出力、標準エラー出力の置き換え

    System.setOut(new TextViewPrintStream(System.out, sysout));    // (1)
    System.setErr(new TextViewPrintStream(System.err, sysout));    // (2)

こうすることで、標準出力、標準エラー出力のどちらも指定した TextView で出力させる
ことができる。


(3) 標準出力を使う

    System.out.printf("%3d|", i);    // (3)


(4) 標準エラー出力を使う

    e.printStackTrace();    // (4)


◆ 標準出力をテキストビューにも出力させるクラス。

PrintStream クラスを継承したクラスを作って、print(String) メソッドをオーバーライ
ドすればよい。


□ TextViewPrintStream.java
---
package jp.marunomaruno.android.sample;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

import android.view.View;
import android.widget.ScrollView;
import android.widget.TextView;

/**
 * 標準入出力を Log と テキストビューに出力させるようにするクラス.
 * 指定されたテキストビューは、スクロールビューに囲まれている必要がある。
 * @author marunomaruno
 * @version 1.0, 2011-12-14
 * @since 1.0
 */
public class TextViewPrintStream extends PrintStream { // (1)

    private TextView view; // (2)
    private Runnable scrollDown = new ScrollDown();    // (3)
    
    public TextViewPrintStream(File file, String csn, TextView view)
            throws FileNotFoundException, UnsupportedEncodingException { // (4)
        super(file, csn);
        this.view = view;
        ((View) view.getParent()).post(scrollDown);    // (5)
    }

    public TextViewPrintStream(File file, TextView view)
            throws FileNotFoundException {    // (4)
        super(file);
        this.view = view;
        ((View) view.getParent()).post(scrollDown);    // (5)
    }

    public TextViewPrintStream(OutputStream out, boolean autoFlush, String enc,
            TextView view) throws UnsupportedEncodingException {    // (4)
        super(out, autoFlush, enc);
        this.view = view;
        ((View) view.getParent()).post(scrollDown);    // (5)
    }

    public TextViewPrintStream(OutputStream out, boolean autoFlush,
            TextView view) {    // (4)
        super(out, autoFlush);
        this.view = view;
        ((View) view.getParent()).post(scrollDown);    // (5)
    }

    public TextViewPrintStream(OutputStream out, TextView view) {    // (4)
        super(out);
        this.view = view;
        ((View) view.getParent()).post(scrollDown);    // (5)
    }

    public TextViewPrintStream(String fileName, String csn, TextView view)
            throws FileNotFoundException, UnsupportedEncodingException { // (4)
        super(fileName, csn);
        this.view = view;
        ((View) view.getParent()).post(scrollDown);    // (5)
    }

    public TextViewPrintStream(String fileName, TextView view)
            throws FileNotFoundException {    // (4)
        super(fileName);
        this.view = view;
        ((View) view.getParent()).post(scrollDown);    // (5)
    }

    @Override
    public synchronized void print(String str) { // (6)
        super.print(str);
        view.append(str); // (7)
    }

    /**
     * スクロールダウンさせるスレッドのクラス
     * @author marunomaruno
     */
    private class ScrollDown implements Runnable { // (8)
        public void run() {
            ((ScrollView) view.getParent()).fullScroll(View.FOCUS_DOWN); // (9)
        }
    }
}
---


(1) PrintStream クラスのサブクラスを作る

    public class TextViewPrintStream extends PrintStream { // (1)


(2) 出力先のオブジェクト

    private TextView view; // (2)

テキストビューに出力させるので、それを保持しておく。


(3) スクロールダウンさせるスレッドのオブジェクト

    private Runnable scrollDown = new ScrollDown();    // (3)

ScrollDown クラスは、(8)で作成するプライベートな内部クラス。


(4) コンストラクター

現行の PrintStream クラスのコンストラクターの引数の後ろに、出力先になる TextView
 を指定しておく。

    public TextViewPrintStream(File file, String csn, TextView view)
            throws FileNotFoundException, UnsupportedEncodingException { // (4)

    public TextViewPrintStream(File file, TextView view)
            throws FileNotFoundException {    // (4)

    public TextViewPrintStream(OutputStream out, boolean autoFlush, String enc,
            TextView view) throws UnsupportedEncodingException {    // (4)

    public TextViewPrintStream(OutputStream out, boolean autoFlush,
            TextView view) {    // (4)

    public TextViewPrintStream(OutputStream out, TextView view) {    // (4)

    public TextViewPrintStream(String fileName, String csn, TextView view)
            throws FileNotFoundException, UnsupportedEncodingException { // (4)

    public TextViewPrintStream(String fileName, TextView view)
            throws FileNotFoundException {    // (4)


(5) このテキストビューを囲むスクロールビュー・オブジェクトに対してつねに最下段を
指すように指定

    ((View) view.getParent()).post(scrollDown);    // (5)


(6) print メソッドのオーバーライド

    public synchronized void print(String str) { // (6)

このメソッドをオーバーライドすることで、自分の意図した PrintStream オブジェクト
になる。


(7) TextView に文字列を追加する

    view.append(str); // (7)


(8) スクロールさせるためのクラス

    private class ScrollDown implements Runnable { // (8)


(9) スクロールさせる

このテキストビューを囲むスクロールビュー・オブジェクトに対して、最下段を表示する
ように指定する。

    ((ScrollView) view.getParent()).fullScroll(View.FOCUS_DOWN); // (9)


□View クラスのどの位置にするかの定数
---
int     FOCUS_BACKWARD
int     FOCUS_DOWN
int     FOCUS_FORWARD
int     FOCUS_LEFT
int     FOCUS_RIGHT
int     FOCUS_UP
---


□ScrollView.fullScroll メソッド
---
public boolean fullScroll (int direction)
---
direction に、上記の定数のうち、FOCUS_DOWN または FOCUS_UP を指定する。


◆ レイアウト

□ res/layout/main.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" >

    <ScrollView
        android:id="@+id/sysoutScrollView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >    <!-- (1) -->

        <TextView
            android:id="@+id/sysout"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />    <!-- (2) -->
    </ScrollView>
</LinearLayout>
---

(1) スクロールビュー

(2) 標準出力のあて先のテキストビュー



◆ 文字列の定数

□ res/values/strings.xml
---
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">SystemOut01</string>
</resources>
---



最新の画像もっと見る

コメントを投稿