无法从 AsyncTask 返回值;使用接口和委托;

Posted

技术标签:

【中文标题】无法从 AsyncTask 返回值;使用接口和委托;【英文标题】:can not return value from AsyncTask; using interface and delegate; 【发布时间】:2021-04-15 05:15:15 【问题描述】:

我正在 AsyncTask 中进行 HTTP 连接。我将查询的字符串结果返回给调用代码。在那里,我将 EditText "HTTPResult" 的值设置为返回的结果字符串。但是 HTTPResult 是空的。这意味着没有任何内容返回给调用代码。但是,我在 AsyncTask 中获取结果字符串,并且可以在 AsyncTask 的 protected void onPostExecute(String bitmap) 方法中设置 HTTPResult。然后我使用了接口和委托,但没有得到结果。

代码:

public class RegisterActivity extends AppCompatActivity implements AsyncResponse 
    Button btn_Connect;
    EditText busNumber;
    EditText text;
    EditText HTTPResult;
    String myServer="http://swulj.atwebpages.com/hi.php";
    String myResult, token;
    HTTPConnection1 conn = new HTTPConnection1();
    RegisterActivity obj = this;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        btn_Connect = (Button) findViewById(R.id.button_Connect);
        busNumber = (EditText) findViewById(R.id.Bus_number);
        text = (EditText) findViewById(R.id.text);
        HTTPResult = (EditText) findViewById(R.id.HTTPResult);

        btn_Connect.setOnClickListener(new View.OnClickListener() 
            public void onClick(View v) 
                // it was the 1st button

                Toast.makeText(getApplicationContext(),"You download is resumed2",Toast.LENGTH_LONG).show();
                conn.delegate =  obj;

                conn.execute(myServer, (String) busNumber.getText().toString());
                //sleep(50000);
                HTTPResult.setText(myResult);
                /*StringTokenizer st = new StringTokenizer(myResult);
                token = st.nextToken("<br>");
                text.setText(token);
                while (st.hasMoreTokens()) 
                    token = st.nextToken("<br>");
                    busNumber.setText(token);
                */
            
        );
    

    @Override
    public void processFinish(String output)
        //Here you will receive the result fired from async class
        //of onPostExecute(result) method.
        myResult = output;
    





    class HTTPConnection1 extends AsyncTask<String, Void, String> 
        String result;
        String url;
        String busNumber;
        public AsyncResponse delegate = null;
        
        @Override
        protected String doInBackground(String... params) 
            url = params[0];
            busNumber = params[1];
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            try 
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
                nameValuePairs.add(new BasicNameValuePair("id", busNumber));
                nameValuePairs.add(new BasicNameValuePair("message", "msg"));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse httpResponse = httpclient.execute(httppost);
                InputStream inputStream = httpResponse.getEntity().getContent();
                //HTTPResult.setText("result3");
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                //HTTPResult.setText("result4");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                //HTTPResult.setText("result5");
                StringBuilder stringBuilder = new StringBuilder();
                //HTTPResult.setText("result6");
                String bufferedStrChunk = null;

                while ((bufferedStrChunk = bufferedReader.readLine()) != null) 
                    stringBuilder.append(bufferedStrChunk);
                


                result = stringBuilder.toString();
                //result= "Sandeep";

             catch (ClientProtocolException e) 
                result = "ClientProtocolException";
                // TODO Auto-generated catch block
             catch (IOException e) 
                result = "IOException";
                // TODO Auto-generated catch block
            
            return result;
        

        @Override
        protected void onPostExecute(String bitmap) 
            super.onPostExecute(bitmap);
            //HTTPResult.setText(result);
            delegate.processFinish(bitmap);

        

    

    public interface AsyncResponse  
        void processFinish(String output);
    

  

我的动机不是将文本设置成HTTPResult,而是设置字符串myResult;我正在使用 HTTPResult 测试值

【问题讨论】:

HTTPResult.setText(myResult); 太早了。异步任务尚未准备好。将该语句放在 onPostExecute 中。 【参考方案1】:

这个问题是因为 AsyncTask 在后台线程中执行任务,所以当您尝试在 EditText 中设置结果时,AsyncTask 可能尚未完成,因此您的 myResult 将具有修复的默认值,您可以更新您的 EditText在 onPostExecute 方法中,以及这条线在 onPostExecute 中正常工作的原因

HTTPResult.setText(bitmap);

编辑: 您可以在 onPostExecute 中更新 myResult,但问题是要知道 AsyncTask 何时完成,以便您可以通过使用接口作为回调来解决此问题

查看此问题以查找如何使用接口作为 AsyncTask 的回调的示例

android asynctask sending callbacks to ui

这是一个关于如何使用接口创建回调的好教程

https://www.tutorialspoint.com/Callback-using-Interfaces-in-Java

编辑 2::将 setText 从 onCreate 移动到您的 processFinish 函数,或者您可以检查日志或 toast 以在异步任务完成时更新 ui 并将值推送到您的回调

@Override
public void processFinish(String output)
    myResult = output;
    HTTPResult.setText(myResult);

【讨论】:

我的动机不是将文本设置成HTTPResult,而是设置字符串myResult;我正在使用 HTTPResult 测试值 您可以在 onPostExecute 中设置它,但问题是要知道 AsyncTask 何时完成开始使用 myResult,您可以使用接口并创建 Callback 以在 AsyncTask 完成时运行并在其中使用您的结果跨度> 我看不懂,你能举个例子吗? but the problem is to know when AsyncTask finished to start using myResult 这完全没有问题,因为它在调用 onPostExecute 时完成。不需要接口。 @blackapps 是的,它在调用 onPostExecute 时完成,但我的意思是使用接口从 onCreate 知道是否调用了 onPostExecute 以开始使用 myResult

以上是关于无法从 AsyncTask 返回值;使用接口和委托;的主要内容,如果未能解决你的问题,请参考以下文章

如何从 AsyncTask 返回布尔值?

如何从AsyncTask返回布尔值?

从Android中的AsyncTask返回一个值[重复]

从Android中的AsyncTask返回一个值[重复]

asynctask 函数无法识别结果值

如何从存储库访问和返回 AsyncTask 的结果?