Reputation: 1617
Could someone please check on codes. My XMLParser has caught an exception. I'm trying to use tabs fragments with listview using XML Parser to parse results from remote database.
MainActivity.java
public class MainActivity extends SherlockFragmentActivity implements TabListener {
private Fragment mFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(true);
//mFragment = new AppleFragment();
Tab tab = actionBar.newTab()
.setText("Apple")
.setTabListener(this)
.setIcon(R.drawable.apple);
actionBar.addTab(tab);
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = new AppleFragment();
ft.add(android.R.id.content, mFragment);
} else {
ft.attach(mFragment);
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.detach(mFragment);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
AppleFragment.java
public class AppleFragment extends SherlockListFragment{
static final String URL = "http://api.androidhive.info/pizza/?format=xml";
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_ID = "id";
static final String KEY_NAME = "name";
static final String KEY_COST = "cost";
static final String KEY_DESC = "description";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return super.onCreateView(inflater, container, savedInstanceState);
}
public void onActivityCreated(Bundle savedInstanceState) {
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_ID, parser.getValue(e, KEY_ID));
map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
// adding HashList to ArrayList
menuItems.add(map);
}
ListAdapter adapter = new SimpleAdapter(getActivity(), menuItems,
R.layout.list_item,
new String[] { KEY_NAME, KEY_DESC, KEY_COST }, new int[] {
R.id.name, R.id.desciption, R.id.cost });
setListAdapter(adapter);
}
}
XMLParser.java
public class XMLParser {
// constructor
public XMLParser() {
}
/**
* Getting XML from URL making HTTP request
* @param url string
* */
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// return XML
return xml;
}
/**
* Getting XML DOM element
* @param XML string
* */
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
return doc;
}
/** Getting node value
* @param elem element
*/
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if( child.getNodeType() == Node.TEXT_NODE ){
return child.getNodeValue();
}
}
}
}
return "";
}
/**
* Getting node value
* @param Element node
* @param key string
* */
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
}
LOGCAT :
10-05 16:36:50.453: E/AndroidRuntime(20162): FATAL EXCEPTION: main
10-05 16:36:50.453: E/AndroidRuntime(20162): java.lang.RuntimeException: Unable to start activity ComponentInfo{in.wptrafficanalyzer.actionbarsherlocknavtab/in.wptrafficanalyzer.actionbarsherlocknavtab.MainActivity}: android.os.NetworkOnMainThreadException
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1970)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.ActivityThread.access$600(ActivityThread.java:127)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.os.Handler.dispatchMessage(Handler.java:99)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.os.Looper.loop(Looper.java:137)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.ActivityThread.main(ActivityThread.java:4512)
10-05 16:36:50.453: E/AndroidRuntime(20162): at java.lang.reflect.Method.invokeNative(Native Method)
10-05 16:36:50.453: E/AndroidRuntime(20162): at java.lang.reflect.Method.invoke(Method.java:511)
10-05 16:36:50.453: E/AndroidRuntime(20162): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982)
10-05 16:36:50.453: E/AndroidRuntime(20162): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
10-05 16:36:50.453: E/AndroidRuntime(20162): at dalvik.system.NativeStart.main(Native Method)
10-05 16:36:50.453: E/AndroidRuntime(20162): Caused by: android.os.NetworkOnMainThreadException
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
10-05 16:36:50.453: E/AndroidRuntime(20162): at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
10-05 16:36:50.453: E/AndroidRuntime(20162): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
10-05 16:36:50.453: E/AndroidRuntime(20162): at java.net.InetAddress.getAllByName(InetAddress.java:220)
10-05 16:36:50.453: E/AndroidRuntime(20162): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
10-05 16:36:50.453: E/AndroidRuntime(20162): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
10-05 16:36:50.453: E/AndroidRuntime(20162): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
10-05 16:36:50.453: E/AndroidRuntime(20162): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
10-05 16:36:50.453: E/AndroidRuntime(20162): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
10-05 16:36:50.453: E/AndroidRuntime(20162): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
10-05 16:36:50.453: E/AndroidRuntime(20162): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
10-05 16:36:50.453: E/AndroidRuntime(20162): at in.wptrafficanalyzer.actionbarsherlocknavtab.XMLParser.getXmlFromUrl(XMLParser.java:45)
10-05 16:36:50.453: E/AndroidRuntime(20162): at in.wptrafficanalyzer.actionbarsherlocknavtab.AppleFragment.onCreateView(AppleFragment.java:38)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:505)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1136)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.Activity.performStart(Activity.java:4475)
10-05 16:36:50.453: E/AndroidRuntime(20162): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1943)
10-05 16:36:50.453: E/AndroidRuntime(20162): ... 11 more
Upvotes: 2
Views: 1569
Reputation: 20563
You're running a network operation on main thread. Use async task to run network operations in background thread (do your xml parsing in a background thread). That's why you are getting android.os.NetworkOnMainThreadException.
parse it in an async task like this:
class XMLParsingTask extends AsyncTask<String, Void, RSSFeed> {
protected void onPreExecute() {
//show a progress dialog to the user or something
}
protected void doInBackground(String... urls) {
//Parse your XML here
}
protected void onPostExecute() {
//do something with your parsed xml here and dismiss the progress dialog
}
}
new RXMLParsingTask().execute(null);
Here are some tutorials for you if you don't know how to use async tasks:
http://mobileorchard.com/android-app-developmentthreading-part-2-async-tasks/
http://www.vogella.com/articles/AndroidPerformance/article.html
here are the official docs: https://developer.android.com/reference/android/os/AsyncTask.html
Upvotes: 3
Reputation: 76
Move your network logic from main thread to separate thread, From Android 3.0, we need to execute all network related code on separate thread.
Upvotes: 0