Как использовать графику Facebook Api Cursor-based Pagination
Я не нашел никакой помощи по этой теме. Документы говорят
Пагуализация на основе курсора является наиболее эффективным методом подкачки и всегда должна использоваться там, где это возможно - курсор относится к случайной строке символов, которые помещают определенный элемент в список данных. Если этот элемент не будет удален, курсор всегда укажет на ту же часть списка, но он будет недействителен, если элемент будет удален. Поэтому ваше приложение не должно хранить старые курсоры или предположить, что они все равно будут действительны.
When reading an edge that supports cursor pagination, you will see the following JSON response:
{
"data": [
... Endpoint data is here
],
"paging": {
"cursors": {
"after": "MTAxNTExOTQ1MjAwNzI5NDE=",
"before": "NDMyNzQyODI3OTQw"
},
"previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
"next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
}
}
Я использую этот формат для вызова api, как я могу пройти через все страницы в цикле
/* make the API call */
new GraphRequest(
session,
"/{user-id}/statuses",
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
/* handle the result */
}
}
).executeAsync();
Ответы
Ответ 1
Я понял хороший способ пересечь страницы api facebook graph с использованием разбивки на страницы курсора
final String[] afterString = {""}; // will contain the next page cursor
final Boolean[] noData = {false}; // stop when there is no after cursor
do {
Bundle params = new Bundle();
params.putString("after", afterString[0]);
new GraphRequest(
accessToken,
personId + "/likes",
params,
HttpMethod.GET,
new GraphRequest.Callback() {
@Override
public void onCompleted(GraphResponse graphResponse) {
JSONObject jsonObject = graphResponse.getJSONObject();
try {
JSONArray jsonArray = jsonObject.getJSONArray("data");
// your code
if(!jsonObject.isNull("paging")) {
JSONObject paging = jsonObject.getJSONObject("paging");
JSONObject cursors = paging.getJSONObject("cursors");
if (!cursors.isNull("after"))
afterString[0] = cursors.getString("after");
else
noData[0] = true;
}
else
noData[0] = true;
} catch (JSONException e) {
e.printStackTrace();
}
}
}
).executeAndWait();
}
while(!noData[0] == true);
Ответ 2
Не изобретайте велосипед.
GraphResponse у класса уже есть удобный метод для подкачки. GraphResponse.getRequestForPagedResults()
возвращает объект GraphRequest
, и вы можете использовать этот объект для подкачки.
Также я нашел фрагмент кода из код facebook-android-sdk unit test.
GraphRequest nextRequest = response.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
nextRequest.setCallback(request.getCallback());
response = nextRequest.executeAndWait();
Ответ 3
Хотя верно, что вы должны использовать GraphResponse.getRequestForPagedResults()
, вы не можете использовать executeAndWait()
, если вы не запустите его в другом потоке.
Вы можете сделать это еще проще, используя executeAsync()
.
В получить первый набор результатов:
new GraphRequest(AccessToken.getCurrentAccessToken(),
"/" + facebookID + "/invitable_friends",
null,
HttpMethod.GET,
new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
//your code
//save the last GraphResponse you received
lastGraphResponse = response;
}
}
).executeAsync();
Используйте этот lastGraphResponse для , чтобы получить следующий набор результатов:
GraphRequest nextResultsRequests = lastGraphResponse.getRequestForPagedResults(GraphResponse.PagingDirection.NEXT);
if (nextResultsRequests != null) {
nextResultsRequests.setCallback(new GraphRequest.Callback() {
@Override
public void onCompleted(GraphResponse response) {
//your code
//save the last GraphResponse you received
lastGraphResponse = response;
}
});
nextResultsRequests.executeAsync();
}
Вы можете объединить все это одним способом!
Ответ 4
Я использую этот код:
final String[] afterString = {""};
final Boolean[] noData = {true};
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
do{
GraphRequest request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/me/likes",
new GraphRequest.Callback() {
@Override
public void onCompleted(GraphResponse response) {
// Insert your code here
JSONObject jsonObject = response.getJSONObject();
try{
if(jsonObject.length() > 1) {
JSONObject jsonFacebook = (JSONObject) new JSONTokener(jsonObject.toString()).nextValue();
JSONObject likes_paging = (JSONObject) new JSONTokener(jsonFacebook.getJSONObject("paging").toString()).nextValue();
ArrayList<String> likes = new ArrayList<String>();
for (int i = 0; i < jsonFacebook.getJSONArray("data").length(); i++) {
likes.add(jsonFacebook.getJSONArray("data").getJSONObject(i).getString("name"));
}
afterString[0] = (String) likes_paging.getJSONObject("cursors").get("after");
}else{
noData[0] = false;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("pretty", "0");
parameters.putString("limit", "100");
parameters.putString("after", afterString[0]);
request.setParameters(parameters);
request.executeAndWait();
}while(noData[0] == true);