0

I'm trying to load a file from my classpath in a static context in Android, and every similar question on SO suggests using MyClass.class.getClassLoader().getResourcesAsStream(<filepath>), but this causes my app to crash before it opens.

My target SDK is 19, min SDK level is 17 and I'm using a phone running Android Lollipop

This is the part of code where I'm trying to load the file "locations.xml":

public static final String LOCATIONS_FILE_PATH = "locations.xml";

public static ArrayList<City> getLocations(String locations_file_path) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = null;
    Document document = null;
    try {
        builder = factory.newDocumentBuilder();
        document = builder.parse(
        City.class.getClassLoader().getResourceAsStream(locations_file_path));

The file is located in the same package as the java classes that is referencing it.

The error given in logcat is an IllegalArgumentException in DocumentBuilder.parse(...) because City.class.getClassLoader().getResourceAsStream("locations.xml")) returns null.

Marcus
  • 6,697
  • 11
  • 46
  • 89
Ozzy
  • 8,244
  • 7
  • 55
  • 95
  • Try `City.class.getResourceAsStream(locations_file_path));` – Marcus Mar 11 '15 at 21:03
  • @Marcus same problem – Ozzy Mar 11 '15 at 21:06
  • Hmm.. I don't see any problem with your code. Have you tried cleaning the project? – Marcus Mar 11 '15 at 21:10
  • 1
    Acording to [this](http://stackoverflow.com/questions/19035407/classloader-getresourceasstream-returns-null) and [this](http://stackoverflow.com/questions/16570523/getresourceasstream-returns-null) answer, your code related to `getResourceAsStream` is correct – Marcus Mar 11 '15 at 21:16
  • Read them, but logcat does point to this line of code as causing the error. Also, have cleaned the project @Marcus – Ozzy Mar 11 '15 at 21:23

2 Answers2

2

I think that you'll want to verify that in the final apk file, the xml file is actually included where you think it is.

The more common pattern for Android is to put the file in the 'assets' directory, and then load it from there using the Activity's getAssets() method.

See Read Assets file as string

Community
  • 1
  • 1
GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67
  • Couldn't get it to work the other way. In the end I put the file in my assets folder and used this line: `InputStream xml = getAssets().open("locations.xml");` and it worked. – Ozzy Mar 12 '15 at 13:21
0

As an alternative to getResourceAsStream you could use FileInputStream as explained in this tutorial

Please note that If FileInputStream also return null, then it's a big chance that as @GreyBeardedGeek said, the xml file is actually not included where you expect it to in the final apk file.

Relevant code:

import java.io.FileInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class DocumentBuilderDemo {

   public static void main(String[] args) {

      // create a new DocumentBuilderFactory
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

      try {
         // use the factory to create a documentbuilder
         DocumentBuilder builder = factory.newDocumentBuilder();

         // create a new document from input stream
         FileInputStream fis = new FileInputStream("Student.xml");
         Document doc = builder.parse(fis);

         // get the first element
         Element element = doc.getDocumentElement();

         // get all child nodes
         NodeList nodes = element.getChildNodes();

         // print the text content of each child
         for (int i = 0; i < nodes.getLength(); i++) {
            System.out.println("" + nodes.item(i).getTextContent());
         }
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}

Student.xml (In your case, locations.xml)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<student id="10">
   <age>12</age>
   <name>Malik</name>
</student>
Marcus
  • 6,697
  • 11
  • 46
  • 89
  • I'm sure my parser works, but the object passed to the parser is null so it probably is the case that the file is not found, as @GreyBeardedGeek mentioned. The problem for me is correctly locating the file. – Ozzy Mar 11 '15 at 21:27
  • I'd try this, and if `FileInputStream` also return null, then you are positive that it's the location of the xml file that is the problem. If that is so, then put the file in the `assets` folder and load it from assets instead. @Ozzy – Marcus Mar 11 '15 at 21:29