我有两门课。我的主活动和一个扩展AsyncTask,现在在我的主活动中,我需要从AsyncTask中的OnPostExecute()获得结果。如何将结果传递给我的主活动?

下面是示例代码。

我的主要活动。

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

}       

}   

当前回答

容易:

Create interface class, where String output is optional, or can be whatever variables you want to return. public interface AsyncResponse { void processFinish(String output); } Go to your AsyncTask class, and declare interface AsyncResponse as a field : public class MyAsyncTask extends AsyncTask<Void, Void, String> { public AsyncResponse delegate = null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); } } In your main Activity you need to implements interface 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. } }


更新

我不知道这是你们很多人的最爱。这是一个简单方便的界面使用方法。

仍然使用相同的界面。供参考,你可以把它合并到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);
    }
}

在你的活动课上做这个吗

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.
    }
}

正如你可以看到上面的两个解决方案,第一个和第三个,它需要创建方法processFinish,另一个,方法在调用者参数中。第三种方法更加简洁,因为没有嵌套的匿名类。

提示:将String输出、String响应和String结果更改为不同的匹配类型,以便获得不同的对象。

其他回答

试试这个:

public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {

    private CallBack callBack;

    public interface CallBack {
        void async( JSONObject jsonResult );
        void sync( JSONObject jsonResult );
        void progress( Integer... status );
        void cancel();
    }

    public SomAsyncTask(CallBack callBack) {
        this.callBack = callBack;
    }

    @Override
    protected JSONObject doInBackground(String... strings) {

        JSONObject dataJson = null;

        //TODO query, get some dataJson

        if(this.callBack != null)
            this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD

        return dataJson;

    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

        if(this.callBack != null)
            this.callBack.progress(values);// synchronize with MAIN LOOP THREAD

    }

    @Override
    protected void onPostExecute(JSONObject jsonObject) {
        super.onPostExecute(jsonObject);

        if(this.callBack != null)
            this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();

        if(this.callBack != null)
            this.callBack.cancel();

    }
}

用法示例:

public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);

         final Context _localContext = getContext();
         SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {

                @Override
                public void async(JSONObject jsonResult) {//async thread
                    //some async process, e.g. send data to server...
                }

                @Override
                public void sync(JSONObject jsonResult) {//sync thread
                    //get result...

                    //get some resource of Activity variable...
                    Resources resources = _localContext.getResources();
                }

                @Override
                public void progress(Integer... status) {//sync thread
                    //e.g. change status progress bar...
                }

                @Override
                public void cancel() {

                }

            };

            new SomeAsyncTask( someCallBack )
                                .execute("someParams0", "someParams1", "someParams2");

    }

容易:

Create interface class, where String output is optional, or can be whatever variables you want to return. public interface AsyncResponse { void processFinish(String output); } Go to your AsyncTask class, and declare interface AsyncResponse as a field : public class MyAsyncTask extends AsyncTask<Void, Void, String> { public AsyncResponse delegate = null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); } } In your main Activity you need to implements interface 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. } }


更新

我不知道这是你们很多人的最爱。这是一个简单方便的界面使用方法。

仍然使用相同的界面。供参考,你可以把它合并到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);
    }
}

在你的活动课上做这个吗

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.
    }
}

正如你可以看到上面的两个解决方案,第一个和第三个,它需要创建方法processFinish,另一个,方法在调用者参数中。第三种方法更加简洁,因为没有嵌套的匿名类。

提示:将String输出、String响应和String结果更改为不同的匹配类型,以便获得不同的对象。

您需要使用“协议”将数据委托或提供给AsynTask。

委托和数据源

委托是一个对象,当另一个对象在程序中遇到事件时,它代表另一个对象或与另一个对象协调行动。(苹果定义)

协议是定义一些方法来委托一些行为的接口。

这是一个完整的例子!!

我通过使用线程和处理程序/消息使它工作。 步骤如下: 声明进度对话框

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

希望你已经读过了,如果没有,请阅读。

https://developer.android.com/reference/android/os/AsyncTask

根据结果数据的性质,您应该选择您能想到的最佳选项。

使用接口是一个很好的选择

其他的选择是…

If the AsyncTask class is defined inside the very class you want to use the result in.Use a static global variable or get() , use it from outer class (volatile variable if necessary). but should be aware of the AsyncTask progress or should at least make sure that it have finished the task and result is available through global variable / get() method. you may use polling, onProgressUpdate(Progress...), synchronization or interfaces (Which ever suits best for you) If the Result is compatible to be a sharedPreference entry or it is okay to be saved as a file in the memory you could save it even from the background task itself and could use the onPostExecute() method to get notified when the result is available in the memory. If the string is small enough, and is to be used with start of an activity. it is possible to use intents (putExtra()) within onPostExecute() , but remember that static contexts aren't that safe to deal with. If possible, you can call a static method from the onPostExecute() method, with the result being your parameter