Skip to content

Commit 4206db8

Browse files
author
Paul Soucy
committed
added sqlitecursorloader, and a few string and io utilities
1 parent 3c467af commit 4206db8

10 files changed

Lines changed: 954 additions & 41 deletions

File tree

demo/.gitignore~

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/bin
2+
/gen
3+
/devsmartlib/bin
4+
/devsmartlib/gen
2.63 KB
Binary file not shown.
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright (c) 2011-2012 CommonsWare, LLC
3+
* portions Copyright (C) 2011 The Android Open Source Project
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.commonsware.cwac.loaderex;
19+
20+
import android.content.Context;
21+
import android.database.Cursor;
22+
import android.support.v4.content.AsyncTaskLoader;
23+
24+
abstract public class AbstractCursorLoader extends AsyncTaskLoader<Cursor> {
25+
abstract protected Cursor buildCursor();
26+
Cursor lastCursor=null;
27+
28+
public AbstractCursorLoader(Context context) {
29+
super(context);
30+
}
31+
32+
/**
33+
* Runs on a worker thread, loading in our data. Delegates
34+
* the real work to concrete subclass' buildCursor() method.
35+
*/
36+
@Override
37+
public Cursor loadInBackground() {
38+
Cursor cursor=buildCursor();
39+
40+
if (cursor!=null) {
41+
// Ensure the cursor window is filled
42+
cursor.getCount();
43+
}
44+
45+
return(cursor);
46+
}
47+
48+
/**
49+
* Runs on the UI thread, routing the results from the
50+
* background thread to whatever is using the Cursor
51+
* (e.g., a CursorAdapter).
52+
*/
53+
@Override
54+
public void deliverResult(Cursor cursor) {
55+
if (isReset()) {
56+
// An async query came in while the loader is stopped
57+
if (cursor!=null) {
58+
cursor.close();
59+
}
60+
61+
return;
62+
}
63+
64+
Cursor oldCursor=lastCursor;
65+
lastCursor=cursor;
66+
67+
if (isStarted()) {
68+
super.deliverResult(cursor);
69+
}
70+
71+
if (oldCursor!=null && oldCursor!=cursor && !oldCursor.isClosed()) {
72+
oldCursor.close();
73+
}
74+
}
75+
76+
/**
77+
* Starts an asynchronous load of the list data.
78+
* When the result is ready the callbacks will be called
79+
* on the UI thread. If a previous load has been completed
80+
* and is still valid the result may be passed to the
81+
* callbacks immediately.
82+
*
83+
* Must be called from the UI thread.
84+
*/
85+
@Override
86+
protected void onStartLoading() {
87+
if (lastCursor!=null) {
88+
deliverResult(lastCursor);
89+
}
90+
91+
if (takeContentChanged() || lastCursor==null) {
92+
forceLoad();
93+
}
94+
}
95+
96+
/**
97+
* Must be called from the UI thread, triggered by a
98+
* call to stopLoading().
99+
*/
100+
@Override
101+
protected void onStopLoading() {
102+
// Attempt to cancel the current load task if possible.
103+
cancelLoad();
104+
}
105+
106+
/**
107+
* Must be called from the UI thread, triggered by a
108+
* call to cancel(). Here, we make sure our Cursor
109+
* is closed, if it still exists and is not already closed.
110+
*/
111+
@Override
112+
public void onCanceled(Cursor cursor) {
113+
if (cursor!=null && !cursor.isClosed()) {
114+
cursor.close();
115+
}
116+
}
117+
118+
/**
119+
* Must be called from the UI thread, triggered by a
120+
* call to reset(). Here, we make sure our Cursor
121+
* is closed, if it still exists and is not already closed.
122+
*/
123+
@Override
124+
protected void onReset() {
125+
super.onReset();
126+
127+
// Ensure the loader is stopped
128+
onStopLoading();
129+
130+
if (lastCursor!=null && !lastCursor.isClosed()) {
131+
lastCursor.close();
132+
}
133+
134+
lastCursor=null;
135+
}
136+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* Copyright (c) 2012 -- CommonsWare, LLC
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
package com.commonsware.cwac.loaderex;
17+
18+
import android.os.AsyncTask;
19+
import android.support.v4.content.Loader;
20+
21+
public abstract class ContentChangingTask<T1, T2, T3> extends
22+
AsyncTask<T1, T2, T3> {
23+
private Loader<?> loader=null;
24+
25+
ContentChangingTask(Loader<?> loader) {
26+
this.loader=loader;
27+
}
28+
29+
@Override
30+
protected void onPostExecute(T3 param) {
31+
loader.onContentChanged();
32+
}
33+
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* Copyright (c) 2011-2012 CommonsWare, LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.commonsware.cwac.loaderex;
18+
19+
import java.io.FileDescriptor;
20+
import java.io.PrintWriter;
21+
import java.util.Arrays;
22+
import android.content.ContentValues;
23+
import android.content.Context;
24+
import android.database.Cursor;
25+
import android.database.sqlite.SQLiteDatabase;
26+
import android.database.sqlite.SQLiteOpenHelper;
27+
28+
public class SQLiteCursorLoader extends AbstractCursorLoader {
29+
SQLiteOpenHelper db=null;
30+
String rawQuery=null;
31+
String[] args=null;
32+
33+
/**
34+
* Creates a fully-specified SQLiteCursorLoader. See
35+
* {@link SQLiteDatabase#rawQuery(SQLiteDatabase, String, String[])
36+
* SQLiteDatabase.rawQuery()} for documentation on the
37+
* meaning of the parameters. These will be passed as-is
38+
* to that call.
39+
*/
40+
public SQLiteCursorLoader(Context context, SQLiteOpenHelper db,
41+
String rawQuery, String[] args) {
42+
super(context);
43+
this.db=db;
44+
this.rawQuery=rawQuery;
45+
this.args=args;
46+
}
47+
48+
/**
49+
* Runs on a worker thread and performs the actual
50+
* database query to retrieve the Cursor.
51+
*/
52+
@Override
53+
protected Cursor buildCursor() {
54+
return(db.getReadableDatabase().rawQuery(rawQuery, args));
55+
}
56+
57+
/**
58+
* Writes a semi-user-readable roster of contents to
59+
* supplied output.
60+
*/
61+
@Override
62+
public void dump(String prefix, FileDescriptor fd,
63+
PrintWriter writer, String[] args) {
64+
super.dump(prefix, fd, writer, args);
65+
writer.print(prefix);
66+
writer.print("rawQuery=");
67+
writer.println(rawQuery);
68+
writer.print(prefix);
69+
writer.print("args=");
70+
writer.println(Arrays.toString(args));
71+
}
72+
73+
public void insert(String table, String nullColumnHack,
74+
ContentValues values) {
75+
new InsertTask(this).execute(db, table, nullColumnHack, values);
76+
}
77+
78+
public void update(String table, ContentValues values,
79+
String whereClause, String[] whereArgs) {
80+
new UpdateTask(this).execute(db, table, values, whereClause,
81+
whereArgs);
82+
}
83+
84+
public void replace(String table, String nullColumnHack,
85+
ContentValues values) {
86+
new ReplaceTask(this).execute(db, table, nullColumnHack, values);
87+
}
88+
89+
public void delete(String table, String whereClause,
90+
String[] whereArgs) {
91+
new DeleteTask(this).execute(db, table, whereClause, whereArgs);
92+
}
93+
94+
public void execSQL(String sql, Object[] bindArgs) {
95+
new ExecSQLTask(this).execute(db, sql, bindArgs);
96+
}
97+
98+
private class InsertTask extends
99+
ContentChangingTask<Object, Void, Void> {
100+
InsertTask(SQLiteCursorLoader loader) {
101+
super(loader);
102+
}
103+
104+
@Override
105+
protected Void doInBackground(Object... params) {
106+
SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
107+
String table=(String)params[1];
108+
String nullColumnHack=(String)params[2];
109+
ContentValues values=(ContentValues)params[3];
110+
111+
db.getWritableDatabase().insert(table, nullColumnHack, values);
112+
113+
return(null);
114+
}
115+
}
116+
117+
private class UpdateTask extends
118+
ContentChangingTask<Object, Void, Void> {
119+
UpdateTask(SQLiteCursorLoader loader) {
120+
super(loader);
121+
}
122+
123+
@Override
124+
protected Void doInBackground(Object... params) {
125+
SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
126+
String table=(String)params[1];
127+
ContentValues values=(ContentValues)params[2];
128+
String where=(String)params[3];
129+
String[] whereParams=(String[])params[4];
130+
131+
db.getWritableDatabase()
132+
.update(table, values, where, whereParams);
133+
134+
return(null);
135+
}
136+
}
137+
138+
private class ReplaceTask extends
139+
ContentChangingTask<Object, Void, Void> {
140+
ReplaceTask(SQLiteCursorLoader loader) {
141+
super(loader);
142+
}
143+
144+
@Override
145+
protected Void doInBackground(Object... params) {
146+
SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
147+
String table=(String)params[1];
148+
String nullColumnHack=(String)params[2];
149+
ContentValues values=(ContentValues)params[3];
150+
151+
db.getWritableDatabase().replace(table, nullColumnHack, values);
152+
153+
return(null);
154+
}
155+
}
156+
157+
private class DeleteTask extends
158+
ContentChangingTask<Object, Void, Void> {
159+
DeleteTask(SQLiteCursorLoader loader) {
160+
super(loader);
161+
}
162+
163+
@Override
164+
protected Void doInBackground(Object... params) {
165+
SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
166+
String table=(String)params[1];
167+
String where=(String)params[2];
168+
String[] whereParams=(String[])params[3];
169+
170+
db.getWritableDatabase().delete(table, where, whereParams);
171+
172+
return(null);
173+
}
174+
}
175+
176+
private class ExecSQLTask extends
177+
ContentChangingTask<Object, Void, Void> {
178+
ExecSQLTask(SQLiteCursorLoader loader) {
179+
super(loader);
180+
}
181+
182+
@Override
183+
protected Void doInBackground(Object... params) {
184+
SQLiteOpenHelper db=(SQLiteOpenHelper)params[0];
185+
String sql=(String)params[1];
186+
Object[] bindParams=(Object[])params[2];
187+
188+
db.getWritableDatabase().execSQL(sql, bindParams);
189+
190+
return(null);
191+
}
192+
}
193+
}

0 commit comments

Comments
 (0)