Android AsyncTask don't return correct Result

后端 未结 3 708
抹茶落季
抹茶落季 2020-12-11 11:22

for one of projects i want to use Ksoap with AsyncTask. now in this below code AsyncTask can work correctly but after return result to

相关标签:
3条回答
  • 2020-12-11 12:14

    you can't return value from asyncTask at all, you can parse result, do what ever you want inside doInbackground() or in onPostExecute(), if you want more flexibility, you can call a method exist out of the asyncTask passing the result from onPostexecute():

    private void continueWithResult(String data){
    //do whatever you want with the json passed from onPostExecute()
    }
    
    class ProcessTask extends AsyncTask<Void, Void, String > {
    :
    :
        @Override
        protected void onPostExecute(String result) {
            continueWithResult(result);
        }
    :
    :
    

    and you really need to read the link posted by JTsunami

    0 讨论(0)
  • 2020-12-11 12:16

    You cannot get the return value of AsyncTask by

    tmp = String.valueOf(p.execute());

    This is because Android app doesn't wait for AsyncTask to return a value to move to next line.

    You need to use the onPostExecute() Method to process the return value of an AsyncTask .

    You can refer AsyncTask: where does the return value of doInBackground() go? for more syntax and more information.

    0 讨论(0)
  • 2020-12-11 12:19

    It seems this question spawned from Mahdi's confusion with the answer here, which formerly suggested using

    ProcessTask p = new ProcessTask(...);
    String result = p.execute();
    

    This obviously can't work as explained by JTsunami here. Anyway, because of that confusion, the intention of Mahdi here is to create and execute the AsyncTask (asynchronously!) and then return the result of the AsyncTask (synchronously!) when it hasn't received the result yet. The only solution is to handle the result INSIDE onPostExecute(). If you need to pass the result to other objects, like an Activity or Fragment, you have to actively pass the result because execute() and call(...) will never wait for it. A good option is to register a listener by replacing

    public static String call(SoapObject request) {
        ProcessTask p =new ProcessTask(request);
        return p.execute();
    }
    
    class ProcessTask extends AsyncTask<Void, Void, SoapObject>
        SoapObject request;
    
        public String ProcessTask(SoapObject rq) {
            request = rq;
        }
    
        ...
    
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
        }
    }
    

    with

    public void String call(SoapObject request, ResultListener listener) {
        ProcessTask p = new ProcessTask(request, listener);
        p.execute();
    }
    
    class ProcessTask extends AsyncTask<Void, Void, SoapObject>
        private SoapObject request;
        private ResultListener listener;
    
        public String ProcessTask(SoapObject rq, ResultListener l) {
            request = rq;
            listener = l;
        }
    
        ...
    
        @Override
        protected void onPostExecute(String result) {
            listener.onResult(result);
        }
    }
    
    public interface ResultListener {
        void onResult(String result);
    }
    

    Now you would call

    WSDLHelper.call(-your SoapObject here-, new ResultListener() {
        @Override
        public void onResult(String result) {
            // do whatever you want with the result
        }
    });
    

    which will make sure you receive the result asynchronously, but still in the same class that calls the method. Note that the return type of call(...) is void: You have to handle the result inside onResult().

    0 讨论(0)
提交回复
热议问题