将Loaders与返回对象的sqlite查询一起使用 [英] Using Loaders with sqlite query that returns object

查看:109
本文介绍了将Loaders与返回对象的sqlite查询一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这就是我从数据库中获取数据时一直在做的所有事情-我的片段将调用dbhelper,它将运行查询并将结果数据传递到对象中.

Here's what I've been doing all this while to get data from my database - my fragment will call a dbhelper which will run the query and pass the resulting data in an object.

我应该使用装载程序,以便不会在UI线程中进行查询,但是以前我不打扰,因为我的应用程序数据库很小.展望未来,这是一个坏主意,因为我的应用程序越来越大,数据库也越来越大.因此,现在我正在阅读有关Loader的所有信息,包括CursorLoader和自定义加载器,但是在我的应用程序中实现它仍然存在问题.

I should have used a loader so that the querying is not done in the UI thread, but previously I didn't bother since my app's database is very small. Moving forward, this was a bad idea since my app has grown larger and so do the database. So now I'm reading all I can about Loaders including CursorLoader and custom loaders, but I still have problem implementing it in my app.

所以这是我当前的代码(简化后,仅显示相关部分):

So here's my current code (simplified, just to show the relevant parts):

public class CategoryEdit extends Fragment{

private DbControl dbc;
private ObjectCategory objCategory;
private int categoryID = 3;
private EditText etName;

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        dbc = new DbControl(getActivity());
        try{
            dbc.open();
            objCategory = new ObjectCategory();
            objCategory = dbc.getCategoryData(categoryID);
            dbc.close();
        }catch (SQLException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

        etName.setText(objCategory.name);
    }
}

public class DbControl {

    public static final String FILE_NAME = "DbControl.java";
    private SQLiteDatabase database;
    private MySQLiteHelper dbHelper;

    public DbControl(Context context) {
        dbHelper = new MySQLiteHelper(context);
    }

    public void open() throws SQLException {
        database = dbHelper.getWritableDatabase();
    }

    public void close() {
        dbHelper.close();
    }

    public ObjectCategory getCategoryData(int itemID) throws Exception{
        ObjectCategory objCategory = new ObjectCategory();
        Cursor cursor = database.query(MySQLiteHelper.TABLE_CATEGORY, new String[] {"name"},
                "id = " + itemID, null, null, null, null);
        if (cursor!=null && cursor.getCount()>0 && cursor.moveToFirst()) {
            objCategory.name = cursor.getString(cursor.getColumnIndex("name"));
        }
        return objCategory;
    }
}

在我这里以正确的方式实现Loader的过程中,有人可以指出我的正确方向吗?如果可能的话,我不想过多地更改类DbControl中的代码-尤其是其中的函数的返回数据类型.

Can anyone point me in the right direction, in implementing Loader the right way in my case here? If possible, I don't want to alter the codes inside class DbControl too much - especially the return data type of the functions inside it.

在我已阅读的有关装载机的教程中,是:

Btw amongst the tutorials about loaders that I've read is:

  • http://www.recursiverobot.com/post/60331340133/very-simple-example-of-a-loader-and-loadermanager - but this was written more than 3 years ago and it uses Runnable to execute getSupportLoaderManager, and I've not seen other examples/tutorials that does this, so I'm afraid this article is outdated. Furthermore it uses CursorLoader, which from my understanding can only return cursor.
  • http://www.grokkingandroid.com/using-loaders-in-android/ - this seems to deal with CursorLoader too

无论如何,这是我到目前为止所做的:

Anyway here's what I've done so far:

public class CategoryEdit extends Fragment implements LoaderManager.LoaderCallbacks<ObjectCategory> {

@Override
    public Loader<ObjectCategory> onCreateLoader(int id, Bundle args){
        try{
            dbc.open();
            objCategory = new ObjectCategory();
            objCategory = dbc.getCategoryData(categoryID);
            dbc.close();
        }catch (SQLException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

        return objCategory; //this returns error, it says required Loader<ObjectCategory> instead of objCategory, but I'm not sure how to do that here
    }

@Override
    public void onLoadFinished(Loader<ObjectCategory> cursorLoader, ObjectCategory cursor) {
//Since onCreateLoader has error above, I'm not sure how to implement this part
    }

@Override
    public void onLoaderReset(Loader<ObjectCategory> cursorLoader) {
        //Can I just leave this empty?
    }
}

推荐答案

在我这里以正确的方式实施Loader时,有人能指出我正确的方向吗?

Can anyone point me in the right direction, in implementing Loader the right way in my case here?

您必须像这样使用AsyncTaskLoader:

You have to use an AsyncTaskLoader like this:

public class CategoryEdit extends Fragment implements LoaderManager.LoaderCallbacks<ObjectCategory> {

    @Override
    public Loader<ObjectCategory> onCreateLoader(int id, Bundle args) {
        return new AsyncTaskLoader<ObjectCategory>(getActivity()) {
            @Override
            public ObjectCategory loadInBackground() {
                try {
                    dbc.open();
                    objCategory = new ObjectCategory();
                    objCategory = dbc.getCategoryData(categoryID);
                    dbc.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return objCategory;
            }

            @Override
            protected void onStartLoading() {
                forceLoad();
            }
        };

    }

    @Override
    public void onLoadFinished(Loader<ObjectCategory> loader, ObjectCategory data) {
        //do some stuff here
    }

    @Override
    public void onLoaderReset(Loader<ObjectCategory> loader) {
        //Yes, you can leave it empty
    }
}

这篇关于将Loaders与返回对象的sqlite查询一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆