Хорошо, я в тупике. У меня есть приложение, которое я опубликовал, с ошибкой ANR keyDispatchingTimedOut
, поэтому, исправляя это, я думал, что получу доступ к своей БД с помощью AsyncTask, но продолжаю получать NPE. Кроме того, он не заполняет представление списка, пока я не нажму кнопку добавления, а затем не нажму назад, поэтому он заполняет представление списка в onResume, но не в OnCreate. Вот код активности.
public class View extends ListActivity implements OnClickListener {
String loc;
SharedPreferences data;
public static String filename = "Location";
private DBase db;
public static String vLoc = null, vId = null, vSong = null, vNumber = null;
Button bNLAdd, bNLBack;
TextView tvNLList;
Cursor c;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.notepad_list);
getLoc();
initialize();
fillData();
}
@Override
public void onClick(android.view.View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.bNLAdd:
startActivity(new Intent("com.ADD")); // edited to remove package name
break;
case R.id.bNLBack:
finish();
break;
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
fillData();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (c != null && !c.isClosed()) {
c.close();
}
db.close();
}
@Override
protected void onListItemClick(ListView l, android.view.View v,
int position, long id) { // TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
vLoc = loc;
vId = (String) ((Cursor) l.getItemAtPosition(position)).getString(0);
vSong = (String) ((Cursor) l.getItemAtPosition(position)).getString(1);
vNumber = (String) ((Cursor) l.getItemAtPosition(position))
.getString(2);
startActivity(new Intent("com.EDIT")); // edited to remove package name
}
private void fillData() {
// Get all of the notes from the database and create the item list
new getCursor().execute(loc);
startManagingCursor(c);
String[] from = new String[] { DBase.KEY_2SONG, DBase.KEY_2NUMBER };
int[] to = new int[] { R.id.text1, R.id.text2 };
// Now create an array adapter and set it to display using our row
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.notes_row, c, from, to);
setListAdapter(notes);
}
private void getLoc() {
// TODO Auto-generated method stub
data = getSharedPreferences(filename, 0);
loc = data.getString("loc", null);
}
private void initialize() {
// TODO Auto-generated method stub
tvNLList = (TextView) findViewById(R.id.tvNLList);
tvNLList.setText("Song List for Location " + loc);
bNLAdd = (Button) findViewById(R.id.bNLAdd);
bNLBack = (Button) findViewById(R.id.bNLBack);
bNLAdd.setOnClickListener(this);
bNLBack.setOnClickListener(this);
}
public class getCursor extends AsyncTask<String, Integer, Cursor> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected Cursor doInBackground(String... params) {
// TODO Auto-generated method stub
db = new DBase(View.this);
db.open();
try {
c = db.fetchData(loc);
} catch (NullPointerException e) {
// TODO: handle exception
e.printStackTrace();
} finally {
if (c != null) {
return c;
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Cursor c) {
// TODO Auto-generated method stub
super.onPostExecute(c);
}
}
}
А вот и logcat.
02-12 16:10:03.834: WARN/System.err(549): java.lang.NullPointerException
02-12 16:10:04.074: WARN/System.err(549): at com.DBase.fetchData(DBase.java:89)
02-12 16:10:04.074: WARN/System.err(549): at com.View$getCursor.doInBackground(View.java:134)
02-12 16:10:04.074: WARN/System.err(549): at com.View$getCursor.doInBackground(View.java:1)
02-12 16:10:04.074: WARN/System.err(549): at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-12 16:10:04.074: WARN/System.err(549): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-12 16:10:04.074: WARN/System.err(549): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-12 16:10:04.074: WARN/System.err(549): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
02-12 16:10:04.074: WARN/System.err(549): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
02-12 16:10:04.074: WARN/System.err(549): at java.lang.Thread.run(Thread.java:1096)
А вот код DBase, упомянутый в logcat.
public Cursor fetchData(String loc) {
// TODO Auto-generated method stub
return ourDatabase.query(loc, new String[] { KEY_ROWID, KEY_2SONG, KEY_2NUMBER },
null, null, null, null, null);
}
Я знаю, что я что-то упускаю. Я попытался поместить startManagingCursor(c);
в onPostExecute, инициализировать базу данных в onCreate и использовать asyncTask для простого извлечения данных и т. Д.
Любая помощь будет оценена.
РЕДАКТИРОВАТЬ здесь остаток класса DBase. Он работал отлично, пока я не попробовал AsyncTask.
public class DBase {
public static final String KEY_ROWID = "_id";
public static final String KEY_2TBL = "loc";
public static final String KEY_2SONG = "Song";
public static final String KEY_2NUMBER = "Number";
private static final String DATABASE_NAME = "Tracker";
static final String DATABASE_TABLE = "TempTable";
private static final int DATABASE_VERSION = 1;
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
private static class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_ROWID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_2TBL
+ " TEXT NOT NULL, " + KEY_2NUMBER + " TEXT NOT NULL, "
+ KEY_2SONG + " TEXT NOT NULL);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public DBase(Context c) {
ourContext = c;
}
public DBase open() throws SQLException {
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close() {
ourHelper.close();
}
public void deleteEntry(long dId, String loc) {
ourDatabase.delete(loc, KEY_ROWID + "=" + dId, null);
}
public long addTable(String loc) {
// TODO Auto-generated method stub
ourDatabase.execSQL("CREATE TABLE IF NOT EXISTS " + loc + " ("
+ KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_2TBL
+ " TEXT NOT NULL, " + KEY_2SONG + " TEXT NOT NULL, "
+ KEY_2NUMBER + " TEXT NOT NULL);");
ContentValues cv = new ContentValues();
cv.put(KEY_2TBL, loc);
return ourDatabase.insert(loc, null, cv);
}
public Cursor fetchData(String loc) {
// TODO Auto-generated method stub
return ourDatabase.query(loc, new String[] { KEY_ROWID, KEY_2SONG, KEY_2NUMBER },
null, null, null, null, null);
}
public long createEntry(String loc, String sSong, String sNumber) {
// TODO Auto-generated method stub
ContentValues cv = new ContentValues();
cv.put(KEY_2TBL, loc);
cv.put(KEY_2SONG, sSong);
cv.put(KEY_2NUMBER, sNumber);
return ourDatabase.insert(loc, null, cv);
}
public ArrayList<String> listTables() {
ArrayList<String> tableList = new ArrayList<String>();
String SQL_GET_ALL_TABLES = "SELECT name FROM "
+ "sqlite_master WHERE type='table' ORDER BY name";
Cursor c = ourDatabase.rawQuery(SQL_GET_ALL_TABLES, null);
c.moveToFirst();
if (!c.isAfterLast()) {
do {
tableList.add(c.getString(0));
} while (c.moveToNext());
}
c.close();
return tableList;
}
public void editSong(long eId, String loc, String eSong, String eNumber) {
// TODO Auto-generated method stub
ContentValues cvUpdate = new ContentValues();
cvUpdate.put(KEY_2TBL, loc);
cvUpdate.put(KEY_2SONG, eSong);
cvUpdate.put(KEY_2NUMBER, eNumber);
ourDatabase.update(loc, cvUpdate, KEY_ROWID + "=" + eId, null);
}
public void deleteTable(String loc) {
// TODO Auto-generated method stub
ourDatabase.execSQL("DROP TABLE " + loc );
}
}