#android #json #listview #api #rest
Хочу разобраться разобраться как правильно организовать REST-клиент. Есть API, которая по запросу выдает JSON объекты. Нужно построить список ListView(или лучше использовать RecyclerView?) из этих JSON. Как я это все делаю: public class MainActivity extends AppCompatActivity { private static final String API = "https://api.github.com"; ListView listView; UserAdapter adapter; DBHandler mDBhandler; int lastUserIDinList=0; //начальное кол-во пользователей в списке int initialAmountUsers=10; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDBhandler = new DBHandler(this); listView = (ListView) findViewById(R.id.listview); adapter = new UserAdapter(MainActivity.this, new ArrayList()); listView.setAdapter(adapter); new CountUserInDB().execute(); listView.setOnScrollListener(new EndlessScrollListener() { @Override public boolean onLoadMore(int page, int totalItemsCount) { loadUsers(1); return true; } }); } //получаем от API объекты, ждем коллбэк и запускаем AsyncTask запись в базу(в качестве параметра передаем список моделей) void loadUsers(int count){ RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(API).build(); GitAPI git = restAdapter.create(GitAPI.class); //полчаем от АПИ пользователей с ид больше lastUserIDinList. количество пользователей в ответе - count git.getNextUsers(lastUserIDinList, count, new Callback >() { @Override public void success(ArrayList gitHubUsers, Response response) { new WriteToDB().execute(gitHubUsers); } @Override public void failure(RetrofitError error) { Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show(); } }); } //get arralist of users and write it to db class WriteToDB extends AsyncTask ,Void,Integer> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Integer doInBackground(ArrayList ... params) { //заноси в таблицу всех пользователей полученных в коллбэке for(int i=0; i > { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected ArrayList doInBackground(Integer... params) { //читаем из базы всех пользователей, ид которых >= params[0] return mDBhandler.getUserFromID(params[0]); } @Override protected void onPostExecute(ArrayList userList) { super.onPostExecute(userList); new DisplayUserInListView().execute(userList); } } //get arralist of users and add it to adapter class DisplayUserInListView extends AsyncTask ,Void,Void> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground(ArrayList ... params) { //добавляем по очереди пользователей в адаптер for(int i=0; i { int lastUserIDinTable=-1; @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Integer doInBackground(Void... params) { //получаем ИД последней записи в таблице lastUserIDinTable=mDBhandler.getLastUseID(); //получаем количество пользователей в таблице return mDBhandler.getUserCount(); } @Override protected void onPostExecute(Integer userCount) { super.onPostExecute(userCount); if(userCount==0){ //база пуста, загрузим 10 пользователей для начала loadUsers(10); } if(userCount>=initialAmountUsers){ //в базе больше 10 пользователей, что достаточно для начала - читаем из базы. new ReadFromDB().execute(0); } if(userCount>0 && userCount Ответы
Ответ 1
Многократно уже отписывался на эту тему, как писать REST клиента. Не поленюсь написать еще раз: Через сервис тягаем JSON объекты из сети и складываем в SQLite БД Над SQLite БД создаем ContentProvider и через CursorLoader организуем подпитку CursorAdapter, который и будет адаптером для ListView или RecyclerView Вопрос выбора ListView или RecyclerView - это вопрос не только вкуса, но и квалификации (все таки). Как показывает опыт RecyclerView сложнее в понимании, но дает гораздо большую свободы в плане управления списком. Я бы рекомендовал начинать с ListView и только потом приступать к RecyclerView Для работы с JSon лучшим инструментом является Google Gson - берите его и даже не сомневайтесь. Функция Gson очень простая, но важная: это трансляция вашего Java объекта в Json строку и обратно. По сути вместо рутинного парсинга json строки вы будете иметь дело с интеллигентными Java классами. Часто при работе с Rest требуется реализация функциональности Pull-To-Refresh - ну то есть обновление списка при вытягивании вверх/вниз. В сети есть огромное количество реализаций Pull-To-Refresh. Я пользовался этим проектом - но он сейчас мертвый. Недавно в суппорт либах появился новый виджет: SwipeRefreshLayout я лично не пользовался не знаю как с ним работать. Те из знакомых кто пользовались - пищат от восторга. У меня нет оснований не доверять им. P.S. Для RecyclerView организовать CursorAdapter напрямую не получится, нужно будет применить эту наработку. Update Создавать сервис, в котором будут загружаться данные с API(), парситься, записываться в базу и потом передавать в активити сообщение, что надо обновить список. Активити как получит такое уведомление, с помощью CursorLoader'а грузит данные из таблицы и добавляет их адаптеру списка. В качестве сервиса подойдет IntentService, который можно запускать по таймеру и/или через событие генерируемое при Pull-To-Refresh Не надо никак уведомлять Activity о том, что БД изменилось - CursorLoader сам будет автоматом подгружать обновленные данные при изменении БД через соответствующий Observer (в случае RecyclerView), а в случае CursorAdapter это уже будет "из коробки"
Комментариев нет:
Отправить комментарий