将许多信息从服务器有效地保存到android

时间:2017-10-06 09:27:44

标签: android optimization download realm

我有一个应用程序,它从服务器执行许多文件下载,解码文件内容(json格式)并将其保存到realm数据库中。它是我们客户的实用程序,需要离线工作,因此必须存储大量信息。

为此,我有一个"同步"我执行所有网络查询的页面(20 +)。

我的问题是完整的操作大约需要5分钟,而我看到许多游戏下载500 + Mb的数据并且几乎可以存储它们。

我要发布最长的asyncTask,大约需要2分钟才能完成。

这是我的对象

public class Meter extends RealmObject {

  public Meter(){}

  @PrimaryKey
  private String ID;

  @Index
  private String MARCA;
  @Index
  private String MATRICOLA;

  private String NUMERO_CIFRE;
  private String DIAMETRO;
  private String SIGILLO;
  private String NUMERO_LOTTO;
  private String LUNGHEZZA;
  private String COEFFICIENTE;
  private String ID_ARTICOLO;
  private Item articolo;
  //...
}

我使用此asyncTask下载它:

public static class DownloadMetersAsyncTask extends AsyncTask<String, Integer, Boolean> {

    private String newSha;
    private GenericDbClassMethods genericDbClass;
    //asyncTaskItem is just an object keeping my file info to identify it on server side like file name
    private AsyncTaskSyncItem asyncTaskSyncItem;
    //this is an interface that I use for handling the start-update-finish events
    private IReturnFinishAndStatusToParent iReturnFinishAndStatusToParent;

    private synchronized void setProgress(int progress) {
        asyncTaskSyncItem.setProgress(progress);
        iReturnFinishAndStatusToParent.onProgressUpdate(progress);
    }

    public DownloadMetersAsyncTask(Context ctx, AsyncTaskSyncItem asyncTaskSyncItem, IReturnFinishAndStatusToParent iReturnFinishAndStatusToParent) {
        this.asyncTaskSyncItem = asyncTaskSyncItem;
        this.iReturnFinishAndStatusToParent = iReturnFinishAndStatusToParent;
        this.genericDbClass = new GenericDbClassMethods(ctx);
    }

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

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        setProgress(values[0]);
    }

    @Override
    protected Boolean doInBackground(String... params) {
        Realm realm = null;
        final boolean[] ok = {true};
        newSha = null;
        try {
            realm = Realm.getDefaultInstance();
            publishProgress(5);
            String url = "...";
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(600, TimeUnit.SECONDS)
                    .writeTimeout(600, TimeUnit.SECONDS)
                    .readTimeout(600, TimeUnit.SECONDS)
                    .retryOnConnectionFailure(true)
                    .build();
            publishProgress(10);
            Request request = new Request.Builder().url(url)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Connection", "close")
                    .build();
            publishProgress(15);
            Response response = client.newCall(request).execute();
            publishProgress(20);

            ResponseBody responseBody = response.body();
            publishProgress(25);
            try {
                String myHeader = response.header("Content-Disposition");
                if (myHeader != null) {
                    int position = myHeader.indexOf("filename=");
                    position += "filename=".length();
                    newSha = myHeader.substring(position);
                }
            } catch (Exception ex) {
                newSha = null;
            }
            if (responseBody == null) {
                return true;
            }
            final BufferedInputStream is = new BufferedInputStream(responseBody.byteStream());

            publishProgress(45);
            realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    try {
                        Log.d("SYNC", "Meter - start delete");
                        realm.delete(Meter.class);
                        Log.d("SYNC", "Meter - end delete, start create");
                        realm.createAllFromJson(Meter.class, is);

                        publishProgress(100, 1);
                        genericDbClass.setSHA(realm, new Meter(), newSha); //another stuff, really fast, can be removed
                    } catch (Exception error) {
                        error.printStackTrace();
                        newSha = null;

                        ok[0] = false;
                        publishProgress(100, 0);
                        publishProgress(75);
                    }
                }
            });
            is.close();
            response.close();

        } catch (IOException error) {
            newSha = null;
            publishProgress(100, 0);
        } finally {
            if (realm != null) {
                realm.close();
            }
        }
        return ok[0];
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void onPostExecute(Boolean v) {
        iReturnFinishAndStatusToParent.onFinish(v);
    }
}

此代码正常工作,问题是即使下载需要几秒钟,数据库插入也需要1-2分钟,这是很有用的。

我想知道是否有更好的方法来处理操作,例如执行insert async。

感谢您的建议

编辑,添加计时器(刚检查)

  • 不到1秒onPreExecute转到realm.createAllFromJson(Meter.class, is)(已排除)。
  • 执行realm.createAllFromJson(Meter.class, is) 需要3分50秒

0 个答案:

没有答案