Android 数据库崩溃

Android database crashing

我是 Android 开发的新手,正在制作一个可以读取 rss xml 文件、将其存储在数据库中并可以在本地访问的应用程序。当我这样做时,代码崩溃了,我不明白为什么。我尝试了一些事情,但一无所获。我真的很感激任何帮助。谢谢

LayoutFile (maintwo.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="I&apos;m screen 2 (main2.xml)"
    android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

Activity 文件 (ActivityTwo.java)

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

import java.util.ArrayList;
public class ActivityTwo extends Activity{

    //private DatabaseHelper helper;
    private TextView tv;
    private ArrayList<String> strings = new ArrayList<String>();
    private HandleXML handleXML;
    //DatabaseHelper helper;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.maintwo);
        tv = (TextView)findViewById(R.id.textView1);
        //helper = new DatabaseHelper(this);
        //storeToDB();
        //writeToFile();
        getFromXML();
    }
    /*public void storeToDB() {
        helper = new DatabaseHelper(this);
        helper.insertContact("Something", "123");
        helper.insertContact("Another", "456");
    }
    public void writeToFile() {
        strings = helper.getAllContacts();
        String x = strings.get(0);
        String y = strings.get(2);
        tv.setText(x + " " + y);
    }*/
    public void getFromXML() {
        handleXML = new HandleXML("http://examplewebsite/file.xml");
        handleXML.fetchXML();
        strings = handleXML.getAll();
        //strings = helper.getAllContacts();
        String x = strings.get(0);
        tv.setText(x);
    }
}

RSS Reader (HandleXML.java)

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.app.Activity;
import android.content.Context;
import android.util.Log;

public class HandleXML extends Activity{

    private String title = "title";
    private String link = "link";
    private String description = "description";
    private DatabaseHelper helper;

    private String urlString = null;
    private XmlPullParserFactory xmlFactoryObject;
    public volatile boolean parsingComplete = true;
    public HandleXML(String url){
        helper = new DatabaseHelper(this);
        this.urlString = url;
    }
    public ArrayList<String> getAll() {
        return helper.getAllContacts();
    }
    /*public String getTitle(){
        return title;
    }
    public String getLink(){
        return link;
    }
    public String getDescription(){
        return description;
    }*/
    public void parseXMLAndStoreIt(XmlPullParser myParser) {
        int event;
        int i =0;
        String text=null;
        try {
            event = myParser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT) {
                String name=myParser.getName();
                switch (event){
                    case XmlPullParser.START_TAG:
                        break;
                    case XmlPullParser.TEXT:
                        text = myParser.getText();
                        break;
                    case XmlPullParser.END_TAG:
                        if(name.equals("title")){
                            title = text;
                        }
                        else if(name.equals("link")){
                            link = text;
                        }
                        else if(name.equals("description")){
                            description = text;
                        }
                        else{
                        }
                        break;
                }
                helper.insertContact(title + i, "123");
                i++;
                event = myParser.next();
            }
            parsingComplete = false;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void fetchXML(){
        Thread thread = new Thread(new Runnable(){
            @Override
            public void run() {
                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();
                    XmlPullParser myparser = xmlFactoryObject.newPullParser();
                    myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
                    myparser.setInput(stream, null);
                    parseXMLAndStoreIt(myparser);
                    stream.close();
                } catch (Exception e) {
                }
            }
        });
        thread.start();
    }
}

用于创建数据库的文件 (DatabaseHelper.java)

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.HashMap;

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DATABASE_NAME = "MyDBName.db";
    public static final String CONTACTS_TABLE_NAME = "contacts";
    public static final String CONTACTS_COLUMN_ID = "id";
    public static final String CONTACTS_COLUMN_NAME = "name";
    public static final String CONTACTS_COLUMN_PHONE = "phone";

    private HashMap hp;

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME , null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table contacts " + "(id integer primary key, name text,phone text)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS contacts");
        onCreate(db);
    }

    public boolean insertContact  (String name, String phone)
    {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();

        contentValues.put("name", name);
        contentValues.put("phone", phone);

        db.insert("contacts", null, contentValues);
        return true;
    }

    public Cursor getData(int id){
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor res =  db.rawQuery( "select * from contacts where id="+id+"", null );
        return res;
    }

    public int numberOfRows(){
        SQLiteDatabase db = this.getReadableDatabase();
        int numRows = (int) DatabaseUtils.queryNumEntries(db, CONTACTS_TABLE_NAME);
        return numRows;
    }

    public boolean updateContact (Integer id, String name, String phone)
    {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put("name", name);
        contentValues.put("phone", phone);
        db.update("contacts", contentValues, "id = ? ", new String[] { Integer.toString(id) } );
        return true;
    }

    public Integer deleteContact (Integer id)
    {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.delete("contacts",
                "id = ? ",
                new String[] { Integer.toString(id) });
    }

    public ArrayList getAllContacts()
    {
        ArrayList array_list = new ArrayList();
        //hp = new HashMap();
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor res =  db.rawQuery( "select * from contacts", null );
        res.moveToFirst();
        while(res.isAfterLast() == false){
            array_list.add(res.getString(res.getColumnIndex(CONTACTS_COLUMN_NAME)));
            res.moveToNext();
        }
        return array_list;
    }
}

崩溃报告

01-23 20:33:10.124  19847-19847/com.varvaniweb.example.helloworld E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.varvaniweb.example.helloworld, PID: 19847
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.varvaniweb.example.helloworld/com.varvaniweb.example.helloworld.ActivityTwo}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access0(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5021)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:256)
            at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
            at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
            at com.varvaniweb.example.helloworld.DatabaseHelper.getAllContacts(DatabaseHelper.java:87)
            at com.varvaniweb.example.helloworld.HandleXML.getAll(HandleXML.java:33)
            at com.varvaniweb.example.helloworld.ActivityTwo.getFromXML(ActivityTwo.java:45)
            at com.varvaniweb.example.helloworld.ActivityTwo.onCreate(ActivityTwo.java:29)
            at android.app.Activity.performCreate(Activity.java:5231)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1090)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access0(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5021)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
            at dalvik.system.NativeStart.main(Native Method)

问题是您正在自己创建 Activity (HandleXML) 并将其用作 DatabaseHelper:

所需的 context
handleXML = new HandleXML("http://examplewebsite/file.xml");

内部 HandleXML:

public HandleXML(String url) {
    helper = new DatabaseHelper(this); // <-- PROBLEM: this does not have Context info
    this.urlString = url;
}

您应该永远不要自己实例化应用程序组件。这样做是系统的责任——作为这样做的一部分,系统会附加有关应用程序和它代表您创建的组件的信息。因为是您自己创建的,所以它没有必要的 Context 信息来打开数据库(或者做很多事情,真的)。

更改您的 HandleXML class,使其不扩展 Activity 而是提供一个上下文以传递给 DatabaseHelper:

public class HandleXML {
    ...
    public HandleXML(Context context, String url) {
        helper = new DatabaseHelper(context);
        this.urlString = url;
    }
    ...
}

在您的 ActivityTwo 中这样调用它:

handleXML = new HandleXML(this, "http://examplewebsite/file.xml");