1

私は現在、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...
        }

}
4

2 に答える 2

3

実行するものonPostExecuteはすべて UI スレッドにあります。また、 ononProgressUpdateを呼び出すだけで、作業の特定の部分が完了したら、UI スレッドでコードを実行できます。publishProgressdoInBackground

詳細については、これを参照してください。について知る必要があるすべてが含まれていますAsyncTask

于 2013-07-01T14:21:57.760 に答える
1

これが正しいと理解できれば、AsyncTask を実行する別のクラスがあります。タスクが完了すると、as callback used インターフェイスが Activity に通知します。これは、コンポーネントでコードをよりモジュール化することを考える場合に適しています。

最も一般的な方法は、AsyncTask を Activity の内部クラスとして使用することです。比較的小さいサイズの画像などをダウンロードしたいだけの場合は、これが推奨される方法です。内部クラスのすべてのフィールドにアクセスできるため、コンストラクター/インターフェイスでそれらを渡すよりも簡単になります。

読みやすくするためだけに、追加のクラスで AsyncTask を使用しないでください。さまざまな方法で結果に対して公正な計算/変更を行う必要がある場合は、問題ありません。

于 2013-07-01T14:44:22.440 に答える