« 開発真っ盛り | トップページ | 春はあけぼの »

2011年2月28日 (月)

バックグラウンドでの実行

今日はとても寒かったです。

寒い日は早く寝るに限ります。じゃぁ、これで。というわけにも行かないので小ネタを出します。

サーバとの通信とか、それに伴うファイルアクセスとかをやるとそれなりに待ちが発生します。UIを担当しているスレッドでこれをやると、UIが止まります。つまり、通信中はスクロールさせたりもできなくなるわけです。

これは、使いにくい、というか、使用者を不安にさせるのでやぱり、そういったことはバックグラウンドで処理することが求められます。そこで登場するのがAsyncTaskです。

Developerサイトにも例があるのですが、それを見ながら私も作ってみました。お題としては、ディレクトリをスキャンして、その中のファイルをXMLparserに掛けて、titleを取り出す。ということにしたかったのですが、長くなるので後半ははしょりました。

ディレクトリをバックグラウンドでスキャンして、ListViewに突っ込むプログラムです。File.listFilesをやって、そのリストの項目ごとにArrayAdapter.add()を呼んでいます。だた入れたのではつまらないのでpublishProgressを経由して一件づつ処理しています。その後に入っている500msのsleepは動作がよく分かるように入れたダミーのウェイトです。ぽこ、ぽこ、という感じでリストされますが、その間も普通にスクロールしたりできます。
あと、onProgressUpdateの中で呼び出しているnotifyDatasetChangedですが、とりあえず、ここでやる分にはおこられませんでした。が、doInBackgroundで呼び出すと別スレッドからViewにさわるんじゃねぇ、といって怒られるかもしれません。たぶん、そのためのハンドラでしょうから。

public class asyncTaskSample extends ListActivity{

    static final String TAG = "AsyncTaskSample";
    static final String SDCard = "/sdcard";

    private Context mContext ;

    private String[] mList = new String[] {""};
    private ArrayAdapter mAdapter ;
   
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
        setContentView(R.layout.asyncsample);
   
       mContext = getApplicationContext();
       mInflater =LayoutInflater.from(mContext);
      
       mAdapter = new ArrayAdapter<String>(mContext, android.R.layout.simple_list_item_1);

        setListAdapter(mAdapter);
    }

    private class DirScan extends AsyncTask<String, String, Void>{
            @Override
            protected Void doInBackground(String... dir) {
                  File sdir = new File(dir[0]);
                  File[] filelist = sdir.listFiles();
                  for (File file : filelist){
                        publishProgress(file.getName());
                        SystemClock.sleep(500);
                  }
                  return null;
            }
            protected void onProgressUpdate(String... foundDir){
                  mAdapter.add(foundDir[0]);
                  mAdapter.notifyDataSetChanged();
            }
            protected void onPostExecute(Void nil){
                  Toast.makeText(mContext, "onPostExecute", Toast.LENGTH_SHORT);
            }
    }
    public void refresh(View v){
      new DirScan().execute(SDCard);
    }
}

« 開発真っ盛り | トップページ | 春はあけぼの »

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/60027/50997986

この記事へのトラックバック一覧です: バックグラウンドでの実行:

« 開発真っ盛り | トップページ | 春はあけぼの »