0

私はしばらくの間、AndroidのAsyncTaskクラスを実装する方法を検討してきました。基本的に、私はそれが古典的なシナリオを実行することを望んでいます:私がネットワーク呼び出しをしている間、単に無期限のローディングホイールをアニメーション化します。ただし、実際には、これを希望どおりに機能させるためにいくつかの問題が発生しています。

私は現在このようなコードを持っています:(私の希望するAsyncTask実装の前に)

 String result = timeConsumingNetworkCall(String someData, ArrayList stuff1);
 doStuff(result);

 String result = timeConsumingNetworkCall(String otherData, ArrayList stuff2);
 doOtherStuff(result);

 String result = timeConsumingNetworkCall(String dataAgain, ArrayList stuff3);
 doYetEvenMore(result);

AsyncTask呼び出しを再利用してデータを渡し、ネットワーク呼び出しを行ってから、上記のように必要に応じて処理できるデータを返します。

これで、アプリが読み込まれずに「ハング」しているように見えることを除けば、これは完璧に機能します。AsyncTaskが登場します。まだ「取得」していないのかもしれませんが、AsyncTaskの外部にデータを返して、doStuffToUI()etcが使用できるようにするにはどうすればよいですか?

最終的には、次のようなAsyncTaskを使用できればと思います。

String result = new PostToFile("function_name", keysAndValues).execute().getResult();
doStuff(result); // this shouldn't execute until the AsyncTask is done

私はこの権利について行っていますか?これはどのようにすべきであるか、または行うことができますか?これが私のAsyncTaskクラスです。簡潔にするために短縮されています。

private class PostToFile extends AsyncTask<PostToFile, Void, Void>{
    private String functionName;
    private ArrayList<NameValuePair> postKeyValuePairs;
    private String result = "";

    public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
        functionName= function;
        postKeyValuePairs = keyValuePairs;
    }

    @Override
    protected void onPreExecute() {
        progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false);
    }

    @Override
    protected Void doInBackground(PostToFile... params) {                       
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair(FUNCTION_KEYWORD, functionName));
        for (int i = 0; i < postKeyValuePairs.size(); i++)            {
            nameValuePairs.add(postKeyValuePairs.get(i));
        }

        try{
            // ***do the POST magic.***
            result = response.toString();
        }
        catch (Exception e){
             // clean up my mess
        }

        return null;
    }

    private String getResult(){
        return result; // can I use this somehow???
    }

    @Override
    protected void onPostExecute(Void result) {
        progressDialog.dismiss();
    }
 }

よろしくお願いします。よろしくお願いします。必要に応じて明確にさせていただきます。

4

2 に答える 2

1

doStuff(結果); これは、AsyncTaskが完了するまで実行されるべきではありません

次に、 AsyncTask.get()を使用する必要があります 。これにより、必要に応じて計算が完了するまで待機し、その結果を取得します。

AsyncTask.get()実行が完了するまでメインUIスレッドをフリーズ するため、UIのフリーズを回避し、AsyncTaskの実行が完了した後にUi要素を更新するdoInBackgroundためにスレッドを使用する必要があります。runOnUiThread

例 :-

public void  ThreaddoStuff(){

 Thread th=new Thread(){
    @Override
    public void run(){
      // start AsyncTask exection here
      String result = new PostToFile("function_name", 
                      keysAndValues).execute().get().getResult();

     // now call doStuff by passing result
     doStuff(result);
    }
  };
th.start();
}
于 2013-03-01T09:27:38.940 に答える
1

デフォルトの onPostExecute 実装で再利用可能な非同期タスクを作成し、呼び出しごとにデフォルトの実装をオーバーライドします。

public static class PostToFile extends AsyncTask<Void, Void, String> {
        private String functionName;
        private ArrayList<NameValuePair> postKeyValuePairs;
        private String result = "";

        public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
            functionName= function;
            postKeyValuePairs = keyValuePairs;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // show progress bar
        }

        @Override
        protected String doInBackground(Void... arg0) {
            // make request and get the result
            return null; // return result
        }

        @Override
        protected void onCancelled(String result) {
            super.onCancelled(result);
            // hide progress bar
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            // hide progress bar
        }
    }

非同期タスクを実行します。

new PostToFile(function, keyValuePairs) {

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result); // this will hide a progress bar

            doStuff(result); 
        }
}.execute();

new PostToFile(otherFunction, otherKeyValuePairs) {

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result); // this will hide a progress bar

            doOtherStuff(result); 
        }
}.execute();
于 2013-03-01T11:02:00.810 に答える