374

この2つのクラスがあります。私のメインアクティビティとを拡張するアクティビティです。メインアクティビティでは、AsyncTaskから結果を取得する必要があります。メインのアクティビティに結果を渡す、または取得するにはどうすればよいですか?OnPostExecute()AsyncTask

これがサンプルコードです。

私の主な活動。

public class MainActivity extends Activity{

    AasyncTask asyncTask = new AasyncTask();

    @Override
    public void onCreate(Bundle aBundle) {
        super.onCreate(aBundle);            

        //Calling the AsyncTask class to start to execute.  
        asyncTask.execute(a.targetServer); 

        //Creating a TextView.
        TextView displayUI = asyncTask.dataDisplay;
        displayUI = new TextView(this);
        this.setContentView(tTextView); 
    }

}

これはAsyncTaskクラスです

public class AasyncTask extends AsyncTask<String, Void, String> {

TextView dataDisplay; //store the data  
String soapAction = "http://sample.com"; //SOAPAction header line. 
String targetServer = "https://sampletargeturl.com"; //Target Server.

//SOAP Request.
String soapRequest = "<sample XML request>";    



@Override
protected String doInBackground(String... string) {

String responseStorage = null; //storage of the response

try {


    //Uses URL and HttpURLConnection for server connection. 
    URL targetURL = new URL(targetServer);
    HttpURLConnection httpCon = (HttpURLConnection) targetURL.openConnection();
    httpCon.setDoOutput(true);
    httpCon.setDoInput(true);
    httpCon.setUseCaches(false); 
    httpCon.setChunkedStreamingMode(0);

    //properties of SOAPAction header
    httpCon.addRequestProperty("SOAPAction", soapAction);
    httpCon.addRequestProperty("Content-Type", "text/xml; charset=utf-8"); 
    httpCon.addRequestProperty("Content-Length", "" + soapRequest.length());
    httpCon.setRequestMethod(HttpPost.METHOD_NAME);


    //sending request to the server.
    OutputStream outputStream = httpCon.getOutputStream(); 
    Writer writer = new OutputStreamWriter(outputStream);
    writer.write(soapRequest);
    writer.flush();
    writer.close();


    //getting the response from the server
    InputStream inputStream = httpCon.getInputStream(); 
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(50);

    int intResponse = httpCon.getResponseCode();

    while ((intResponse = bufferedReader.read()) != -1) {
        byteArrayBuffer.append(intResponse);
    }

    responseStorage = new String(byteArrayBuffer.toByteArray()); 

    } catch (Exception aException) {
    responseStorage = aException.getMessage(); 
    }
    return responseStorage;
}

protected void onPostExecute(String result) {

    aTextView.setText(result);

}       

}   
4

17 に答える 17

774

簡単:

  1. interfaceクラスを作成します。ここで、String outputはオプションです。または、返したい任意の変数にすることができます。

     public interface AsyncResponse {
         void processFinish(String output);
     }
    
  2. クラスに移動し、インターフェイスをフィールドとしてAsyncTask宣言します。AsyncResponse

     public class MyAsyncTask extends AsyncTask<Void, Void, String> {
       public AsyncResponse delegate = null;
    
         @Override
         protected void onPostExecute(String result) {
           delegate.processFinish(result);
         }
      }
    
  3. implementsメインのアクティビティでは、インターフェイスする必要がありますAsyncResponse

     public class MainActivity implements AsyncResponse{
       MyAsyncTask asyncTask =new MyAsyncTask();
    
       @Override
       public void onCreate(Bundle savedInstanceState) {
    
          //this to set delegate/listener back to this class
          asyncTask.delegate = this;
    
          //execute the async task 
          asyncTask.execute();
       }
    
       //this override the implemented method from asyncTask
       @Override
       void processFinish(String output){
          //Here you will receive the result fired from async class 
          //of onPostExecute(result) method.
        }
      }
    

アップデート

これが多くの人に愛されているとは知りませんでした。そこで、シンプルで便利な使い方をご紹介しますinterface

まだ同じものを使用していinterfaceます。AsyncTask参考までに、これをクラスに組み合わせることができます。

AsyncTaskクラスで:

public class MyAsyncTask extends AsyncTask<Void, Void, String> {

  // you may separate this or combined to caller class.
  public interface AsyncResponse {
        void processFinish(String output);
  }

  public AsyncResponse delegate = null;

    public MyAsyncTask(AsyncResponse delegate){
        this.delegate = delegate;
    }

    @Override
    protected void onPostExecute(String result) {
      delegate.processFinish(result);
    }
}

あなたのActivityクラスでこれをしてください

public class MainActivity extends Activity {
  
   MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){
    
     @Override
     void processFinish(String output){
     //Here you will receive the result fired from async class 
     //of onPostExecute(result) method.
     }
  }).execute();

 }

または、アクティビティにインターフェイスを再度実装します

public class MainActivity extends Activity 
    implements AsyncResponse{
      
    @Override
    public void onCreate(Bundle savedInstanceState) {

        //execute the async task 
        new MyAsyncTask(this).execute();
    }
      
    //this override the implemented method from AsyncResponse
    @Override
    void processFinish(String output){
        //Here you will receive the result fired from async class 
        //of onPostExecute(result) method.
    }
}

上記の 2 つのソリューションを見るとわかるように、1 番目と 3 番目のソリューションは method を作成する必要がprocessFinishあり、もう 1 つはメソッドが caller パラメータ内にあります。3 番目は、ネストされた無名クラスがないため、より適切です。

ヒント: String outputString response、およびString resultを異なる一致するタイプに変更して、異なるオブジェクトを取得します。

于 2012-09-25T02:08:04.227 に答える
25

いくつかのオプションがあります:

  • AsyncTaskクラスをクラス内にネストしますActivity。複数のアクティビティで同じタスクを使用しないと仮定すると、これが最も簡単な方法です。コードはすべて同じままです。既存のタスク クラスをアクティビティのクラス内のネストされたクラスに移動するだけです。

    public class MyActivity extends Activity {
        // existing Activity code
        ...
    
        private class MyAsyncTask extends AsyncTask<String, Void, String> {
            // existing AsyncTask code
            ...
        }
    }
    
  • AsyncTaskあなたの への参照を取るカスタム コンストラクターを作成しますActivity。のようなものでタスクをインスタンス化しますnew MyAsyncTask(this).execute(param1, param2)

    public class MyAsyncTask extends AsyncTask<String, Void, String> {
        private Activity activity;
    
        public MyAsyncTask(Activity activity) {
            this.activity = activity;
        }
    
        // existing AsyncTask code
        ...
    }
    
于 2012-09-25T01:35:01.000 に答える
19

以下のアプローチは非常に簡単だと感じました。

コールバック用のインターフェースを宣言しました

public interface AsyncResponse {
    void processFinish(Object output);
}

次に、すべてのタイプの並列リクエストに応答するための非同期タスクを作成しました

 public class MyAsyncTask extends AsyncTask<Object, Object, Object> {

    public AsyncResponse delegate = null;//Call back interface

    public MyAsyncTask(AsyncResponse asyncResponse) {
        delegate = asyncResponse;//Assigning call back interfacethrough constructor
    }

    @Override
    protected Object doInBackground(Object... params) {

      //My Background tasks are written here

      return {resutl Object}

    }

    @Override
    protected void onPostExecute(Object result) {
        delegate.processFinish(result);
    }

}

次に、アクティビティ クラスのボタンをクリックすると、非同期タスクが呼び出されます。

public class MainActivity extends Activity{

    @Override
    public void onCreate(Bundle savedInstanceState) {

    Button mbtnPress = (Button) findViewById(R.id.btnPress);

    mbtnPress.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {

                    @Override
                    public void processFinish(Object output) {
                        Log.d("Response From Asynchronous task:", (String) output);

                        mbtnPress.setText((String) output);
                   }
                });

                asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." });


            }
        });

    }



}

ありがとう

于 2015-02-14T07:39:03.787 に答える
7

AsyncTask を呼び出すときに onPostExecute をオーバーライドするだけで、数行で実行できます。以下に例を示します。

new AasyncTask()
{
    @Override public void onPostExecute(String result)
    {
       // do whatever you want with result 
    }
}.execute(a.targetServer);

お役に立てば幸いです、幸せなコーディング:)

于 2015-03-17T16:00:41.143 に答える
4

get()のメソッドAsyncTask(またはオーバーロードされた )を呼び出すことができますget(long, TimeUnit)。このメソッドは、 が作業を完了するまでブロックし、AsyncTask完了した時点で を返しますResult

非同期タスクの作成/開始とメソッドの呼び出しの間に他の作業を行うことが賢明getです。そうしないと、非同期タスクを非常に効率的に利用できません。

于 2012-09-25T01:30:03.820 に答える
1

Activity クラスに静的メンバーを作成します。次に、onPostExecute

たとえば、AsyncTask の結果が文字列の場合、アクティビティに public static 文字列を作成します

public static String dataFromAsyncTask;

次に、onPostExecuteAsyncTask で、メイン クラスへの静的呼び出しを行い、値を設定します。

MainActivity.dataFromAsyncTask = "result blah";

于 2012-09-25T01:38:08.873 に答える
0

スレッドとハンドラー/メッセージを使用して機能させます。手順は次のとおりです。進行状況を宣言するダイアログ

ProgressDialog loadingdialog;

操作が終了したらダイアログを閉じる関数を作成します。

   private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        loadingdialog.dismiss();

    }
    };

実行の詳細をコーディングします。

 public void startUpload(String filepath) {
    loadingdialog = ProgressDialog.show(MainActivity.this, "Uploading", "Uploading Please Wait", true);
    final String _path = filepath;
    new Thread() {
        public void run() {
            try {
                UploadFile(_path, getHostName(), getPortNo());
                handler.sendEmptyMessage(0);

            } catch (Exception e) {
                Log.e("threadmessage", e.getMessage());
            }
        }
    }.start();
}
于 2016-10-09T13:37:06.227 に答える