AsyncTask Androidの例
私はAsyncTask
について読んでいて、以下の簡単なプログラムを試してみました。しかし,うまくいかないようです。どうすれば動くようになりますか?
public class AsyncTaskActivity extends Activity {
Button btn;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener((OnClickListener) this);
}
public void onClick(View view){
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
return null;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
}
バックグラウンド処理で5秒後にラベルを変更しようとしているだけです。
これは私の 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" >
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="10"
android:padding="10dip">
</ProgressBar>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Progress" >
</Button>
<TextView android:id="@+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Replace"/>
</LinearLayout>
665
3
別のスレッドを使ってGUIにアクセスしようとしていますね。これは一般的には良い方法ではありません。
AsyncTaskは、
doInBackground()
内のすべてを別のスレッド内で実行しますが、そのスレッドはビューがあるGUIにアクセスできません。preExecute()とpostExecute()を使えば、この新しいスレッドで重い処理が行われる前と後にGUIにアクセスすることができ、長い処理の結果をpostExecute()に渡して処理の結果を表示することもできます。
以下の行では、後でTextViewを更新しています。
を
onPostExecute()
に入れてください。そうすると、
doInBackground
が完了した後、TextViewのテキストが更新されるのがわかります。EDIT: あなたのonClickリスナーが、どのViewが選択されたかをチェックしていないことに気づきました。これを行う最も簡単な方法はswitch文であることがわかります。混乱を避けるために、すべての提案を含む完全なクラスを以下に編集しました。
正常に実行されていると思いますが、バックグラウンドのスレッドでUI要素を変更しようとしているので、それはできません。
呼び出しとAsyncTaskを以下のように修正してください。
呼び出しクラスについて
注:個人的には、AsyncTaskを拡張したクラスではなく、AsyncTaskのスレッドを実行する場所ではどこでも
onPostExecute()
を使うことをお勧めします。特に、AsyncTaskが複数の場所で必要とされ、微妙に異なる結果を処理する場合には、コードが読みやすくなると思います。**ロングスレッドクラス(AsyncTask を拡張):***。
この2本の線を動かす。
をAsyncTask'の
doInBackground
メソッドから外し、onPostExecute
メソッドの中に入れます。あなたのAsyncTask
は以下のようになるはずです。