Android - 如何处理1000条记录SQLite

时间:2015-03-26 10:27:34

标签: android sqlite

我正在尝试在开始时在我的SQLite上添加1000条记录,但问题是,当我启动APP时,它会变成白色屏幕,然后是黑屏,直到它崩溃,当我输入5条记录时,它仍在执行与白色屏幕和黑色屏幕一样,但是当添加记录时,它会向我显示所有记录的祝酒词,所以它可以... 这是我的SQLiteBaseAdapter

public class ClientsSQL extends SQLiteOpenHelper {
// Declaramos la sentencia para crear la tabla
String sqlCreate = "CREATE TABLE Clients(NIF text,cognom1 text,cognom2 text,nom text)";



 public ClientsSQL(Context context, String name, SQLiteDatabase.CursorFactory factory,
                          int version) {
        super(context, name, factory, version);
        // TODO Auto-generated constructor stub
    }
    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(sqlCreate);
        db.execSQL("INSERT INTO Clients VALUES ('39410028B', 'hola1', 'Hola2', 'Jonathan')");
        Log.v("INFO1", "creating db");


    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        // Si existe la tabla, la borramos y la volvemos a crear.
       db.execSQL("DROP TABLE IF EXISTS Clients");
        db.execSQL(sqlCreate);
    }

我创建了一个插入作为测试,但是在我的MainActivity上,我做了这个:

public void crearRegistres(SQLiteDatabase db){

    int i;
    String dni ="";

    for (i = 0; i < 1000; i++) {

        dni = NumeroDNI();

        db.execSQL("INSERT INTO Clients VALUES ('" + dni + "'," + "'cognomA" + i + "'," + "'cognomB" + i + "',"+ "'nom" + i + "')");
    }
    Cursor c;
    c = db.rawQuery("Select NIF from Clients", null);


    Toast.makeText(MainActivity.this, Integer.toString(c.getCount()),
            Toast.LENGTH_LONG).show();
    c.close();
}

我尝试创建一个Async类,但是没有得到它,我如何调用doInBackGround()方法(如果这是正确的方法......)。

EDIT1

这是我尝试过的,但是在完成之前我什么也做不了。

  progress = ProgressDialog.show(getActivity(), "Cargando",
                        "Espere mientras cargan sus ofertas", true);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(2000);


                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        getActivity().runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                crearRegistres(db);
                                progress.dismiss();
                            }
                        });
                    }

                }).start();
            }

LogCat错误:

 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at android.os.Handler.<init>(Handler.java:200)
            at android.os.Handler.<init>(Handler.java:114)
            at android.widget.Toast$TN.<init>(Toast.java:327)
            at android.widget.Toast.<init>(Toast.java:92)
            at android.widget.Toast.makeText(Toast.java:241)
            at joancolmenero.com.practicabasedadesxmlthreads.MainActivity.NumeroDNI(MainActivity.java:111)
            at joancolmenero.com.practicabasedadesxmlthreads.MainActivity.crearRegistres(MainActivity.java:123)
            at joancolmenero.com.practicabasedadesxmlthreads.MainActivity$1.run(MainActivity.java:41)
            at java.lang.Thread.run(Thread.java:841)
03-26 11:49:20.436  21310-21310/joancolmenero.com.practicabasedadesxmlthreads E/WindowManager﹕ android.view.WindowLeaked: Activity joancolmenero.com.practicabasedadesxmlthreads.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{41f8f5b8 V.E..... R......D 0,0-684,324} that was originally added here
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:361)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.app.Dialog.show(Dialog.java:286)
            at android.app.ProgressDialog.show(ProgressDialog.java:116)
            at android.app.ProgressDialog.show(ProgressDialog.java:99)
            at joancolmenero.com.practicabasedadesxmlthreads.MainActivity.onCreate(MainActivity.java:29)
            at android.app.Activity.performCreate(Activity.java:5248)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2173)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269)
            at android.app.ActivityThread.access$800(ActivityThread.java:139)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5102)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

EDIT2

当我运行APP时,显示我的活动需要5或6秒钟,它会显示一个带有任何内容的白色屏幕......

public class MainActivity extends ActionBarActivity {
Button test;
    public SQLiteDatabase db;
    public ClientsSQL Conexion;
    ProgressDialog progress;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Conexion = new ClientsSQL(this, "Clients", null, 1);
        db = Conexion.getReadableDatabase();

        new MyAsyncTask().execute();



    public void crearRegistres(SQLiteDatabase db){

        int i;
        String dni ="";

        for (i = 0; i < 1000; i++) {

            dni = NumeroDNI();

            db.execSQL("INSERT INTO Clients VALUES ('" + dni + "'," + "'cognomA" + i + "'," + "'cognomB" + i + "',"+ "'nom" + i + "')");
        }
        Cursor c;
        c = db.rawQuery("Select NIF from Clients", null);



        c.close();
    }
    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
        private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);

        @Override
        protected void onPreExecute() {

            this.dialog.setMessage("Cargando DNI en SQLite");
            this.dialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            db.beginTransaction();

            try {
                crearRegistres(db);

                db.setTransactionSuccessful();
            } catch (Exception ignored) {

            } finally {
                db.endTransaction();
            }
            return null;
        }


        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Cursor c;
            c = db.rawQuery("Select NIF from Clients where NIF", null);
            Toast.makeText(MainActivity.this, Integer.toString(c.getCount()), Toast.LENGTH_LONG).show();
            c.close();
            this.dialog.dismiss();
        }
    }

}

3 个答案:

答案 0 :(得分:5)

使用AsyncTask。

要启动AsyncTask,将调用doInBackground方法:

 new MyAsyncTask().execute();

看一下doc http://developer.android.com/reference/android/os/AsyncTask.html

编辑2:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progress = ProgressDialog.show(getActivity(), "Cargando",
                            "Espere mientras cargan sus ofertas", true);
        }
        @Override
        protected Void doInBackground(Void... params) {
            crearRegistres(db);
            return null;
        }
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            progress.dismiss();
        }
    }

答案 1 :(得分:3)

使用Transaction插入您的数据。我只需将它放入Transaction

,就会从220秒开始插入16k行到8秒

This answer似乎已经足够了。

我还建议使用Futuroid(或类似的异步库)来执行异步操作。

快速交易示例:

try {
  db.beginTransaction();
  crearRegistres(db); 
  db.setTransactionSuccessful();
} catch (Exception ignored) { }
finally { db.endTransaction(); }

一个人使用Futuroid:

public Future<Boolean> insertRows(final SqliteDatabase db) {
    return Async.submit(new Callable<Boolean>() {
        @Override
        public Boolean call() {
            try {
                db.beginTransaction();
                crearRegistres(db);
                db.setTransactionSuccessful();
            } catch (Exception ignored) {
            } finally {
                db.endTransaction();
                return true;
            }
        }
    });
}

这就是您从活动中调用它的方式;

 insertRows(db).addCallback(new FutureCallback<Boolean>() {
                                   @Override
                                   public void onSuccess(Boolean boolean) {
                                       Log.i("SQLITE", "Data inserted");
                                   }

                                   @Override
                                   public void onFailure(Throwable t) {
                                       Log.e("SQLITE", "Unable to insert data ", t);
                                   }
                               }

    );

答案 2 :(得分:2)

您需要在后台线程上执行此操作。 AsyncTask也可以工作,但是如果你有任何其他AsyncTasks继续我会避免它,因为任务是在一个线程上循环完成的,这可以显着地保持它。