1

Is there any way to pass a JAXP Node or Document via an Intent and Parcelable? JAXP doesn't implement Parcelable, so the answer is probably --no. Is there any DOM library that implements Parcelable? Can someone provide a working example of that?

Serialization isn't an option; nasty performance hit. Storing the data in res/xml is not an option: it must eventually (by end of project) be encrypted on disk. Android's "compiled" XML Access Tools do not support decrypting the whole XML. Of course I can do it myself with a class.

Here's my starter code that inflates the XML. My goal is to pass a Node or Document from one ListView to another, effectively drilling down the DOM via Lists.

My Document contains information that all activities need to share. Each activity accesses different Nodes, and extracts new information. I've considered exposing the Document via a global, but I don't think it will be safe for multiple Activities to access it that way.

Also, in the working code below I intend to pass a Node to the second ListActivity rather than a String, just haven't gotten that far.

package com.example

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;

public class JAXPListActivity extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Document doc = null;
        try {
            DocumentBuilderFactory factory = 
                        DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            doc = builder.parse(new File("/sdcard/example.xml"));

        } catch (Exception e) {
            e.printStackTrace(); //TO-DO: exception handling
        }

        NodeList nodes = doc.getChildNodes();
        String[] nodeList = new String[nodes.getLength()];

        for(int i = 0; i<nodes.getLength(); i++) {
            Node node = nodes.item(i);
            nodeList[i] = nodes.item(i).getNodeName();
        }

        this.setListAdapter(new ArrayAdapter<String>(this, 
                R.layout.list_item, 
                R.id.label, nodeList));

        ListView lv = getListView();

        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, 
                        int position, long id) {

                String nodeName = ((TextView) view).getText().toString();

                Intent i = new Intent(getApplicationContext(), 
                                JAXPNodeListActivity.class);

                i.putExtra("nodeName", nodeName);
                startActivity(i);
            }
        });
    }
}
yetimoner
  • 787
  • 2
  • 9
  • 19
  • Okay, apparently passing data via Intents is frowned upon, and clearly there are no putExtra() methods for Object. I'm still wondering if anybody has repackaged the DOM objects with Parcelable implementations. Maybe I'll give it a shot. – yetimoner Dec 09 '12 at 11:18
  • you can try to use : getIntent().getSerializableExtra(nodeName) – Anis BEN NSIR Dec 09 '12 at 16:36
  • The solution can't use serialization: it's one of the stated requirements. – yetimoner Dec 10 '12 at 23:44
  • i don't think so, passing serializable objects into the intent, is not the good solution. The use of Singletons consist on a quick fix, but the best solution, i think is to create a service witch will parse your xml from background and then expose parsed objects when they are available. – Anis BEN NSIR Dec 11 '12 at 09:44
  • Yes, I agree. If you put that comment in an Answer I'll accept it as the right answer. By the way, I decided to load the DOM into a global member. It's working out so far. – yetimoner Feb 04 '13 at 10:58

1 Answers1

-1

You can simply use a Singleton class. Like:

public class DomObjectManager{

private static DomObjectManager INSTANCE;
private  Document doc;

public static DomObjectManager getInstance(){

if(INSTANCE==null){
INSTANCE = new DomObjectManager();
}
return INSTANCE;
}
private DomObjectManager(){
}
//set the shared document;
public void setDocument(Document doc){
this.doc = doc;
}
public void getDocument(){
retunr doc;
}
//call to destroy before when you do not need the singleton any more.
public void destroy(){
INSTANCE == null;
}

}
Anis BEN NSIR
  • 2,555
  • 20
  • 29
  • Singletons get reaped by the Android GC, meaning they can revert to null at any point. The other problem is dropping the contextual messaging aspect of Intent.putExtra(). My second ListActivity needs to know which part of the DOM to refer to (since this is a drill-down). Passing a DOM Object of type Node would let the second activity continue to descend down the document hierarchy. – yetimoner Dec 09 '12 at 10:58
  • force it to be null with the destroy method. – Anis BEN NSIR Dec 09 '12 at 16:35