好的,我很难过。我有一个我发布的应用程序有错误ANR keyDispatchingTimedOut
所以在修复它时,我以为我会使用AsyncTask访问我的数据库,但我一直在获取NPE。此外,在我单击“添加”按钮然后单击“返回”之前,它不会填充列表视图,因此它会在onResume中填充listview,但不会填充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)
这是logcat中提到的DBase代码。
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中初始化dbase并使用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 );
}
}
答案 0 :(得分:1)
c
,然后在startManagingCursor()
运行第一行之前几乎肯定立即调用c
上的AsyncTask
。我强烈怀疑这就是为什么它适用于onResume
而不是onCreate
,因为onResume
实际上会填充c
。
就个人而言,如果您真的希望将所有内容都基于AsyncTask,那么将所有基于AsyncTask。在startManagingCursor()
之前请勿setListAdapter()
或onPostExecute()
。
不知道你的DBView
内部正在发生什么,尽管最有可能来自发布的代码,ourDatabase
此时为空。