1. ホーム
  2. android

[解決済み] AsyncTaskは別のクラスなので、OnPostExecute()の結果をメインアクティビティに取得するにはどうすればよいですか?

2022-03-14 10:36:50

質問

私はこの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);

}       

}   

解決方法は?

簡単です。

  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();

 }

または、Activityに再度インターフェイスを実装する

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番目の解決策を見ることができるように、これはメソッドを作成する必要があります。 processFinish もうひとつは、メソッドが呼び出し側のパラメータの中にあるものです。3番目の方法は、ネストされた匿名クラスがないため、よりすっきりしています。

チップ : 変更 String output , String response および String result を異なるマッチングタイプに変換することで、異なるオブジェクトを取得することができます。