Return 来自 AsyncTask/doInBackground 的多个值并在其他方法中使用它

Return multiple values from AsyncTask/doInBackground and use it in other method

这是我用来获取值的方法。

 @Override
    protected Void doInBackground(String... params) {
        try {

            Intent intent = getIntent();
            String dvlaNumFin = intent.getStringExtra("dvlaNumber");

            final TextView outputView = (TextView) findViewById(R.id.showOutput);
            final URL url = new URL("https://dvlasearch.appspot.com/DvlaSearch?licencePlate="+dvlaNumFin+"&apikey=");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod("GET");
            connection.setRequestProperty("USER-AGENT", "Mozilla/5.0");
            connection.setRequestProperty("ACCEPT-LANGUAGE", "en-US,en;0.5");

            final StringBuilder output = new StringBuilder(String.valueOf(url));

           BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line = "";
            StringBuilder responseOutput = new StringBuilder();
            System.out.println("output===============" + br);
            while ((line = br.readLine()) != null) {
                responseOutput.append(line);
            }
            br.close();

            HandleJSON obj = new HandleJSON("");

            obj.readAndParseJSON(responseOutput.toString());

            output.append(System.getProperty("line.separator") + "\n" + System.getProperty("line.separator") + "Make : " + obj.getMake() + "\nModel : " + obj.getModel());
            output.append("\nSix Month Rate  : " + obj.getSixMonthRate() + "\nTwelve Month Rate : " + obj.getTwelveMonthRate() + "\nDate of First Registration : " + obj.getDateofFirstRegistrationegistration());
            output.append("\nYear of Manufacture : " + obj.getYearOfManufacture() + "\nCylinder Capacity : " + obj.getCylinderCapacity() + "\nCO2 Emmissions : " + obj.getCo2Emissions());
            output.append("\nVIN number : " + obj.getVin() + "\nTransmission type : " + obj.getTransmission());

            DVLAresult.this.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    outputView.setText(output);
                    progress.dismiss();

                }
            });

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

我想使用 obj.getMake() 等,来自 JSON 的值。但是不明白怎么做,还是return吧。我知道应该是 return 值,或者使用 final.

只需在 AsyncTask 中实现 onPostExecute class :)

例如:

@Override
protected void onPostExecute(String makeValue) {
    // remember this method gets called on main thread
    letsCallFogsMethod(makeValue); //call your method and pass the make value here :)
}

就是这样,伙计:) 现在这个 onPostExecute 怎么会得到任何价值??? 你必须 return 从 doInBackground 方法老兄:)

喜欢

@Override
protected String doInBackground(String... params) {
     //after all bra bla simply say
     return obj.getMake();
}

你注意到你的 doInBackground 签名伙伴有什么变化吗??是的,我从 Void 改为 String :)

通过编写字符串,您通知当您完成执行 doInBackground 时,您将 return 一个字符串到 onPostExecute :)

所以,如果我按答案中的原样写,它会起作用吗??没有。 鉴于您在 doInBackground 中指定了 Void ,您的异步任务签名可能类似于

private class FogsAsyncTask extends AsyncTask<bla,blah,Void> {

你能看到最后的虚空吗??? :) 但是现在你已经改变了 doInBackground 是不是所以更新 AsyncTask 签名 :)

private class FogsAsyncTask extends AsyncTask<bla,blah,String> {

现在它应该可以正常工作了:)快乐的编码伙伴:)希望我的回答对你有帮助:)

您可以在 onPostExecute 方法上获取输出,只需覆盖该方法并在其上获取输出

AsyncTask 有三个(主要)方法,onPreExecutedoInBackgroundonPostExecute。只有 doInBackGround 运行 在后台线程上,另外两个 运行 在 UI 线程上。 (还有onProgressUpdate不过这里略过)

在你的情况下,return 任何你想要的 doInBackground 方法。 return 值将是 onPostExecute 的输入参数。在那里你可以调用你想要的任何其他(可达)方法。请注意,您当时 运行 正在 UI 线程中。

漂亮又简单。让你的 AsyncTask return 成为一个值:

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

@Override
protected String doInBackground(String... params) {
//rest of code

return output.toString();
}
}

现在您所要做的就是在调用 .execute()

之后调用 .get() 方法
TestClass tc = new TestClass();
tc.execute();
String output = tc.get();

非常非常重要的注意事项

通过在 .execute() 之后立即调用 .get(),您的 UI 线程将被阻塞,直到 AsyncTask 完成。这有悖于 AsyncTask 的目的。此问题的解决方案之一是向 AsyncTask 添加一个回调接口,该接口将在完成时调用,并在该接口的实现中调用 .get() 方法。有关如何设计回调接口的示例,请参阅 here