Android usa CursorLoader para cargar datos SQLite de forma asincrónica

Use CursorLoader para cargar datos SQLite de forma asincrónica

Descargue el código fuente completo: http://download.csdn.net/detail/q296264785/9686676
Puntos de conocimiento:

1、对SQLite数据的操作。
    关于SQLite的使用:http://blog.csdn.net/q296264785/article/details/53155739

2、CursorLoader加载器异步加载数据
    同步加载数据的方法:http://blog.csdn.net/q296264785/article/details/53167961

3、内容提供者ContentProvider
    内容提供者详解:http://blog.csdn.net/q296264785/article/details/53158873

Las aplicaciones que usan cargadores deben incluir lo siguiente:

1. Una actividad o fragmento.
2. Una instancia de LoaderManager.
3. Un CursorLoader para cargar los datos devueltos por ContentProvider. Alternativamente, puede implementar su propia subclase Loader o AsyncTaskLoader para cargar datos de otros recursos
. Una implementación de LoaderManager.LoaderCallbacks. Aquí es donde crea nuevos cargadores y administra referencias a sus cargadores existentes.
4. Un cargador de pantalla Método de datos, como un SimpleCursorAdapter.
5. Una fuente de datos, como un ContentProvider, cuando usa un CursorLoader.
La ventaja de usar el cargador CursorLoader para cargar datos de forma asincrónica es evitar el bloqueo del subproceso de la interfaz de usuario cuando se consulta la base de datos sincrónicamente, y usar el patrón de diseño del observador para decirle al usuario (escucha) que cambie los datos cargados para lograr actualizaciones en tiempo real.

Efecto de demostración: el botón guardará los datos de los dos cuadros de entrada en el archivo de base de datos a través del proveedor de contenido y lo actualizará dinámicamente en ListView

Escriba una descripción de la imagen aquí

1. Durante el proceso de creación class_cursorloader_contentprovider_test, elija la versión anterior a 3.0, porque API11 actualiza la función del cargador.
Cree tres nuevas clases:
a. DBHelper hereda SQLiteOpenHelper y crea una base de datos.
b. MProvider hereda ContentProvider y opera proveedores de contenido.
c. test hereda AndroidTestCase, depuración de prueba unitaria y agrega datos a la base de datos, recuerde agregar la función de prueba unitaria en el archivo de manifiesto.

数据库的创建和ContentProvider前面有博文已经介绍过,本博文只贴源码,重点介绍异步加载器的使用。

Primero debe crear una base de datos para proporcionar datos para Listview. Creé una tabla de clase que contiene tres tipos de _pid, nombre, número. Y use el método de prueba unitaria para cargar algunos datos en la clase de tabla.
Escriba una descripción de la imagen aquí

Código fuente de creación de base de datos:


import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper {

    public DBHelper(Context context) {
        super(context, "mydb.db", null, 1);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        String sql = "create table class(_pid integer primary key autoincrement,name varchar(64),number varchar(64))";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

Código fuente de prueba de unidad:

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.test.AndroidTestCase;

public class test extends AndroidTestCase {
    public void create() {
        DBHelper dbHelper = new DBHelper(getContext());
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        ContentValues values = new ContentValues();
        values.put("name", "张利利");
         values.put("number", "12345");
        database.insert("class", null, values);
        values.put("name", "李提莫");
         values.put("number", "12345");
        database.insert("class", null, values);
        values.put("name", "王石说");
         values.put("number", "12345");
        database.insert("class", null, values);
        values.put("name", "赵六壳");
         values.put("number", "12345");
        database.insert("class", null, values);
        values.put("name", "郭撒大");
         values.put("number", "12345");
        database.insert("class", null, values);
        values.put("name", "刘䮻明");
         values.put("number", "12345");
        database.insert("class", null, values);
    }
}

Se resolvió el problema del origen de datos. A continuación, necesitamos crear una subclase de ContentProvider para modificar los datos de la base de datos. Esta columna solo necesita usar la búsqueda en la base de datos y aumentar las operaciones, por lo que solo debe reescribir la búsqueda y los datos nuevos. Método En esta clase, registramos un escucha. El papel del escucha es que cuando los datos cambian, el escucha retroalimentará la información al objeto que llamó al escucha.
cursor.setNotificationUri (contentResolver, uri); // Regístrese para escuchar

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class MProvider extends ContentProvider {
    private DBHelper dbHelper;
    private ContentResolver contentResolver;
    private static String str_Uri = "com.example.class_cursorloader_contentprovider_test.MProvider";
    private static final UriMatcher MATCHER = new UriMatcher(
            UriMatcher.NO_MATCH);
    static {
        MATCHER.addURI(str_Uri, "class", 1);
        MATCHER.addURI(str_Uri, "class/#", 2);
    }

    @Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        dbHelper = new DBHelper(getContext());
        contentResolver = getContext().getContentResolver();
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
        Cursor cursor = null;
        SQLiteDatabase sqLiteDatabase = dbHelper.getReadableDatabase();
        switch (MATCHER.match(uri)) {
        case 1:// 为1时代表查找全部
            cursor = sqLiteDatabase.query("class", projection, selection,
                    selectionArgs, null, null, sortOrder);
            break;
        case 2:
            long id = ContentUris.parseId(uri);// 截取获取uri的“id”
            String str = "_pid = " + id;
            if (selection != null && !selection.equals("")) {
                str += selection;
            }
            cursor = sqLiteDatabase.query("class", projection, str,
                    selectionArgs, null, null, sortOrder);
            break;
        }
        cursor.setNotificationUri(contentResolver, uri);//注册监听
        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub

        switch (MATCHER.match(uri)) {
        case 1:
            return "vnd.android.cursor.dir/class";// 多行操作
        case 2:
            return "vnd.android.cursor.item/class";// 单行操作
        }
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        Uri uri2 = null;
        switch (MATCHER.match(uri)) {
        case 1:
            SQLiteDatabase sqLiteDatabase = dbHelper.getReadableDatabase();
            long id = sqLiteDatabase.insert("class", null, values);
            uri2 = ContentUris.withAppendedId(uri, id); // 重组uri
            break;
        }
        contentResolver.notifyChange(uri, null);// 通知监听者数据改变
        return uri2;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

}

En la clase MainActivity, quiero que la clase MainActivity implemente LoaderCallbacks y devuelva un parámetro de cursor. Para mostrar los datos en listView, necesitamos un adaptador. Personalizamos un adaptador myAdapter para heredar BaseAdapter y escribimos un archivo de diseño XML para que el adaptador muestre las tres columnas en la tabla Clase.
Clase MainActivity

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity implements LoaderCallbacks<Cursor> {
    private myAdapter adapter;
    private ListView listView;
    private LoaderManager loaderManager;
    private EditText editText1;
    private EditText editText2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        loaderManager = getLoaderManager();
        listView = (ListView) findViewById(R.id.listview1);
        editText1 = (EditText) findViewById(R.id.editText1);// 工号
        editText2 = (EditText) findViewById(R.id.editText2);// 名字
        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Uri uri = Uri
                        .parse("content://com.example.class_cursorloader_contentprovider_test.MProvider/class");
                ContentResolver contentResolver = getContentResolver();
                ContentValues values = new ContentValues();
                values.put("name", editText2.getText().toString());
                values.put("number", editText1.getText().toString());
                contentResolver.insert(uri, values);//按键操作,将两个EditText中的数据传递给内容提供者保存到数据库
                loaderManager.restartLoader(1111, null, MainActivity.this);
            }
        });
        loaderManager.initLoader(1111, null, this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // TODO Auto-generated method stub
        CursorLoader loader = new CursorLoader(this);
        Uri uri = Uri
                .parse("content://com.example.class_cursorloader_contentprovider_test.MProvider/class");
        loader.setUri(uri);
        return loader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // TODO Auto-generated method stub
        List<List<String>> list = new ArrayList<List<String>>();
        while (data.moveToNext()) {
            List<String> data_list = new ArrayList<String>();
            data_list.add(data.getString(data.getColumnIndex("_pid")));
            data_list.add(data.getString(data.getColumnIndex("name")));
            data_list.add(data.getString(data.getColumnIndex("number")));
            list.add(data_list);
        }
        adapter = new myAdapter(list);
        listView.setAdapter(adapter);
        adapter.notifyDataSetChanged();// 通知数据有更新
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // TODO Auto-generated method stub

    }
//自定义适配器
    class myAdapter extends BaseAdapter {
        private List<List<String>> list;

        public myAdapter(List<List<String>> list) {
            // TODO Auto-generated constructor stub
            this.list = list;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View view = null;
            if (convertView == null) {
                view = LayoutInflater.from(MainActivity.this).inflate(
                        R.layout.list, null);

            } else {
                view = convertView;
            }
            TextView textView1 = (TextView) view
                    .findViewById(R.id.list_textView1);
            TextView textView2 = (TextView) view
                    .findViewById(R.id.list_textView2);
            TextView textView3 = (TextView) view
                    .findViewById(R.id.list_textView3);
            List<String> list1 = new ArrayList<String>();
            list1 = list.get(position);
            textView1.setText(list1.get(0));
            textView2.setText(list1.get(1));
            textView3.setText(list1.get(2));
            return view;
        }
    }
}


Publicado 34 artículos originales · Me gusta 10 · Visitas 30,000+

Supongo que te gusta

Origin blog.csdn.net/q296264785/article/details/53213681
Recomendado
Clasificación