SQLite数据库具有用于在表中存储纬度和经度值的字段。邮件地址是在Add活动中从用户输入的。
在为输入地址提取LatLng对象的AsyncTask
中,数据库写操作是其doInBackground
方法的最后一个语句。然而,与预期相反,写入发生 BEFORE 响应的JSON解析,为lat和long 最初写入NULL值。
表前端的ListView
显示空的Lat和Long值,但刷新后的值为正确。焦点在JSON解析之前从Add活动反冲回来,这不是所需的行为。只有在表中填充了正确的LatLng后才能返回ListView
,直到显示不确定的进度条。这 IS 一切正常, 除了
ListView
返回其列表项的其他组件已正确填充。 问题是,如何强制数据库写入等待JSON解析完成?
希望对这种情况的详细解释就足够了。如果需要更多详细说明或代码,请提及。
非常感谢提前!
您的善意调查的相关伪代码:
AsyncTask扩展:
private class Geocode extends AsyncTask<String, Void, LatLng>
{
@Override
protected LatLng doInBackground(String...addressToGeocode)
{
int DELAY = 9000;
URL geoCodeURL;
String jsonResponse = null;
String geoCodeRequestURL = Contract.HTTPS_GOOGLE_GEOCODE_PRE_ADDRESS_URL
+ Uri.encode(addressToGeocode[0]);
// Get JSON response
try
{
geoCodeURL = new URL(geoCodeRequestURL);
URLConnection geoCodeURLConnection = geoCodeURL.openConnection();
BufferedReader responseReader = new BufferedReader(new InputStreamReader (geoCodeURLConnection.getInputStream()));
StringBuilder response = new StringBuilder();
int cp;
while((cp = responseReader.read()) != -1)
{
response.append((char)(cp));
}
jsonResponse = response.toString();
Thread.sleep(DELAY); // Force a delay, apparently not enough...
}
catch (relevantExceptions e)
{
Log.i(LOG_TAG, e.toString());
e.printStackTrace();
}
// Parse the LatLng from the JSON response
try
{
JSONObject responseObject = new JSONObject(jsonResponse);
double lat = ((JSONArray) responseObject
.get("results"))
.getJSONObject(0)
.getJSONObject("geometry")
.getJSONObject("location")
.getDouble("lat");
double lng = ((JSONArray) responseObject
.get("results"))
.getJSONObject(0)
.getJSONObject("geometry")
.getJSONObject("location")
.getDouble("lng");
addressLatLng = new LatLng(lat, lng);
object.setLat(lat);
objet.setLng(lng);
}
catch (JSONException e)
{
e.printStackTrace();
}
if (addressLatLng != null)
{
....
}
else
{
Toast.makeText(getApplicationContext(), "Unable to Geocode", Toast.LENGTH_SHORT).show();
}
// Write to the database
dbResult = dbHelper.commitRow(object);
return addressLatLng;
}
@Override
protected void onPreExecute()
{
setProgressBarIndeterminate(true);
setProgressBarIndeterminateVisibility(true);
}
@Override
protected void onPostExecute(LatLng addressLatLng)
{
setProgressBarIndeterminateVisibility(false);
}
} // of getLatLong()
实例化AsyncTask的Add活动中的相关代码:
String addressToGeocode = address +
" " +
city +
country;
AsyncTask<String, Void, LatLng> geocodeTask = new Geocode();
geocodeTask.execute(addressToGeocode);
添加活动由ListView
活动调用,如下所示:
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
int itemId = item.getItemId();
switch (itemId)
{
case (R.id.action_menu_add):
{
Intent addIntent = new Intent(this, AddActivity.class);
startActivityForResult(addIntent, Contract.ADD_REQUEST_CODE);
return true;
}
default:
return false;
}
} // of onOptionsItemSelected()
ListView
&#39; onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
Bundle b = data.getBundleExtra(GlobeShopperContract.NEW_BUNDLE);
MyObject d = (MyObject) b.get(Contract.NEW_BUNDLE_NAME);
collection.add(d);
dViewAdapter.setNotifyOnChange(true);
dViewAdapter.notifyDataSetChanged();
}
else
...
}