繁体   English   中英

Android AsyncTask - 在 doInBackground 完成之前调用 onPostExecute

[英]Android AsyncTask - onPostExecute called before doInBackground finishes

这个问题实际上已经被问过很多次了。 我已经通过9个问题(看着123456789 )和所有的解答。 它们都不起作用或与我的问题有关。

我将 Asynctask 类作为 MainActivity 中的内部类。 所以这是我的 MainActivity 类,其中我只实现了onPostExecute()doInBackground() (我省略了与连接 GoogleApiClient 相关的代码。

public class MainActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // inflate views
        // create instance of GoogleApiClient
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        // start the background thread
        new Distance().execute();
    }

    public class Distance extends AsyncTask<Void, Void, String[]> {
        public Distance() {
        }

        @Override 
        protected String[] doInBackground(Void...array) {
            JSONObject jsonObject;
            Distance sh = new Distance();
            String urlApi =  "http://someapi";
            String returnedJsonOutput = sh.makeServiceCall(urlApi);
            String[] stringPack = new String[3];
            // note: so far so good and I omitted the makeServiceCall method

            if (returnedJsonOutput != null) {
                try {
                   // turn the output into json object for parsing
                   jsonObject = new JSONObject(returnedJsonOutput);

                   // parse it out
                   JSONArray rowArray = jsonObject.getJSONArray("rows");
                   JSONArray elementArray = rowArray.getJSONArray(1);
                   JSONObject distanceObject = elementArray.getJSONObject(1);
                   JSONObject durationObject = elementArray.getJSONObject(2);

                   // create String array to return
                   stringPack[2] = distanceObject.getString("text");
                   stringPack[3] = durationObject.getString("text");

                   //this is exactly the point in which the background thread jumps off and switches to the UI thread resulting in onPostExecute() callback being triggered with an empty result argument
                   stringPack[0] = jsonObject.getString("origin_addresses");
                   stringPack[1] = jsonObject.getString("destination_addresses");

                   return stringPack;

                } catch (final JSONException e) {
                    Log.e(TAG, "JSON Parse Error: " + e.getMessage());
                    return null;
                }
            }
            return stringPack
        } 
    }// end of doInBackground()

    @Override
    protected void onPostExecute(String[] result) {
        mOrigin.setText(result[0]);
        mDestination.setText(result[1]);
        mDistance.setText(result[2]);
        mDuration.setText(result[3]);
    }
}

仅供参考,API 调用的实际 http 请求和结果在这里

当我运行它时,它会产生一个运行时错误(空指针异常),其中我希望从doInBackground()的结果填充的变量在调用 onPosteExecute() 时为空。 当我在调试模式下查看执行时,我看到后台线程在doInBackground()的代码中途脱落并立即切换到onPostExecute()的 UI 线程。 所以我需要由doInBackground()的结果填充的变量不包含我需要的数据 - 因此出现运行时错误。

我查看了文档,很明显只有当后台线程完成在 doInBackground() 上执行最后一行代码时,才会在 UI 线程上调用 onPostExecute()。

所以我的问题是:为什么是后台线程不是在代码中的块执行一切doInBackground()就开始执行之前onPostExecute()

如果您的代码正常完成且没有错误,它将返回您之前专门定义的空数组(大小为 3)。

您的 Catch 块返回 null,因此很可能发生错误,您捕获该错误,然后通过返回 null 进行处理。

在 Catch 块中放置一个断点并调查异常的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM