【问题标题】:Return multiple values from AsyncTask/doInBackground and use it in other method从 AsyncTask/doInBackground 返回多个值并在其他方法中使用
【发布时间】:2016-07-24 01:27:30
【问题描述】:

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

 @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 的值。但是不明白怎么做,还是退货吧。我知道应该是返回值,或者使用final。

【问题讨论】:

  • 在 AsyncTask 类中实现 onPostExecute 方法 :) 顾名思义,一旦 doInBackground 完成执行,就会调用它。从 onPostExecute 调用您要调用的方法并将您在 onPostExecute 中收到的响应作为参数传递:) 就是这样:)
  • AsyncTask Android example的可能重复

标签: android methods android-asynctask return-value


【解决方案1】:

漂亮而简单。让你的 AsyncTask 返回一个值:

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。

【讨论】:

    【解决方案2】:

    雾

    只需在 AsyncTask 类中实现 onPostExecute :)

    例如:

    @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 怎么会有任何价值??? 你必须从 doInBackground 方法返回它 :)

    喜欢

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

    您是否注意到您的 doInBackground 签名伙伴有任何变化?是的,我从 Void 变成了 String :)

    通过编写 String 表示您在执行完 doInBackground 后将返回一个字符串给 onPostExecute :)

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

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

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

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

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

    【讨论】:

    • new GetClass(this).execute();使用它我可以执行并获得结果,但我如何只使用单个值?
    • 你这是什么意思??抱歉,我正确地回答了您的问题,您想将一个以上的值传递给 onPostExecute 吗?这就是你想要的???
    • 主要思想是分别获取值,我得到的不仅仅是显示完整的数据包。 1)基于这些值,我想将此数据发送到数据库 2)我想使用其中一些数据作为 url 的一部分,用户将被重定向到。
    • autotrader.co.uk/search/used/cars MAKE /postcode/bh153eb/radius/1500/onesearchad/used%2Cnearlynew%2Cnew/sort/default/page/1/searchcontext/default
    • 如果您想一次发送多个值,例如发送 make,model all at once 这里是您的完美答案:) stackoverflow.com/questions/11833978/… 如果您看到答案,您会看到他没有发送字符串对象,而是创建了他的自定义类的对象并将其转发给 OnPostExecute 就是这样:)
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      AsyncTask 具有三个(主要)方法,onPreExecute、doInBackground 和 onPostExecute。只有doInBackGround 在后台线程上运行,另外两个在UI 线程上运行。 (也有onProgressUpdate,这里就略过了)

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-18
        相关资源
        最近更新 更多