2

我是一个开始提到我对 Android 完全陌生的人,我刚刚读完一本快速的介绍性书籍,现在我必须实现我的第一个应用程序。这个应用程序将用于接受订单。在我要存储在本地数据库中的所有数据中,有两个表是最重要的:Customers 和 Articles,后者是所有表中最大的(大约 20000 条记录)我的应用程序中的主要过程之一,获取当用户按下开始设备上的日常操作的按钮时,我的应用程序需要离线工作的所有数据。

好吧,该过程包括以下步骤:

一个。读取一个 RESTful 服务以检索客户数据
b. 解析对 Json 对象的响应
c。将这些客户插入客户表
d。读取一个 RESTful 服务以检索文章数据
e。解析对 Json Objects
f 的响应。将这些文章插入文章表

这是我计划做的:

  1. 编写一个帮助类来处理所有 HTTP GET 请求。然后在我需要下载所有客户和文章数据时调用这个类
  2. 由于所有这些过程可能需要很多时间,所以我需要在后台进行。因此,根据一些建议,我将把所有这些代码放在绑定服务中。
  3. 虽然所有这些长时间的处理都在后台进行,但我必须显示某种指示器(ProgressDialog)这就是我选择使用绑定服务的原因

虽然我认为我已经大致了解了如何分别完成大部分这些事情但我认为将所有这些放在一起是完全不同的故事。

所以这些是我现在得到的问题,我必须把这个谜题放在一起:

  1. 您认为我执行所描述过程的所有 6 个步骤的顺序是否正确/有效?如果你必须做出一些改变,你会改变什么?
  2. 如果启动服务的活动被显式取消或被另一个活动隐藏,则服务必须有办法让用户知道该过程已经完成。我怎么能实现呢?
  3. 是否可以/建议在服务中写入 SQLite DB?是否与我在活动中这样做时相同?
  4. 在 J2ME 中我做过类似的事情,当我把上面提到的 6 个步骤之类的东西放在一起时,它们都是按顺序执行的,也就是说,一个接一个。安卓也一样吗?

我希望我没有问太多问题。我只是把它们放在一起,因为它们都是相关的。

基本上在这个问题中,我不是要求工作代码(尽管如果你能提供一些示例代码就可以了)我真正想要的是一些建议,一些指导。诸如“嘿,我认为这可能会帮助您解决第 3 点”“您可能会发现这篇文章很有用”“我认为您最好使用这个而不是那个”。那种事。

我决定来找你,因为你是专家,我真的需要有人把我引向正确的方向。

非常感谢。

PS请不要关闭这个问题,如果您认为我需要更改某些内容,请告诉我,我会这样做。

4

3 回答 3

3

我决定来找你,因为你是专家

首先i am not experti am not knowledgeable您可以找到比我更多的专家,但这是我的意见 hope to give you some help

首先忘记使用AsyncTask下载,因为它必须用于不像你的短后台工作我认为你要下载的文件量很大。(我认为是这样)

检查downloadmanager谷歌,看看它是如何工作的,它可能会对你有所帮助。

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

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

如果您想使用serviceuseunbound service是因为您不希望该服务在用户关闭应用程序时被 android 或用户破坏,您呢?我认为您想以任何方式获取数据。

为了提高效率,我推荐以下步骤:

一个。读取一个安静的服务来检索客户数据

湾。当您获得客户数据时:

  • 创建另一个服务或线程来读取一个安静的服务来检索文章数据

  • 在旧服务或线程上解析对 Json 对象的响应

insert parse现在您有 2 个同时运行的服务或线程,因此请在每个服务或线程上遵循显而易见的步骤。

为什么我不把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)这就是我选择使用绑定服务的原因

如何从 Unbound Service 更新 UI?`

使用 a LocalBroadCastManager,或者一般来说BroadCastReciever

Android 从服务更新活动 UI

在 J2ME 中我做过类似的事情,当我把上面提到的 6 个步骤之类的东西放在一起时,它们都是按顺序执行的,也就是说,一个接一个。安卓也一样吗?

这取决于您的步骤,如果您按照我的想法运行concurrently,如果您运行您的想法,您将运行sequentially

祝你好运。

于 2014-09-02T05:46:09.913 回答
2

我做了类似你的事情。

在第一步中,我使用如下 方式从webservicePOST 方法的 HTTP GET 中获取数据: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);
}

我在我想从 web 服务获取数据的任何地方都在我的代码中调用 AsyncTask:

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

在第二步中,我在 onTaskComplete 方法中使用 json 帮助程序库(如Gsonor )解析 WebService 的响应Jackson。例如在杰克逊:

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

最后,我将数据存储在数据库中。用于连接到 DB 我更喜欢GreenDao用作我的 ORM。这样,DB中的存储数据可以在一行代码中完成,如下所示:

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

要使用GreenDaoORM ,此链接非常有用;

于 2014-09-01T05:08:51.593 回答
2

您认为我执行所描述过程的所有 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

步骤cf应结合在事务中。

否则,顺序无关紧要。如果数据不相关,那么分离这些进程并按顺序运行它们可能是一个好主意。


如果启动服务的活动被显式取消或被另一个活动隐藏,则服务必须有办法让用户知道该过程已经完成。我怎么能实现呢?

我建议从类的实现开始IntentService。它为您处理后台线程,并且像一个事件队列一样工作,其中单个Intent交付数据进行处理。

实际上,您可以实现 Google 在其IO 会议之一上提出的模式之一。我已经实现了视频中显示的选项 A。它对我很有用。诀窍是ContentProvider从后台使用自动更新 UI 来监听变化,这要归功于 CursorAdapter。

要更新 UI 进度,您可以使用LocalBroadcastManager事件总线库,例如Otto

您还可以扩展表格并存储状态和进度,更新表格也会自动更新 UI,请记住,这些更新应该很少见,例如在服务后台控制表格进度更新的频率首先计算进度并检查服务局部变量(如果已更改)。

如果您的应用在后台,请发布状态通知。用户应该能够通过单击通知导航回您的应用程序。


是否可以/建议在服务中写入 SQLite DB?是否与我在活动中这样做时相同?

您可以在服务中执行此操作。实际上,如果您遵循我上面提到的模式,您将在后台服务线程的处理器层中执行此操作。


在 J2ME 中我做过类似的事情,当我把上面提到的 6 个步骤之类的东西放在一起时,它们都是按顺序执行的,也就是说,一个接一个。安卓也一样吗?

与服务器的通信如何工作完全取决于您。如果您决定使用IntentService类,那么它将按顺序工作,这在 Android 上不是一个坏主意。另一方面,您可以直接扩展 Service 类并使用线程池实现自己的线程执行器。您还可IntentService以为不相关的操作设置专用类。


我还建议阅读课程:

如果您不想直接使用 HTTP 连接实现,请考虑使用RetrofitVolley

如果您只需要 JSON 解析器,那么这两个是最好的:

于 2014-09-02T09:26:09.983 回答