Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Loaderを使ったデータの読み込み

$
0
0

最近のAndroidでのデータの読み込みはLoaderというものを使うらしいです。ちょっとやってみました。

オレオレ仕様にカスタムできるLoader

カーソル前提のLoaderもあるんですが、自前のデータ読み込み処理を書けるAsyncTaskLoaderというのがあるのでそれを使うのが一番柔軟っぽいです。

AsyncTaskLoaderは、継承してloadInBackgroundメソッドを実装するだけの簡単クラスです。例えばPersonという以下のようなクラスがあるとします。

// めんどいのでActivityの内部クラスにしたpublicstaticclass Person {
    private String name;
    public String getName() {
        return name;
    }
    publicvoid setName(String name) {
        this.name = name;
    }
    @Overridepublic String toString() {
        returnthis.name;
    }
}

適当にこのクラスを生成する実装は以下のようになります。画面にeditTextという名前のEditTextを置いていて、そいつから取得したテキストをベースに先ほどのPersonクラスを組み立てては、Listに突っ込んでいます。時間のかかる処理っぽく少しSleepも入れています。

final Random r = new Random();
final String input = this.editText.getText().toString();
AsyncTaskLoader<List<Person>> loader = new AsyncTaskLoader<List<Person>>(this) {
    @Overridepublic List<Person> loadInBackground() {
        Log.d("MyActivity", "loadInBackground");
        int count = r.nextInt(100);
        List<Person> result = new ArrayList<Person>();
        for (int i = 0; i < count; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Person p = new Person();
            p.setName(input + " " + i);
            result.add(p);
        }
        return result;
    }
};

Loaderを使うためのコールバックインターフェース

Javaってコールバック地獄でめんどくさいですよね…。Loaderをバックグラウンドで実行するために、以下のインターフェースを実装しないといけません。これは先ほど示したAsyncTaskLoaderクラスとは別ものです。LoaderManager.LoaderCallbacksというインターフェースになります。Tは、AsyncTaskLoaderのTと合わせて使います。

LoaderCallbacksには、以下の3つのメソッドがあります。

  • onCreateLoader: Loaderを作るメソッド
  • onLoadFinished: Loaderの処理が終わった後に呼ばれるメソッド
  • onLoaderReset: リセットしたときに呼ばれるメソッド

ActivityにLoaderCallbacksインターフェースを実装するサンプルをよく見るのでここでもそうしました。

まず、onCreateLoaderメソッドです。こいつはさっきのAsyncTaskLoaderを作成しています。 そして、Loaderの処理をキックするforceLoadメソッドを呼んでいます(大事)

@Overridepublic Loader<List<Person>> onCreateLoader(int id, Bundle args) {
    Log.d("MyActivity", "onCreateLoader");
    Random r = new Random();
    final String input = this.editText.getText().toString();
    AsyncTaskLoader<List<Person>> loader = new AsyncTaskLoader<List<Person>>(this) {
        @Overridepublic List<Person> loadInBackground() {
            Log.d("MyActivity", "loadInBackground");
            int count = r.nextInt(100);
            List<Person> result = new ArrayList<Person>();
            for (int i = 0; i < count; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Person p = new Person();
                p.setName(input + " " + i);
                result.add(p);
            }
            return result;
        }
    };
    loader.forceLoad();
    return loader;
}

そして、onLoadFinishedメソッドで読み込みが終わったときの処理を書きます。ここではArrayAdapterにデータをセットしています。

@Overridepublicvoid onLoadFinished(Loader<List<Person>> loader, List<Person> data) {
    Log.d("MyActivity", "onLoadFinished");
    this.peopleAdapter.clear();
    this.peopleAdapter.addAll(data);
}
@Overridepublicvoid onLoaderReset(Loader<List<Person>> loader) {
}

ついでに、何もしないonLoaderResetも書いておきました。

コード全体

レイアウトファイル。EditTextとListView置いただけの画面

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/editText" /><ListViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/listView" /></LinearLayout>

Activityに全部処理かいてます///

package com.example.kazuki.myapplication;

import android.app.Activity;
import android.app.LoaderManager;
import android.content.AsyncTaskLoader;
import android.content.Loader;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;


publicclass MyActivity extends Activity implements LoaderManager.LoaderCallbacks<List<MyActivity.Person>>  {

    private EditText editText;
    private ListView listView;
    private ArrayAdapter<Person> peopleAdapter;


    @Overrideprotectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        this.editText = (EditText) this.findViewById(R.id.editText);
        this.listView = (ListView) this.findViewById(R.id.listView);
        this.peopleAdapter = new ArrayAdapter<Person>(this, android.R.layout.simple_list_item_1);
        this.listView.setAdapter(this.peopleAdapter);
    }


    @Overridepublicboolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.my, menu);
        returntrue;
    }

    @Overridepublicboolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();
        if (id == R.id.action_settings) {
            Log.d("MyActivity", "onOptionsItemSelected");
            this.getLoaderManager().restartLoader(0, null, this);
            returntrue;
        }
        returnsuper.onOptionsItemSelected(item);
    }


    @Overridepublic Loader<List<Person>> onCreateLoader(int id, Bundle args) {
        Log.d("MyActivity", "onCreateLoader");
        final Random r = new Random();
        final String input = this.editText.getText().toString();
        AsyncTaskLoader<List<Person>> loader = new AsyncTaskLoader<List<Person>>(this) {
            @Overridepublic List<Person> loadInBackground() {
                Log.d("MyActivity", "loadInBackground");
                int count = r.nextInt(100);
                List<Person> result = new ArrayList<Person>();
                for (int i = 0; i < count; i++) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Person p = new Person();
                    p.setName(input + " " + i);
                    result.add(p);
                }
                return result;
            }
        };
        loader.forceLoad();
        return loader;
    }

    @Overridepublicvoid onLoadFinished(Loader<List<Person>> loader, List<Person> data) {
        Log.d("MyActivity", "onLoadFinished");
        this.peopleAdapter.clear();
        this.peopleAdapter.addAll(data);
    }

    @Overridepublicvoid onLoaderReset(Loader<List<Person>> loader) {

    }


    publicstaticclass Person {
        private String name;

        public String getName() {
            return name;
        }

        publicvoid setName(String name) {
            this.name = name;
        }

        @Overridepublic String toString() {
            returnthis.name;
        }
    }
}

Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>