私は現在、Android アプリケーションの開発を始めています。すべてが非常にシンプルでわかりやすいものになったと言わざるを得ません。
AsyncTask についてちょっとした質問があります。私のやり方が悪いのかもしれませんが、こんな状況です。
Web からリストのコンテンツを読み込む必要がある小さなアプリがあります。偽のリクエストに基づいてすべてを開発しましたが、すべてが素晴らしいものになりました。次に、実際のリクエストでコードを更新したところ、「ネットワーク オン メイン スレッド エラー」が発生しました。そこで、AsyncTask に切り替えることにしました。
AsyncTask に非同期作業をさせて、結果を別の場所 (実際には GUI 接続とすべてがある場所) で処理できるかどうか疑問に思っていました。可読性とロジックの観点から、インターフェイスを処理するすべてのコードをアクティビティに含める方が理にかなっていると思いましたが、タスクが完了したことをアクティビティに知らせるにはどうすればよいでしょうか?
私はこれらの単純なクラスとインターフェースを書きました (そしてそれは機能します) が、これが良いことなのか、それともそれを行うためのより良い方法があるのかを知りたいと思いました。
コードは次のとおりです。
public interface AsyncDelegate {
public void executionFinished(LazyLoaderWithDelegate lazyLoaderWithDelegate);
}
これはシンプルなインターフェースです。目的は、Activity にこれを実装させ、'executionFinished' メソッドを処理させることです。リスナーのようなもの。
import android.os.AsyncTask;
public class LazyLoaderWithDelegate<Params, Progress, Result> extends AsyncTask<Params, Progress, Result>{
AsyncDelegate delegate;
Result result;
public LazyLoaderWithDelegate(AsyncDelegate delegate){
this.delegate = delegate;
}
@Override
protected Result doInBackground(Object... params) {
//This will be Overridden again from the subclasses anyway.
return null;
}
@Override
protected void onPostExecute(Result r){
this.result = r;
delegate.executionFinished(this);
}
public Result getResult(){
return result;
}
}
このクラスは基本的に、タスクが終了したときにデリゲートに通知するためのスケルトン構造を提供します。
それで全部です。このクラスの使用例を次に示します。
public class LazyVideoLoader extends LazyLoaderWithDelegate<Void, Void, List<List<Video>>>{
public LazyVideoLoader(AsyncDelegate delegate) {
super(delegate);
}
@Override
protected List<Video> doInBackground(Void ...params) {
return ServerInterface.getVideos();
}
}
public class MainActivity extends Activity implements AsyncDelegate {
private LazyVideoLoader videoLoader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* Set up the lazy loaders
*/
videoLoader = new LazyVideoLoader(this);
videoLoader.execute();
}
@Override
public void executionFinished(LazyLoaderWithDelegate task) {
if(task == videoLoader){
List<Video> result = videoLoader.getResult();
//Do whatever you need...
}
}