Androidの学習をはじめて13日くらいの人の問題集

Android

前回はファイルに対してテキストの書き込みを行ったが、オブジェクトを直接書き込むこともできる。今回はまずその方法を学ぼう。

●ステップ1
ファイルに書き込みたいクラスにSerializableインターフェイスを実装する。

import java.io.Serializable;
public class Word implements Serializable {
 
    private String word;
    private String body;
 
    public Word(String word, String body) {
        this.word = word;
        this.body = body;
    }
 
    @Override
    public String toString() {
        return "word:" + word + " body:" + body;
    }
     
}

●ステップ2
読み込みはfisをObjectInputStreamで包み、readObject()
書き込みはfosをObjectOutputStreamで包み,writeObject(Object)
詳しくは以下のソースコードを参照せよ。
以下のソースコードではWordクラスのインスタンスをファイルに書き込み、その書き込まれたファイルから復元する手順を示している。

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        ObjectInputStream ois=null;
        ObjectOutputStream oos=null;
        try {
            //書き込みストリームにファイルを指定
            FileOutputStream fos=openFileOutput("data.dat",MODE_PRIVATE);
            //シリアライズ
            oos= new ObjectOutputStream(fos);
            //Wordインスタンスを書き込み
            oos.writeObject(new Word("word1","body1"));
 
            //読み込みストリームにファイルを指定
            FileInputStream fis=openFileInput("data.dat");
            //デシリアライズ
            ois=new ObjectInputStream(fis);
            //readObjectはオブジェクト型なのでダウンキャスト
            Word w=(Word)ois.readObject();
            //トースト表示
            Toast.makeText(this,w.toString(),Toast.LENGTH_SHORT).show();
 
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
            try{
                if(ois != null){ois.close();}
                if(oos != null){oos.close();}
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

オブジェクトのファイルへ書き込み方法がわかったところで前回のお題をListを直接ファイルに書く方法で実現してみよう。StringクラスもArrayListクラスもSerializableインターフェイスを実装しているので特別な処理をせずに上記の方法で読み書きできる。

Q1
登録されているデータ(List)をファイルに書き込み、次回起動時に復元させよ。
なお、今回はObjectOutputStreamクラスとObjectInputStreamクラスを使ってオブジェクトを直接ファイルに記録すること。
書き込み処理は
アプリがバックグランドにまわる際のonPauseをオーバーライドしてそこに書くとよい。

[実行例]

スタート画面
リストアイテムを登録するフォームとボタンがある。

フォームに入力し登録ボタンを押すと・・・

フォーム下部にあるリストビューに表示される。

いくつか登録する。

リストアイテム長押しでアイテムを削除できる。
下図はitem2を削除した。

バックボタンを押してアプリを終了する。

アプリ一覧からアプリを再起動する。

データが復元されていることが確認できる。

●activity_main.xml

01<?xml version="1.0" encoding="utf-8"?>
02<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
03    xmlns:app="http://schemas.android.com/apk/res-auto"
04    android:layout_width="match_parent"
05    android:layout_height="match_parent"
06    >
07 
08    <ListView
09        android:id="@+id/lv"
10        android:layout_width="0dp"
11        android:layout_height="0dp"
12        android:layout_marginLeft="8dp"
13        android:layout_marginRight="8dp"
14        android:layout_marginTop="8dp"
15        app:layout_constraintLeft_toLeftOf="parent"
16        app:layout_constraintRight_toRightOf="parent"
17        app:layout_constraintTop_toBottomOf="@+id/etItem"
18        app:layout_constraintBottom_toBottomOf="parent"
19        android:layout_marginBottom="8dp" />
20 
21    <TextView
22        android:id="@+id/textView"
23        android:layout_width="wrap_content"
24        android:layout_height="wrap_content"
25        android:text="item"
26        android:layout_marginLeft="8dp"
27        app:layout_constraintLeft_toLeftOf="parent"
28        app:layout_constraintBaseline_toBaselineOf="@+id/etItem" />
29 
30    <EditText
31        android:id="@+id/etItem"
32        android:layout_width="0dp"
33        android:layout_height="wrap_content"
34        android:layout_marginLeft="8dp"
35        android:layout_marginTop="8dp"
36        android:ems="10"
37        android:inputType="textPersonName"
38        app:layout_constraintLeft_toRightOf="@+id/textView"
39        app:layout_constraintTop_toTopOf="parent" />
40 
41    <Button
42        android:id="@+id/button"
43        android:layout_width="wrap_content"
44        android:layout_height="wrap_content"
45        android:layout_marginLeft="8dp"
46        android:layout_marginRight="8dp"
47        android:layout_marginTop="8dp"
48        android:onClick="btClick"
49        android:text="登録"
50        app:layout_constraintLeft_toRightOf="@+id/etItem"
51        app:layout_constraintRight_toRightOf="parent"
52        app:layout_constraintTop_toTopOf="parent" />
53</android.support.constraint.ConstraintLayout>

●MainActivity.java

001package com.example.mjpurin.filesaveobject;
002 
003import android.os.Bundle;
004import android.support.v7.app.AppCompatActivity;
005import android.view.View;
006import android.widget.AdapterView;
007import android.widget.ArrayAdapter;
008import android.widget.EditText;
009import android.widget.ListView;
010import android.widget.Toast;
011 
012import java.io.FileInputStream;
013import java.io.FileNotFoundException;
014import java.io.FileOutputStream;
015import java.io.IOException;
016import java.io.ObjectInputStream;
017import java.io.ObjectOutputStream;
018import java.util.ArrayList;
019import java.util.List;
020 
021public class MainActivity extends AppCompatActivity {
022    private ListView lv;
023    private EditText etItem;
024    private List<String> list=new ArrayList<>();
025    private ArrayAdapter<String> adapter;
026    @Override
027    protected void onCreate(Bundle savedInstanceState) {
028        super.onCreate(savedInstanceState);
029        setContentView(R.layout.activity_main);
030        //ファイル未作成の場合はnullが帰る
031        Object ret=readFile();
032        if(ret != null){
033            list=(List<String>)ret;
034        }
035        lv=(ListView)findViewById(R.id.lv);
036        etItem=(EditText)findViewById(R.id.etItem);
037        adapter=new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,list);
038        lv.setAdapter(adapter);
039        lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
040            @Override
041            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
042                list.remove(position);
043                adapter.notifyDataSetChanged();
044                Toast.makeText(MainActivity.this,"削除しました。",Toast.LENGTH_SHORT).show();
045                return true;
046            }
047        });
048 
049    }
050    public void btClick(View v){
051        String item=etItem.getText().toString();
052        list.add(item);
053        adapter.notifyDataSetChanged();
054        etItem.setText("");
055    }
056    //ファイルを読み込みオブジェクトを返却
057    private Object readFile() {
058        //返却するオブジェクト(初期値null)
059        Object ret=null;
060        //ObjectInputStream型の変数を宣言
061        ObjectInputStream ois=null;
062        try {
063            //fisを作成
064            FileInputStream fis=openFileInput("data.dat");
065            //fisをラッピングする形でObjectInputStreamインスタンスを作成
066            ois=new ObjectInputStream(fis);
067            //oisがreadObjectをするとオブジェクトを取得できる(Object型)
068            ret=ois.readObject();
069 
070        } catch (FileNotFoundException e) {
071            e.printStackTrace();
072        } catch (IOException e) {
073            e.printStackTrace();
074        } catch (ClassNotFoundException e) {
075            e.printStackTrace();
076        } finally{
077            if(ois !=null){
078                try {
079                    ois.close();
080                } catch (IOException e) {
081                    e.printStackTrace();
082                }
083            }
084        }
085        return ret;
086 
087    }
088 
089    @Override
090    protected void onPause() {
091        super.onPause();
092        //ObjectOutputStream型の変数を宣言
093        ObjectOutputStream oos=null;
094        try {
095            //fosを作成
096            FileOutputStream fos=openFileOutput("data.dat",MODE_PRIVATE);
097            //fosをラッピングする形でObjectOutputStreamインスタンスを作成
098            oos=new ObjectOutputStream(fos);
099            //oosがwriteObject(object)でobjectをファイルに書き込める
100            //今回はArrayListをそのまま書き込む
101            oos.writeObject(list);
102 
103        } catch (FileNotFoundException e) {
104            e.printStackTrace();
105        } catch (IOException e) {
106            e.printStackTrace();
107        }finally{
108            if(oos != null){
109                try {
110                    oos.close();
111                } catch (IOException e) {
112                    e.printStackTrace();
113                }
114            }
115        }
116    }
117}

コメント

タイトルとURLをコピーしました