Android SQLite查询导致许多跳过的帧

时间:2016-01-14 13:17:34

标签: android multithreading performance sqlite retrofit

我正在进行一些改装调用,4确切地说,并且在每个调用中我都将它的结果存储到SQLite数据库中,我的问题是,这些存储查询有通常大约有800个条目保存到数据库中,因此需要几秒钟才能使应用程序跳过大约300帧。

所以我搜索过并发现改装调用是在另一个线程中进行的,但它是onResponse,而onFailure是由主线程处理的。

我担心如果我在同一时间运行4个asyncTasks,它会以同样的方式让应用程序变慢,我是对的吗?另外,因为在Sqlite查询结束时,我执行测试以确定这是否是最后一个查询并显示成功消息。有什么建议吗?

最终工作代码:

Call<List<Cadastro>> callCadastro = cadastroApi.getCadastro(token);
callCadastro.enqueue(new Callback<List<Cadastro>>() {
@Override
public void onResponse(Response<List<Cadastro>> response, Retrofit retrofit) {

    final List<Cadastro> cadastroList = response.body();

        if (cadastroList != null) {

            class CadastroAsyncTask extends AsyncTask<Void, Void, Integer> {

                @Override
                protected Integer doInBackground(Void... params) {

                    try {

                        RepositorioCadastro repositorioCadastro = new RepositorioCadastro(conn);

                        // Insere cada item da lista no Banco de dados
                        for (Cadastro c : cadastroList) {

                            repositorioCadastro.inserirCadastro(c);

                            // Log.i("ACTTOKEN", "Cadastro inserido ID: " + c.getId());

                        }

                    } catch (SQLiteException e) {

                        Log.i("ACTTOKEN", "Erro ao inserir Cadastro(s) no banco de dados local: " + e.getMessage());

                    }

                    return null;
                }

                @Override
                protected void onPostExecute(Integer integer) {

                    // Incrementa o contador para verificar se abre ou não a caixa de dialogo de sucesso
                    contador++;

                    if (contador == 4) {

                        //Aumenta o progresso da janela de Dialogo
                        progressDialog.incrementProgress(28);
                        Log.i("CONTADOR", "Contador Cadastros: " + contador);
                        progressDialog.dismiss();// Dispensa a barra de progresso
                        // Janela de dialogo que abre a activity login
                        MessageBox.showAlertToken(TokenActivity.this, "Sincronizado com sucesso", "Pressione OK para continuar");

                    } else {
                        //Aumenta o progresso da janela de Dialogo
                        progressDialog.incrementProgress(28);
                        contador++;
                        Log.i("CONTADOR", "Contador Cadastros else: " + contador);

                    }
                }
            }

            // Executa a asyncTask
            new CadastroAsyncTask().execute();

        }

    }

    @Override
    public void onFailure(Throwable t) {

        Log.i("ACTTOKEN", "Erro retrofit ao baixar Cadastros: " + t.getMessage());

    }

});

上一个代码:

Call<List<Cadastro>> callCadastro = cadastroApi.getCadastro(token);
callCadastro.enqueue(new Callback<List<Cadastro>>() {
@Override
public void onResponse(Response<List<Cadastro>> response, Retrofit retrofit) {

    List<Cadastro> cadastroList = response.body();

        if (cadastroList != null) {

            try {

                RepositorioCadastro repositorioCadastro = new RepositorioCadastro(conn);

                    // Inserts each item of the list in the sqlite database
                    for (Cadastro c : cadastroList) {

                        repositorioCadastro.inserirCadastro(c);

                    }

                } catch (SQLiteException e) {

                     // On Sqlite Failure
                     Log.i("ACTTOKEN", "Erro ao inserir Cadastro(s) no banco de dados local: " + e.getMessage());

                } finally {

                    // Increments the counter to test if it is the last query to finish
                    contador++;

                    if (contador == 4) {

                        // If is the last query to finish, opens the message box

                        //Increases the progress in a MaterialDialog progressDialog
                        progressDialog.incrementProgress(28);
                        Log.i("CONTADOR", "Contador Cadastros: " + contador);
                        progressDialog.dismiss();// Dispensa a barra de progresso
                        // When click OK in the message box, start a new activity
                        MessageBox.showAlertToken(TokenActivity.this, "Sincronizado com sucesso", "Pressione OK para continuar");

                    } else {
                        //Increases the progress in a MaterialDialog progressDialog
                        progressDialog.incrementProgress(28);
                        contador++;
                        Log.i("CONTADOR", "Contador Cadastros else: " + contador);

                    }
                }

        }

}

@Override
// On Retrofit Failure
public void onFailure(Throwable t) {

    Log.i("ACTTOKEN", "Erro retrofit ao baixar Cadastros: " + t.getMessage());

}
});

1 个答案:

答案 0 :(得分:2)

  

我担心如果我在同一时间运行4个asyncTasks,它会以同样的方式变慢,我是对的吗?

你错了。如果您在UI线程或任何其他线程中执行数据库工作,则完全不同: 如果您不在UI线程上执行此操作,您的应用程序将保持响应。您的用户可以使用您的应用。 如果您在UI线程上执行此操作,则将跳过帧。在此期间,您的用户将无法使用您的应用 在没有响应的UI 5秒后,系统甚至会向用户显示ANR(应用程序未响应)消息,要求他退出应用程序。

您建议使用Asynctask。这应该是正确的方法,请尝试一下。 您可以在“doInBackground”和contador内处理您的计数器(publishProgress)。 {}}和Asynctask.onProgressUpdate都在UI线程上运行,因此您可以在此安全地更新您的用户界面并通知您的用户。