Рекомендуемый способ/порядок чтения данных из веб-службы, анализ этих данных и их вставка в SQLite db

Я должен начать упоминать, что я совершенно новичок в Android, я только что закончил читать краткую, вводную книгу, и теперь мне нужно реализовать свое первое приложение. Это приложение будет использоваться для выполнения заказов. Среди всех данных, которые я собираюсь хранить в локальном db, наиболее важны две таблицы: клиенты и статьи, являющиеся последней самой большой из всех таблиц (aprox 20000 records) Один из основных процессов в моем приложении, извлекает все данные, которые мое приложение должно работать в автономном режиме, когда пользователь нажимает кнопку, которая запускает ежедневные операции на устройстве.

Ну, процесс состоит из следующих шагов:

а. Прочтите сервис для восстановления данных клиентов
 б. Разберите ответ на объекты Json
 с. Вставьте этих клиентов в таблицу клиентов
 д. Прочтите резервное обслуживание для получения данных статей
 е. Разберите ответ на объекты Json
 е. Вставьте эти статьи в таблицу статей.

Это то, что я планировал сделать:

  • Напишите класс-помощник, который обрабатывает все HTTP-запросы GET. Затем вызовите этот класс всякий раз, когда мне нужно загрузить все данные Customers и Articles.
  • Поскольку весь этот процесс может занять много времени, мне нужно сделать это в фоновом режиме. Поэтому, основываясь на некоторых предложениях, я собираюсь поместить весь этот код в Bound Service.
  • Пока вся эта длительная обработка происходит в фоновом режиме, мне нужно будет показать какой-то индикатор (ProgressDialog). Именно по этой причине я решил использовать Bound Service

Хотя я думаю, что у меня есть общее представление о том, как делать большую часть этой вещи отдельно, я думаю, что объединение всех - совсем другая история.

Итак, вот те вопросы, которые у меня есть, что мне нужно собрать головоломки:

  • Как вы думаете, порядок, в котором я выполняю все 6 шагов описанного процесса, является правильным/эффективным? Если бы вам пришлось внести некоторые изменения, что бы вы изменили?
  • Если действие, которое запустило службу, явно отменено или скрыто другим действием, служба должна иметь возможность сообщить пользователю, что процесс завершен. Как я мог реализовать это?
  • Возможно ли/рекомендуется писать в SQLite DB внутри службы? Это то же самое, что когда я делаю это в рамках деятельности?
  • В J2ME я сделал что-то подобное, и когда я помещал что-то вроде 6 шагов, о которых я говорил выше, все они выполняются последовательно, то есть один за другим. Это то же самое в Android?

Надеюсь, я не задаю слишком много вопросов. Я просто собрал их, потому что они все связаны.

В основном в этом вопросе я не прошу работать с рабочим кодом (хотя было бы хорошо, если бы вы могли предоставить примерный код). Я действительно нахожусь в некоторых предложениях, некоторые рекомендации. Что-то вроде "Эй, я думаю, это может помочь вам с номером 3" или "Вы можете найти эту статью полезной", "Я думаю, вам лучше использовать это вместо этого". Такого рода вещи.

Я решил приехать к вам, потому что вы эксперты, и мне действительно нужно, чтобы кто-то поставил меня в правильном направлении.

Большое спасибо.

P.S. Пожалуйста, не закрывайте этот вопрос, если вы думаете, что мне нужно что-то изменить, просто дайте мне знать, и я это сделаю.

Ответ 1

Я решил приехать к вам, потому что вы эксперты

сначала i am not expert, а также i am not knowledgeable вы можете найти больше экспертов, чем меня, но это мое мнение hope to give you some help.

прежде всего забудьте использовать AsyncTask для загрузки, потому что он должен использоваться для коротких фоновых заданий, не похожих на ваши, я думаю, что количество файлов, которые вы хотите загрузить, довольно велико. (я так думаю)

проверьте downloadmanager Google, чтобы узнать, как он работает, он может вам помочь.

http://developer.android.com/reference/android/app/DownloadManager.html

http://blog.vogella.com/2011/06/14/android-downloadmanager-example/

если вы хотите использовать service использовать unbound service, потому что вы не хотите, чтобы служба была уничтожена андроидом или пользователем, когда пользователь закрывает приложения? Я думаю, вы хотите получить свои данные в любом случае.

чтобы быть эффективными, я рекомендую следующие шаги:

а. Прочтите резервную службу для извлечения данных клиентов.

б. когда вы получаете данные клиента:

  • создать другую службу или поток для чтения службы восстановления для получения данных статей

  • Разберите ответ на объекты Json на своей старой службе или потоке

теперь у вас есть 2 службы или потоки, которые работают одновременно, поэтому следуйте шагам, которые очевидны insert parse, и поэтому на каждой службе или потоке.

Почему бы мне не объединить a и d? потому что я думаю, что пользователь не любит ждать много времени за панель выполнения загрузки.

чтобы вставить ваши данные в базу данных transaction, и я рекомендую вам использовать:

http://greendao-orm.com/

он эффективнее ORM, чем другие для базы данных, и вы освобождаетесь от реализации db.

Если действие, которое запустило службу, явно отменено или скрыто другим действием, служба должна иметь возможность сообщить пользователю, что процесс завершен. Как я мог реализовать это?

использовать уведомление:

http://developer.android.com/training/notify-user/build-notification.html

http://www.tutorialspoint.com/android/android_notifications.htm

http://www.vogella.com/tutorials/AndroidNotifications/article.html

Пока вся эта длинная обработка происходит в фоновом режиме, мне нужно будет показать какой-то индикатор (ProgressDialog). Именно по этой причине я решил использовать Bound Service

как я могу обновить пользовательский интерфейс из несвязанной службы?

Используйте LocalBroadCastManager или вообще BroadCastReciever

Пользовательский интерфейс активности Android для Android

В J2ME я сделал что-то подобное, и когда я помещал что-то вроде 6 шагов, о которых я упоминал выше, все они выполняются последовательно, то есть один за другим. Это то же самое в Android?

это зависит от ваших шагов, если вы будете следовать моей идее, вы запустите concurrently, и если вы запустите свою идею, вы запустите sequentially.

Удачи.

Ответ 2

Я сделал что-то вроде твоего.

На первом этапе я получаю данные из webservice в HTTP GET метода POST, используя AsyncTask следующим образом:

public class GetService extends AsyncTask<String, String, String> {

private String mRestUrl;
private ServiceCallback mCallback;
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String url;
private String Error;
private ProgressDialog barProgressDialog;
private ProgressDialog Dialog;

public GetService(String restUrl, ServiceCallback callback) {
    this.mRestUrl = restUrl;
    this.mCallback = callback;
    this.url = restUrl;
    Dialog = new ProgressDialog(AppContext.CurrentContext);
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... urls) {

    Content = null;

    BufferedReader reader = null;

    try {

        StringBuilder builder = new StringBuilder();

        HttpClient client = new DefaultHttpClient();

        HttpGet get = new HttpGet(this.url);

        HttpResponse response = client.execute(get);
        int status = response.getStatusLine().getStatusCode();

        if (status == 200) // sucess
        {
            HttpEntity e = response.getEntity();
            // String data = EntityUtils.toString(e);
            InputStream content = e.getContent();
            reader = new BufferedReader(new InputStreamReader(content));

            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }

            Content = builder.toString();
        } else if (status == 401) {
            return "-Auth Failed Error Code 400";
        } else {
            return "-Error Code: " + status;
        }

    } catch (Exception ex) {
        Error = ex.getMessage();
    } finally {
        Dialog.dismiss();
        try {
            reader.close();
        }

        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    return Content;

}

@Override
protected void onPostExecute(String result) {
    try {
        GetService.this.get(20000, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (TimeoutException e) {
        e.printStackTrace();
    }
    mCallback.onTaskComplete(result);
    super.onPostExecute(result);
}
}

и мой класс обратного вызова:
  открытый абстрактный класс ServiceCallback {

public abstract void onTaskComplete(String result);
}

Я вызываю AsyncTask в свой код всюду, я хочу получать данные из webservice:

 new GetService(url, new ServiceCallback() {
                public void onTaskComplete(String response) {
                       // Parse Response of WebService
                }
            }).execute();

На втором шаге выполните парсинг-ответ WebService в методе onTaskComplete с использованием json-хелпер-библиотек, таких как Gson или Jackson. например, в джексоне:

List<YourClass> data = new ObjectMapper()
                .readValue(
                        response,
                        new TypeReference<List<YourClass>>() {
                        });

В конце я храню данные в базе данных. для подключения к БД я Предпочитаю использовать GreenDao как мой ORM. Таким образом, данные хранилища в БД могут выполняться одним строковым кодом следующим образом:

//after converting json to object
YourORMDaoClass.insertOrReplaceInTx(data);

Использовать GreenDao ORM эта ссылка очень полезна;

Ответ 3

Как вы думаете, порядок, в котором я выполняю все 6 шагов описанный процесс является правильным/эффективным? Если вам нужно сделать некоторые изменения, что бы вы изменили?

Это зависит. Если эти данные связаны и не могут существовать друг без друга, вы должны изменить порядок следующим образом:

a. Read a restful service to retrieve the Customers Data
b. Parse the response to Json Objects
d. Read a restful service to retrieve the Articles Data
e. Parse the response to Json Objects
c. Insert those customers to the Customers Table
f. Insert those articles to the Articles Table

Шаги c и f должны быть объединены в транзакции.

В противном случае порядок не имеет значения. Если данные не связаны, то разделение этих процессов и их выполнение в последовательности может быть хорошей идеей.


Если действие, которое запустило службу, явно отменено или спрятанная другой деятельностью, служба должна иметь возможность пользователь знает, что процесс завершен. Как я мог реализовать это?

Я предлагаю начать с реализации класса IntentService. Он обрабатывает фоновый поток и работает как очередь событий, где одиночный Intent предоставляет обрабатываемые данные.

На самом деле вы можете реализовать один из шаблонов, представленных Google, на одной из своих конференций IO. Я внедрил вариант A, показанный на видео. Это работает для меня очень хорошо. Фокус в том, что с помощью ContentProvider с фона автоматически обновляется пользовательский интерфейс, который прослушивает изменения благодаря CursorAdapter.

Чтобы обновить прогресс пользовательского интерфейса, вы можете использовать библиотеки LocalBroadcastManager или библиотеки событий, например. Otto.

Вы также можете расширить свои таблицы и сохранить статус и прогресс, обновление таблиц также будет автоматически обновлять пользовательский интерфейс, просто имейте в виду, что эти обновления должны быть редкими, например. контроль на фоне обслуживания, как часто обновляется таблица, вычисляя сначала прогресс и проверяя локальную переменную службы, если она изменилась.

Если ваше приложение находится в фоновом режиме, опубликуйте статус notification. Пользователь должен иметь возможность вернуться к вашему приложению, нажав на уведомление.


Возможно ли/рекомендуется писать в SQLite DB в оказание услуг? Это то же самое, что когда я делаю это в рамках действия?

Вы можете сделать это в Сервисе. На самом деле, если вы будете следовать шаблону, о котором я упомянул выше, вы бы сделали это в Уровне Процессора в потоке службы фона.


В J2ME я сделал что-то подобное, и когда я положил что-то вроде 6 шагов, о которых я говорил выше, все они выполняются последовательно, что есть, один за другим. Это то же самое в Android?

Это полностью зависит от вас, как будет работать связь с сервером. Если вы решите использовать класс IntentService, то он будет работать в последовательности, которая не является плохой идеей на Android. С другой стороны, вы можете напрямую расширить класс обслуживания и реализовать собственный исполнитель потока с пулом потоков. Вы также можете иметь выделенные классы IntentService для несвязанных операций.


Я также рекомендую читать уроки:

Если вы не хотите играть напрямую с реализацией HTTP-соединения, подумайте об использовании Retrofit или Volley

Если вам просто нужны синтаксические анализаторы JSON, то эти 2 являются лучшими: