我有计数器应用,我使用了SimpleCursorAdapter
,ListView
和StartManagingCursor()
。现在我想使用新的CursorLoader
和Contentprovider
。我编写了自己的ContentProvider
并在MainActivity
上实现了它。正如你可以看到我上面的应用程序,当我点击加号按钮并更新计数时,它是滞后的。我每秒大约做2次点击,但它无法快速处理。我使用ContentResolver
进行更新。
旧方法startManagingCursor
很快。
代码就在这里,如果我在ContentProvider
或CursorLoader
上有任何错误,请帮助我。
MAIN.java
public class Main extends ActionBarActivity implements LoaderCallbacks<Cursor> {
Cursor cursor;
String[] FROM = { Database.C_NAME, Database.C_VALUE };// get values from db
int[] TO = { R.id.textMainName, R.id.textMainValue };// set values of item
SimpleCursorAdapter adapter;
boolean clickP;
boolean clickN;
boolean clickR;
String Lng;
private static final int URL_LOADER = 0;
private ListView mListView;
private ChannelAdapter mAdapter ;
ContentResolver cr ;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mListView = (ListView) findViewById(R.id.list);
mAdapter =new ChannelAdapter(this, R.layout.list_item,null, FROM, TO,0);
mListView.setAdapter(mAdapter);
getSupportLoaderManager().initLoader(URL_LOADER, null, this);
registerForContextMenu(mListView);
}
@Override
protected void onResume() {
getSupportLoaderManager().restartLoader(0, null, this); }
public class ChannelAdapter extends SimpleCursorAdapter {
@SuppressWarnings("deprecation")
public ChannelAdapter(Context context, int layout, Cursor c,
String[] from, int[] to,int flag) {
super(context, layout, c, from, to, flag);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, parent, false);
Button bP = (Button) convertView.findViewById(R.id.buttonMainPlus);
final TextView tvName = (TextView) convertView.findViewById(R.id.textMainName);
final TextView tvValue = (TextView) convertView.findViewById(R.id.textMainValue);
// When plus button is clicked
bP.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int valuer = Integer.parseInt(tvValue.getText().toString());
ContentValues updatedValues = new ContentValues();
updatedValues.put(Database.C_VALUE,valuer+1);
//Uri rowURI =ContentUris.withAppendedId(MyContentProvider.CONTENT_URI,hoardId);
// Specify a specific row so no selection clause is required.
String where = Database.C_NAME+ " = '" + tvName.getText().toString() + "'" ;
String whereArgs[] = null;
// Get the Content Resolver.
cr = getContentResolver();
// Update the specified row.
int updatedRowCount = cr.update(MyContentProvider.CONTENT_URI, updatedValues, where, whereArgs);
}
});
return super.getView(position, convertView, parent);
}
}
@Override
public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) {
switch (loaderID) {
case URL_LOADER:
return new CursorLoader(Main.this,MyContentProvider.CONTENT_URI,null,null,null,null);
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mAdapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
mAdapter.swapCursor(null);
}
}
MyContentProvider.java
public class MyContentProvider extends ContentProvider{
// database
private Database database;
private static final int ALL_ROWS = 1;
private static final int SINGLE_ROW= 2;
public static final String KEY_ID = "_id";
private static final String AUTHORITY = "com.example.counter.contentprovider";
private static final String BASE_PATH = "list";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);//uri
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE+ "/todos";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/todo";
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, BASE_PATH, ALL_ROWS);
sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", SINGLE_ROW);
}
@Override
public boolean onCreate() {
database = new Database(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
database.openDb();
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
int uriType =sURIMatcher.match(uri);
switch (uriType) {
case SINGLE_ROW:
String rowID = uri.getPathSegments().get(1);
queryBuilder.appendWhere(KEY_ID + "=" + rowID);
default:
break;
}
queryBuilder.setTables(database.TABLE);
Cursor cursor = queryBuilder.query(database.db, projection, selection,selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public String getType(Uri uri) {
switch (sURIMatcher.match(uri)) {
case ALL_ROWS:
return "vnd.android.cursor.dir/vnd.example.elemental";
case SINGLE_ROW:
return "vnd.android.cursor.item/vnd.example.elemental";
default:
throw new IllegalArgumentException("Unsupported URI: " +uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
database.openDb();
String nullColumnHack = null;
long id = database.db.insert(database.TABLE,nullColumnHack, values);
if (id > -1) {
Uri insertedId = ContentUris.withAppendedId(CONTENT_URI, id);
getContext().getContentResolver().notifyChange(insertedId, null);
return insertedId;
}
else
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
database.openDb();
if (selection == null)
selection = "1";
int deleteCount = database.db.delete(database.TABLE, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return deleteCount;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
database.openDb();
switch (sURIMatcher.match(uri)) {
case SINGLE_ROW :
String rowID = uri.getPathSegments().get(1);
selection = KEY_ID + "=" + rowID+ (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')': "");
default: break;
}
int updateCount = database.db.update(database.TABLE,values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return updateCount;
}
}
Database.java
public class Database extends Activity {
public static final String TAG = "Database";
public static final String C_ID = BaseColumns._ID;
//Columns
public static final String C_NAME = "counterName";
public static final String C_VALUE = "counterValue";
public static final String C_ORDER = "counterOrder";
//Database name, version, table name
public static final String DB_NAME = "list.db";
public static final int DB_VERSION = 1; // If you change, it will call onUpgrade()
public static final String TABLE = "List";
Context context;
DbHelper dbHelper;
SQLiteDatabase db;
public Database(Context context) {
this.context = context;
dbHelper = new DbHelper();
}
class DbHelper extends SQLiteOpenHelper {
public DbHelper() {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = String.format("CREATE TABLE %s"
+ " (%s INTEGER PRIMARY KEY AUTOINCREMENT, %s VARCHAR, %s INT, %s INT)",
TABLE, C_ID, C_NAME, C_VALUE, C_ORDER);
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + TABLE);
onCreate(db);
}
}
public void openDb(){
db=dbHelper.getWritableDatabase();
}
public Cursor query() {
openDb();
// iterate over all rows columns on TABLE
Cursor cursor = db.query(TABLE, null, null, null, null, null, null);
return cursor;
}
}
答案 0 :(得分:0)
我已更改ChannelAdapter
,像here那样夸大列表项,我开始使用ViewHolder
,这会提高约15-18的速度(我已经从某处读取了) ),findViewById
消耗大量时间来查找资源并为每个项目充气。