이유가 확실하지 않습니다. NullPointerException이 발생합니다. 다른 스레드 내에서 데이터베이스에 액세스한다는 사실과 관련이 있는지 궁금합니다. 데이터베이스 (.getWritableDatabase)를 아무 문제없이 MainActivity에서 열 수 있지만 작동하지 않는 다른 클래스에서 액세스를 시도합니다. 나는 "Context"를 사용하기 위해 "Activity"로 클래스를 확장했다. 그 맞습니까? 어떤 조언을 주셔서 감사합니다.데이터베이스를 열 때 NullPointerException이 발생했습니다.
다음 명령을 실행할 때 오류 FetchXML.java 파일 발생
의 SQLiteDatabase dbTools.getWritableDatabase DB =();
오류 :
W/System.err﹕ java.lang.NullPointerException
W/System.err﹕ at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:256)
W/System.err﹕ at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
W/System.err﹕ at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
W/System.err﹕ at com.digitalalias.dndandroid.rss.FetchXML.parseXMLAndStoreIt(FetchXML.java:151)
W/System.err﹕ at com.digitalalias.dndandroid.rss.FetchXML$Fetch.doInBackground(FetchXML.java:79)
W/System.err﹕ at com.digitalalias.dndandroid.rss.FetchXML$Fetch.doInBackground(FetchXML.java:57)
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err﹕ at java.lang.Thread.run(Thread.java:841)
FetchXML.java
public class FetchXML extends Activity {
private static final String TAG = "dnda";
private String urlString = null;
private XmlPullParserFactory xmlFactoryObject;
private XmlPullParser myparser;
private DatabaseTools dbTools;
private Post post;
private List<Post> posts;
private ContentValues values;
/**
* constructor
* @param url
*/
public FetchXML(String url) {
this.urlString = url;
posts = new ArrayList<Post>();
}
/**
* Starts the new thread to download/parse XML
*/
public void grabXml() {
new Fetch().execute();
}
/**
* fetch the XML file from the URL
*/
public class Fetch extends AsyncTask<Void, Void, XmlPullParser> {
@Override
protected XmlPullParser doInBackground(Void... params) {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
xmlFactoryObject = XmlPullParserFactory.newInstance();
xmlFactoryObject.setNamespaceAware(true);
myparser = xmlFactoryObject.newPullParser();
// myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
myparser.setInput(stream, null);
parseXMLAndStoreIt(myparser);
stream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return myparser;
}
protected void onPostExecute(XmlPullParser result) {
}
}
/**
* parseXMLAndStoreIt
* @param myParser
*/
public void parseXMLAndStoreIt(XmlPullParser myParser) {
int eventType;
boolean item = false; // used to indicate if the parser is within an ITEM tag
String tagText = "";
try {
eventType = myParser.getEventType();
// loop through xml
while (eventType != XmlPullParser.END_DOCUMENT) {
String tagName = myParser.getName();
// gather specific tags
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagName.equalsIgnoreCase("item")) {
item = true;
post = new Post(); // new instance of post object
}
break;
case XmlPullParser.TEXT:
tagText = myParser.getText();
break;
case XmlPullParser.END_TAG:
if (item) {
if (tagName.equalsIgnoreCase("item")) {
posts.add(post); // add post object to list
} else if (tagName.equalsIgnoreCase("title")) {
post.setTitle(tagText);
} else if (tagName.equalsIgnoreCase("link")) {
post.setLink(tagText);
} else if (tagName.equalsIgnoreCase("pubDate")) {
post.setPubDate(tagText);
} else if (tagName.equalsIgnoreCase("guid")) {
post.setGuid(tagText);
} else if (tagName.equalsIgnoreCase("description")) {
post.setDescription(tagText);
}
}
break;
}
eventType = myParser.next();
}
// process list of posts
if (!posts.isEmpty()) {
values = new ContentValues();
dbTools = new DatabaseTools(FetchXML.this);
SQLiteDatabase db = dbTools.getWritableDatabase();
// insert posts into database
for (Post key : posts) {
values.put(dbTools.COLUMN_TITLE, key.getTitle());
values.put(dbTools.COLUMN_LINK, key.getLink());
values.put(dbTools.COLUMN_PUBDATE, key.getPubDate());
values.put(dbTools.COLUMN_GUID, key.getGuid());
values.put(dbTools.COLUMN_DESCRIPTION, key.getDescription());
db.insert(dbTools.DATABASE_TABLE, null, values);
}
db.close();
dbTools.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
그래서; 이 경우에는 MainActivity 만 있습니다. 내가 가지고있는 다른 모든 클래스 파일은 배경 기능으로 동작합니다. 그것으로 컨텍스트로 MainActivity를 전달해야한다고 말했습니까? – fergatron
네,'MainActivity'의'this'. – laalto