Android - 将解析的xml数据存储到sql时出错

时间:2017-11-30 09:30:14

标签: java android sql xml arraylist

我将从本地主机(http://10.0.0.22/cardealers.xml)上的URL解析的xml数据存储到sql时出现java.lang.NullPointerException错误。这是xml am解析:

<Providers>
  <CarDealer name="BEFORWARD" id="1">
    <CarMake name="Toyota" id="20">
      <CarModel name="Belta" id="21"/>
      <CarModel name="RunX" id="22"/>
      <CarModel name="Corolla" id="23"/>
    </CarMake>
    <CarMake name="Nissan" id="30">
      <CarModel name="Murano" id="31"/>
      <CarModel name="Pathfinder" id="32"/>
      <CarModel name="Navara" id="33"/>
    </CarMake>
  </CarDealer>
</Providers>

在我的xml处理程序类中,我像这样传递了我的xml:

public class SAXXMLHandler extends DefaultHandler {
private List<CarMake> carMaker;
private String tempVal;
// to maintain context
private CarMake carmake;

public SAXXMLHandler() {

    carMaker = new ArrayList<CarMake>();
}

public List<CarMake> getCarMake() {

    return carMaker;
}

// Event Handlers
public void startElement(String uri, String localName, String qName,
                         Attributes attributes) throws SAXException {
    // reset
    tempVal = "";
    if (qName.equalsIgnoreCase("CarMake")) {
        // create a new instance of CarMake
        carmake = new CarMake();
        carmake.setName(attributes.getValue("name"));
    }
}

public void characters(char[] ch, int start, int length)
        throws SAXException {
    tempVal = new String(ch, start, length);
}

public void endElement(String uri, String localName, String qName)
        throws SAXException {

    if (qName.equalsIgnoreCase("CarMake")) {
        // add it to the list
        carMaker.add(carmake);
    } else if (qName.equalsIgnoreCase("CarModel")) {
        carmake.setCarModel(tempVal);
    }
 }
 }

然后在Sell.java

中使用AsyncTask
public class Sell extends Activity implements
    View.OnClickListener, AdapterView.OnItemClickListener {

static final String URL = "http://10.0.0.22/cardealers.xml";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sell);

    //new GetXMLTask().execute();
    new GetXMLTask(this).execute();
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
                        long id) {
}

@Override
public void onClick(View view) {
    GetXMLTask task = new GetXMLTask(this);
    task.execute(new String[]{URL});
}

//private inner class extending AsyncTask
private class GetXMLTask extends AsyncTask<String, Void, List<Service>> {
    private Activity context;

    public GetXMLTask(Activity context) {

        this.context = context;
    }

    /* uses HttpURLConnection to make Http request from Android to download
     the XML file */
    private String getXmlFromUrl(String urlString) {
        StringBuffer output = new StringBuffer("");
        try {
            InputStream stream = null;
            URL url = new URL(urlString);
            URLConnection connection = url.openConnection();

            HttpURLConnection httpConnection = (HttpURLConnection) connection;
            httpConnection.setRequestMethod("GET");
            httpConnection.connect();

            if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                stream = httpConnection.getInputStream();

                BufferedReader buffer = new BufferedReader(
                        new InputStreamReader(stream));
                String s = "";
                while ((s = buffer.readLine()) != null)
                    output.append(s);
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return output.toString();
    }


    @Override
    protected List<CarMake> doInBackground(String... urls) {
        List<CarMake> carMaker = null;
            String xml = null;

        for (String url : urls) {
            xml = getXmlFromUrl(url);

            InputStream stream = new ByteArrayInputStream(xml.getBytes());
            carMaker = SAXXMLParser.parse(stream);

        }
        // stream.close();
        return carMaker;
    }

     @Override
    protected void onPostExecute(List<CarMake> carMaker) {

        if (carMaker==null){
            Toast.makeText(Sell.this, "carMaker is empty..", Toast.LENGTH_LONG).show();
        } else {
            E_VodaDB myE_Voda = new E_VodaDB(this.context);
            myE_Voda.InsertData(carMaker);
        }
    }

  }
}

可以看出,我的doInBackground()会返回一个结果,即carMaker。然后在我的OnPostExecute()中,我将carMaker arraylist传递给我的数据库类以插入db。

// Adding new service
public void InsertData(List<CarMake> carMaker) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(CARMAKE_NAME, carMaker.get(0).getCarMake()); // CarMake Names

    // Inserting Row
    db.insert(TABLE_CARDEALER, null, values);
    db.close(); // Closing database connection
  }
}

我在Android Studio中运行应用时出现以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference

在我的Sell.java中指向我的onPostExecute()。从carMaker返回的doInBackground() arraylist似乎是空的,或者它是一个不能直接存储到db中的不同数据类型。我该如何解决此错误?请注意我是android的新手

1 个答案:

答案 0 :(得分:0)

doInBackground()上创建了arraylist,但忘了初始化。试试这个。

@Override
    protected List<CarMake> doInBackground(String... urls) {
        List<CarMake> carMaker = new ArrayList<CarMake>();
            String xml = null;

        for (String url : urls) {
            xml = getXmlFromUrl(url);

            InputStream stream = new ByteArrayInputStream(xml.getBytes());
            carMaker = SAXXMLParser.parse(stream);

        }
        // stream.close();
        return carMaker;
    } 

在此传递当前类上下文的null实例:

@Override
    protected void onPostExecute(List<CarMake> carMaker) {

        //E_DB myE_db = new E_DB(null);// replace this to 
          E_DB myE_db = new E_DB(this);
        myE_db.InsertData(carMaker);
    }

  }

快乐的编码!!