Я делаю простую заявку на место с API-интерфейсом Foursquare. В Activity у меня есть кнопка, которая при нажатии делает HTTP GET в AsyncTask для службы, чтобы занять трендовые места вокруг текущего местоположения пользователя. Если GET преуспевает, то к активности добавляется фрагмент, содержащий ListView с результатом.Android-тестирование - как синхронизировать AsyncTask
Я хочу проверить, создан ли Фрагмент после нажатия кнопки. Проблема в том, что AsyncTask работает в другом потоке, и тест заканчивается неудачным утверждением.
Вот код:
public void testBtnFindVenues_clickShouldInstantiateVenueListFragment() {
TouchUtils.clickView(this, this.btnFindVenues);
assertNotNull("VenueListFragment is null", this.getVenueListFragment());
}
private Fragment getVenueListFragment() {
FragmentManager fragmentManager = this.activity
.getSupportFragmentManager();
VenueListFragment venueListFragment = (VenueListFragment) fragmentManager
.findFragmentByTag(this.activity
.getString(R.string.fragment_tag_venue_list));
return venueListFragment;
}
Как я могу сделать утверждение будет выполняться после того, как AsyncTask выполняется
EDIT: Вот AsyncTask
protected class HttpGetJsonTask extends AsyncTask<Void, Void, ResponsePair> {
private String requestUrl;
private IOnSuccess onSuccess;
private IOnError onError;
public HttpGetJsonTask(String requestUrl) {
this.requestUrl = requestUrl;
}
public void setOnSuccess(IOnSuccess onSuccess) {
this.onSuccess = onSuccess;
}
public void setOnError(IOnError onError) {
this.onError = onError;
}
@Override
protected ResponsePair doInBackground(Void... params) {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(this.requestUrl);
get.addHeader("content-type", "application/json");
ResponsePair responsePair = new ResponsePair();
try {
HttpResponse response = client.execute(get);
String jsonData = HttpRequester.this
.getResponseContentAsString(response);
int statusCode = response.getStatusLine().getStatusCode();
responsePair.setJsonData(jsonData);
responsePair.setStatusCode(statusCode);
return responsePair;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return responsePair;
}
@Override
protected void onPostExecute(ResponsePair responsePair) {
super.onPostExecute(responsePair);
HttpRequester.this.executeEvents(this.onSuccess, this.onError,
responsePair);
}
}
private void executeEvents(IOnSuccess onSuccess, IOnError onError,
ResponsePair responsePair) {
String jsonData = responsePair.getJsonData();
int statusCode = responsePair.getStatusCode();
if (statusCode/100 == 4 || statusCode/100 == 5 || statusCode == 0) {
onError.performAction(jsonData);
} else {
onSuccess.performAction(jsonData);
}
}
private String getResponseContentAsString(HttpResponse response) {
String stringContent = null;
InputStream inputStream = null;
InputStreamReader reader = null;
BufferedReader bufferedReader = null;
try {
inputStream = response.getEntity().getContent();
reader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(reader);
StringBuilder stringContentBuilder = new StringBuilder();
String line = bufferedReader.readLine();
while (line != null) {
stringContentBuilder.append(line);
line = bufferedReader.readLine();
}
stringContent = stringContentBuilder.toString();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return stringContent;
}
Вот setUp для кнопки и транзакции из VenueListFragment
private void setUpBtnFindVenues() {
this.btnFindVenues = (Button) this.findViewById(R.id.btn_findVenues);
this.btnFindVenues.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!NetworkUtils
.isNetworkConnectionEnabled(VenueListActivity.this)) {
MessageNotifier.displayMessage(VenueListActivity.this,
R.string.toast_network_connection_not_found);
return;
}
IOnSuccess onSuccess = new IOnSuccess() {
@Override
public void performAction(String data) {
int index = data.indexOf("{\"venues\"");
data = data.substring(index, data.length() - 1);
Gson gson = new Gson();
ResponseModel response = gson.fromJson(data,
ResponseModel.class);
VenueListActivity.this.venues = response.getVenues();
if (VenueListActivity.this.venues.size() == 0) {
MessageNotifier.displayMessage(
VenueListActivity.this,
R.string.toast_not_venues_within_radius);
}
VenueListActivity.this
.setUpVenueList(VenueListActivity.this.venues);
}
};
IOnError onError = new IOnError() {
@Override
public void performAction(String data) {
MessageNotifier.displayMessage(VenueListActivity.this,
R.string.toast_problem_on_server);
}
};
// Get the user's location
Location location = VenueListActivity.this.locationTracker
.getLocation();
if (location == null) {
MessageNotifier.displayMessage(VenueListActivity.this,
R.string.toast_location_not_found);
} else {
// Build the route parameters HashMap
Map<String, String> routeParams = new HashMap<String, String>();
double latitude = location.getLatitude();
double longitude = location.getLongitude();
Log.d("denis", "Latitude: " + Double.toString(latitude));
Log.d("denis", "Longitude: " + Double.toString(longitude));
routeParams.put("ll",
String.format("%s,%s", latitude, longitude));
int radius = (VenueListActivity.this.seekBarRadius
.getProgress() + MIN_RADIUS) * SEEK_BAR_PROGRESS_MULTIPLIER;
routeParams.put("radius", Integer.toString(radius));
AppUtils.getData().venues()
.getTrendingVenues(routeParams, onSuccess, onError);
}
}
});
}
private void setUpVenueList(List<VenueModel> venues) {
Gson gson = new Gson();
Bundle arguments = new Bundle();
arguments.putBoolean(BundleKey.IS_TWO_PANE, this.isTwoPane);
arguments.putString(BundleKey.VENUES, gson.toJson(venues));
VenueListFragment fragment = new VenueListFragment();
fragment.setArguments(arguments);
FragmentManager fragmentManager = this.getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.frameLayout_venueListContainer, fragment,
this.getString(R.string.fragment_tag_venue_list));
transaction.commit();
}
Вот метод в DataUnitOfWork
public void getTrendingVenues(Map<String, String> routeParams,
IOnSuccess onSuccess, IOnError onError) {
if (!routeParams.containsKey("ll")) {
throw new IllegalArgumentException("The routeParams Map does not contain the \"ll\" route parameter (it is required)");
}
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(this.rootUrl);
urlBuilder.append(String.format("%s%s", "trending", MainPersister.CLIENT_ROUTE_PARAMS));
Set<String> keys = routeParams.keySet();
for (String key : keys) {
urlBuilder.append(String.format("&%s=%s", key, routeParams.get(key)));
}
HttpGetJsonTask get = new HttpGetJsonTask(urlBuilder.toString());
get.setOnSuccess(onSuccess);
get.setOnError(onError);
get.execute();
}
Я не знаю, для чего вам нужно утверждение. У меня складывается впечатление, что то, что вы хотите выполнить, больше связано с жизненным циклом фрагментов, чем с асинтезной. –
Ну, есть ли способ проверить Фрагмент? Я просто хочу проверить, правильно ли добавлен фрагмент в действие. –
Вы можете принять это как должное. Когда действие создает фрагмент и запрашивает его поместить в контейнер, вам не нужно проверять, удалось ли это сделать. Внутри фрагмента, чтобы начать заполнять данные, например, поместите код в методы onStart или onResume. Таким образом, он начнет свое поведение, когда он будет правильно активирован. –