这个问题实际上曾多次被问过。我查看了9个问题(1,2,3,4,5,6,7,{ {3}},8)及其所有答案。它们都不起作用或与我的问题有关。
我将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]);
}
}
仅供参考,实际的http请求和API调用的结果为9。
当我运行它时,它会产生一个运行时错误(nullpointerexception),当调用onPosteExecute()时,我期望从doInBackground()
的结果填充的变量为空。当我在调试模式下查看执行时,我看到后台线程在doInBackground()
中的代码中途脱落并立即切换到onPostExecute()
中的UI线程。所以我需要用doInBackground()
的结果填充的变量不包含我需要的数据 - 因此运行时错误。
我查看here,很明显只有后台线程在doInBackground()上执行最后一行代码时,才会在UI线程上调用onPostExecute()。
所以我的问题是:为什么后台线程在开始执行doInBackground()
之前没有在onPostExecute()
内的代码块中执行所有内容?
答案 0 :(得分:1)
如果您的代码正常完成且没有错误,它将返回您之前明确定义的空数组(大小为3)。
您的Catch块返回null,因此很可能发生错误,您可以通过返回null来捕获然后处理。
在Catch bloack中放置一个断点并调查异常原因。