public String getMetaData() {
String errors = "";
try {
URL url = new URL("http://in2streaming.com:9999/stats?sid=1.xml");
URLConnection conn = url.openConnection();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// Error Here:
Document doc = db.parse(conn.getInputStream().toString());
// get the root node
NodeList nodeList = doc.getElementsByTagName("SHOUTCASTSERVER");
Node node=nodeList.item(0);
// the node has three child nodes
for (int i = 0; i < node.getChildNodes().getLength(); i++) {
Node temp=node.getChildNodes().item(i);
if(temp.getNodeName().equalsIgnoreCase("SONGTITLE")){
return temp.getTextContent();
}
}
return "Couldn't reach XML";
}
catch (Exception e) {
return "Exception ";
}
}
Calling this function via Runnable, Got Exception android.os.NetworkOnMainThreadException
I might change the link to http://in2streaming.com:9999/7.html and use HTMl parser instead
// Refresh meta data
private final Runnable refresh_meta = new Runnable() {
#Override
public void run() {
Toast.makeText(m_context, getMetaData(), Toast.LENGTH_SHORT).show();
m_handler.postDelayed(this, 5000);
}
};
For NetworkOnMainThreadException(You can also use AsyncTask):
Executors.newSingleThreadExecutor().submit(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, getMetaData(), Toast.LENGTH_SHORT).show();
}
});
If you want to Schedule every 5 sec.
You can use ScheduledExecutorService
ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.scheduleAtFixedRate(refresh_meta,
1, //initial delay
5, //run every 5 seconds
TimeUnit.SECONDS);
And Update your Runnable as
private Runnable refresh_meta = new Runnable() {
#Override
public void run() {
final String text = getMetaData();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(m_context, text, Toast.LENGTH_SHORT).show();
}
}
);
}
};
Also,
Change Document doc = db.parse(conn.getInputStream().toString()); to
Document doc = db.parse(conn.getInputStream());
First some remarks:
a) Do not muffle the exceptions like you do here :
catch (Exception e) {
return "Exception ";
}
This way you will never know what was the exception that was thrown. It is better to log/print the exception's stack trace, for example:
catch (Exception e) {
Log.e("TAG", "Error", e);
return "Exception";
}
b) conn.getInputStream().toString() doesn't do what you suppose it does (convert the InputStream to String). DocumentBuilder's parse method takes an InputStream as parameter no need to convert it to String.
Having the above in mind here is your method:
public String getMetaData() {
String errors = "";
try {
URL url = new URL("http://in2streaming.com:9999/stats?sid=1.xml");
URLConnection conn = url.openConnection();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// Error Here:
Document doc = db.parse(conn.getInputStream());
// get the root node
NodeList nodeList = doc.getElementsByTagName("SHOUTCASTSERVER");
Node node=nodeList.item(0);
// the node has three child nodes
for (int i = 0; i < node.getChildNodes().getLength(); i++) {
Node temp=node.getChildNodes().item(i);
if(temp.getNodeName().equalsIgnoreCase("SONGTITLE")){
return temp.getTextContent();
}
}
return "Couldn't reach XML";
}
catch (Exception e) {
Log.e("TAG", "Error in getMetaData()", e);
return "Exception ";
}
}
Try running your app again and if an error arises from this method it will be printed in your logcat with the message "Error in getMetaData()". Update your question accordingly with the error to let other members help you.
Related
I'm creating a weather app which gets the min/max temperature from a 5 day forecast XML with same node names. I want to use the current date to look through the XML and find the correct min/max for that day.
This is the weather XML: Link
Here is my code, I've trimmed it just enough to the part where I don't understand the multi-nodes, but still I wanted it to be reusable (Currently it just gets the first min/max as denoted by a 0):
public class MyAsyncTask extends AsyncTask < Void, Void, String > {
//========================== pre execute to get date for xml =======
protected void onPreExecute() {
try {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
} catch (Exception e) {}
}#
Override
protected String doInBackground(Void...params) {
//=========================== Load data using xml ================
try {
URL xmlUrl2 = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=london&mode=xml&units=metric&cnt=5");
InputStream inm = xmlUrl2.openStream();
Document docm = parsem(inm);
docm.getDocumentElement().normalize();
Node nNodem = docm.getElementsByTagName("temperature").item(0);
Element eElementm = (Element) nNodem;
double dmax = Math.round(Double.parseDouble(eElementm.getAttribute("max")));
int dxmax = (int) dmax;
xmaxtemp = Integer.toString(dxmax);
double dmin = Math.round(Double.parseDouble(eElementm.getAttribute("min")));
int dxmin = (int) dmin;
xmintemp = Integer.toString(dxmin);
} catch (UnknownHostException s) {
internet = false;
} catch (IOException i) {
System.out.println("IO Exception error!");
} catch (Exception ex) {
ex.printStackTrace();
}
return xtemp;
}
//========================= show data===============
#
Override
protected void onPostExecute(String result) {
TextView minmax = (TextView) findViewById(R.id.minmax);
minmax.setText("↑" + xmaxtemp + " " + xmintemp + "↓");
}
//======================== parse document =======
public static Document parse(InputStream is) {
Document ret = null;
DocumentBuilderFactory domFactory;
DocumentBuilder builder;
try {
domFactory = DocumentBuilderFactory.newInstance();
domFactory.setValidating(false);
domFactory.setNamespaceAware(false);
builder = domFactory.newDocumentBuilder();
ret = builder.parse(is);
} catch (Exception ex) {
System.err.println("unable to load XML: " + ex);
}
return ret;
}
}
For better use, u should use xpath to have a perfect manipulation over ur xml data:
this is an example how to get all temperature nodes
String expression = "//temperature";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
After that you can manipulate the list.
this is a good tuto to start using xpath with java:
java-xml-xpath-tutorial/
I have a running async task in my android application which runs perfectly. However I would like to know if it possible to return a string value from the asynctask in android as well as update a UI item. I want to update to a rating stars in the UI update and return a list of information from my server (which is working now).
Is it possible to return a value and update a UI from one asynctask in android??
Code for my Asynctask is below:
public class ConnectToServer extends AsyncTask< String, String, ArrayList<String>> {
#Override
protected ArrayList<String> doInBackground(String... params)
{
Socket client;
DataInputStream input;
DataOutputStream output;
String results = "";
XMLCreator x = new XMLCreator();
ArrayList<String> lists = new ArrayList<String>();
try
{
Log.i("CLIENT", "Client started");
// Step 1: Create a Socket to make connection.
// client = new Socket(InetAddress.getLocalHost(), 500);
client = new Socket("*****", 5001);
Log.i("CLIENT", "Connected to: "
+ client.getInetAddress().getHostName());
publishProgress("Connected...");
// Step 2: Get the input and output streams.
input = new DataInputStream(client.getInputStream());
output = new DataOutputStream(client.getOutputStream());
Log.i("CLIENT", "Got I/O Streams");
publishProgress("Obtained Streams...");
// Step 3: Process connection.
//Read in the value that the user selected from the bundle
String Day = params[0].toString();
//put into XML document as a query
//create a string
Document doc;
try
{
//Create an XML document with tutor's student number
doc = x.createDoc();
Element tutor = doc.createElement("Query");
tutor.appendChild(x.createDayforSession(doc, "GetSessionByDay", Day));
doc.appendChild(tutor);
//Create a string
String s = x.getStringFromDocument(doc);
output.writeUTF(s);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
publishProgress("Processing");
//Get all the session information for that day in XML string
//Create a document
//Break it up and add it to the view
results = input.readUTF();
try
{
//Creates the document
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(results)));
//optional, but recommended
//read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
document.getDocumentElement().normalize();
//Look at root node's type (e.g. <query> or <login> or <add>)
String rootNode = document.getDocumentElement().getNodeName().toString();
if (rootNode.equals("Result"))
{
//Any methods which need to be called that will be used to query the database
//Always sending the String XML through as a parameter
//Look at the child node
NodeList nList = document.getElementsByTagName("Query");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) nNode;
String Semester = eElement.getElementsByTagName("Semester").item(0).getTextContent();
String StartTime = eElement.getElementsByTagName("StartTime").item(0).getTextContent();
String Days = eElement.getElementsByTagName("Day").item(0).getTextContent();
String Lab = eElement.getElementsByTagName("Lab").item(0).getTextContent();
String session = "Semester: " + Semester + "\n" + "StartTime: " + StartTime + "\n" + "Days: " + Days + "\n" + "Lab: " + Lab + "\n";
lists.add(session);
}
}
}
}
catch (Exception e)
{
e.getMessage();
}
// Step 4: Close connection.
Log.i("CLIENT", "Transmission complete. "
+ "Closing connection.");
output.writeUTF("TERMINATE");
client.close();
publishProgress("Closed connection...");
} catch (IOException e) {
e.printStackTrace();
}
return lists;
}
#Override
protected void onPostExecute(ArrayList<String> lists)
{
super.onPostExecute(lists);
//UPDATE A STAR RATING HERE
}
#Override
protected void onProgressUpdate(String... values)
{
super.onProgressUpdate(values);
}
}
You cannot return a value. But you can update the UI in onPostExecute(). Remove all super calls in your asynctask.
you should override onPostExecute!! you can access your UI from this function and the inputs of this function is the result of doInBackground!!
I am currently working with the tab host and fragment. Currently I set fragment a to download json A and fragment B to download json B , the problem is when I switch fragment, the fragment A onPostExecute function will fall into the fragment B one , is there any way to fix this?
Thanks
Tab host:
tabHost = (FragmentTabHost) findViewById(R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), R.id.tabcontent);
tabHost.addTab(
tabHost.newTabSpec("Home").setIndicator("",
res.getDrawable(R.drawable.btn_about)), Home.class,
null);
tabHost.addTab(
tabHost.newTabSpec("About").setIndicator("",
res.getDrawable(R.drawable.btn_about)), About.class,
null);
The async task
public class JSONReader {
public static final String TAG = "JSONReader";
public ArrayList<Record> records;
public Record myRecordObj;
public ArrayList<GalleryImage> images;
public String url;
public int failCount = 0; // retry twice
public Context ctx;
public String readCase;
public JSONReader(String _url, Context _ctx , String _readCase) {
url = _url;
ctx = _ctx;
readCase = _readCase;
}
public void getJSON() {
new JSONDownload().execute(url);
}
private class JSONDownload extends AsyncTask<String, Void, JSONObject> {
// TODO Auto-generated method stub
StringBuilder builder = new StringBuilder();
String temp = "";
String json = ""; // json content
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
#Override
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
try {
Log.d(TAG, "Start reading: " + url);
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
return null;
// return "Server returned HTTP " + connection.getResponseCode()
// + " " + connection.getResponseMessage();
input = connection.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(input));
while ((temp = reader.readLine()) != null) {
builder.append(temp);
}
json = builder.toString();
} catch (Exception e) {
return null;
} finally {
try {
if (input != null)
input.close();
if (output != null)
output.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
try {
return new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(JSONObject result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
onJSONDownloaded(result);
}
}
public void onJSONDownloaded(JSONObject result) {
// TODO Auto-generated method stub
if (result != null) {
failCount = 0;
if (readCase.equals("leaderBoard")){
records = new ArrayList<Record>();
try {
JSONObject myRecord = result.getJSONObject("myRecord");
if (myRecord != null) {
myRecordObj = new Record(myRecord.getString("pic"),myRecord.getString("name"),myRecord.getString("score"));
}
JSONArray topRecords = result.getJSONArray("topRecord");
for (int i = 0; i < topRecords.length(); i++) {
JSONObject topRecord = topRecords.getJSONObject(i);
String topName = topRecord.getString("name");
String topPic = topRecord.getString("pic");
String topScore = topRecord.getString("score");
records.add(new Record(topPic, topName, topScore));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
((LeaderBoardDetail)ctx).setData(records,myRecordObj);
} else if (readCase.equals("galleryList")){
images = new ArrayList<GalleryImage>();
try {
JSONArray imageList = result.getJSONArray("images");
for (int i = 0; i < imageList.length(); i++) {
JSONObject image = imageList.getJSONObject(i);
images.add(new GalleryImage(image.getString("url"),image.getString("thumbUrl"),image.getString("category"),image.getString("userPic"),image.getString("name")));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//exception
if (((FragmentActivity) ctx).getSupportFragmentManager().findFragmentById(R.id.tabcontent).getTag().equals("Gallery")) {
PhotoGallery galleryFragment = (PhotoGallery) ((FragmentActivity) ctx).getSupportFragmentManager().findFragmentById(R.id.tabcontent);
galleryFragment.setData(images);
}
}
} else {
if (failCount <= 1) { // check global_conf twice if fail
failCount++;
Log.d(TAG, "No of retry" + failCount);
new JSONDownload().execute(url); // Retry download json
} else {
failCount = 0;
}
}
}
}
I used it in my app this way which works for me and answer is a bit similar to another answer but few additions and more detail. Hope it help you too.
NOTE: This is just a idea, u need to try, it may vary as per your app architect.
At your activity make the task object global [make sure set task obj null once task is finish]
JSDownload js = null;
public void getJSON() {
if(js != null && js.getStatus() == AsyncTask.Status.RUNNING)
{
js.cancel(true);
if(js.isCancelled())
{
js = new JSONDownload();
js.execute(url);
}
else
{
js = new JSONDownload();
js.execute(url);
}
}
At the Async class side....[make sure u take care null result # onpostExcute]
class JSONDownload extends AsyncTask<String, Void, JSONObject>
{
protected JSONObject doInBackground(String... params) {
// TODO Auto-generated method stub
try {
if(!this.isCancelled())
{
//make http connection ..
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
//as we are in steps in bg check iscancel .. again
//if its a loop here we call break; and return null once only..
if(this.isCancelled())
return null;
// connection status check and get buffer etc .. code here
if(this.isCancelled())
return null;
//read data
return data;
}
} catch (Exception e) {
return null;
}
}
#Override
protected void onCancelled(){
// If you write your own implementation, do not call super.onCancelled(result).
}
}
Use the global async task variable
LongOperation LongOperationOdeme = new LongOperation();
and set:
LongOperationOdeme.cancel(true);
This will stop any async task running at that moment, it's what the back button does
If you are not looking for a simplest answer but for a maybe more interesting and elegant, have a peek at this article, especially if you find functional programming interesting.
It's easier than it looks, i was almost unfamiliar to FP before this article but it covers common problems related to AsyncTask and asynchronicity in Android in general, so I got the gist and consider to use Observables instead of AsyncTask in the future projects myself. It is RxJava and it can solve your problem gracefully: "The fromFragment call transforms the given source observable in such a way that events will only be emitted to the fragment if it’s still alive and attached to its host activity."
One more citation form the article: "What if the user decides to back out of the Activity that triggered the task, and we are holding on to a stale reference. This not only creates a substantial memory leak, but is also worthless because meanwhile it has been detached from the application window. A problem that everyone is well aware of."
I am creating an Android application. In that, I am showing the result by parsing an XML file that is stored in the SD card of the mobile. But it is taking more than one minute to parse the XMl file.
So for this I have implemented the AsyncTask functionality, but still it is taking more than one min.
The same code, if I am running as a Java application for parsing the XML, is taking 3-5 seconds to parse the complete XML and printing the data.
Parsing code
public class ParseMyTripResponseXML {
String aprovedStatus="";
SetFlightRecordsData objFlight;
public MyTripRespone parseMyTripXML(File filename) {
MyTripRespone respObj = new MyTripRespone();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = null;
CorporateBookingApprovals corpApprovalObj = null;
List<CorporateBookingApprovals> corpApprovalList = new ArrayList<CorporateBookingApprovals>();
try {
dBuilder = dbFactory.newDocumentBuilder();
}
catch (ParserConfigurationException e) {
e.printStackTrace();
}
Document doc = null;
try {
doc = dBuilder.parse(filename);
}
catch (SAXException e) {
Log.d("SAXException", e.getMessage()+"");
}
catch (IOException e) {
Log.d("IOException", e.getMessage()+"");
}
doc.getDocumentElement().normalize();
Node rootNode = doc.getElementsByTagName("Root").item(0);
Element rootElement = (Element) rootNode;
String status = getTagValue("StatusCode", rootElement);
if (status.equals("200")) {
NodeList corpList = ((Element) doc.getElementsByTagName("Result").item(0)).getElementsByTagName("CorporateBookingApprovals");
for (int i = 0; i < corpList.getLength(); i++) {
try {
Node corporateDetailsNode = corpList.item(i);
Element corporateDetailsElement = (Element) corporateDetailsNode;
corpApprovalObj = new CorporateBookingApprovals();
corpApprovalObj.setApprovalId(getTagValue("ApprovalId", corporateDetailsElement));
corpApprovalObj.setAgentId(getTagValue("AgentId", corporateDetailsElement));
String statusApproval = getTagValue("ApprovalStatus", corporateDetailsElement);
if(statusApproval.equals("approved")){
aprovedStatus = "A";
}else if (statusApproval.equals("pending")) {
aprovedStatus = "P";
}
else if (statusApproval.equals("inqueue")) {
aprovedStatus = "Q";
}
else if (statusApproval.equals("rejected")) {
aprovedStatus = "R";
}
corpApprovalObj.setApprovalStatus(aprovedStatus);
corpApprovalObj.setInsertTime(getTagValue("InsertTime", corporateDetailsElement));
objFlight = new SetFlightRecordsData();
objFlight.setFlightData(doc, corpApprovalObj);
corpApprovalList.add(corpApprovalObj);
}
catch (Exception e) {
Log.d("exception in main", e.getMessage()+"");
continue;
}
}
respObj.setCoroprateBookingDetails(corpApprovalList);
}
return respObj;
}
public static String getTagValue(String sTag, Element eElement) {
NodeList nlList = eElement.getElementsByTagName(sTag).item(0)
.getChildNodes();
Node nValue = (Node) nlList.item(0);
if (nValue == null) {
return "";
}
else {
return nValue.getNodeValue();
}
}
How do I make it faster?
I am using the DOM parser.
I suggest the general approach to speeding up your XML parse routine by adding timer functions and process of elimination, commenting out sections and rerunning it so you know exactly what is causing your slow down. Usual suspects would be object creation calls and string handling.
long startTime;
long endTime;
startTime = android.os.SystemClock.uptimeMillis();
// parse routine here
endTime = android.os.SystemClock.uptimeMillis();
Log.d("xmlparse", "Excution time: "+(endTime-startTime)+" ms");
I have this code here that worked all this time in 2.3 now we have to update it and I am getting a lot of errors like NetworkOnMainThreadException. I want to go and grab a xml from my web service, bring it down and parse it into an array list. Here is the code
//Gets the xml from the url specified
String CallWebService(String url){
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
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;
}
//Parses the xml to get DOM element
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 DOM
return doc;
}
//Gets the child nodes of the xml
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
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 || child.getNodeType() == Node.CDATA_SECTION_NODE){
return child.getNodeValue();
}
}
}
}
return "";
}
I also have a getChildElements method. The problem is when I call this method. I used to do so like this:
String serviceURL = "http://webservice.example.com/";
String xml = CallWebService(serviceURL);
Document doc = GetDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl);
But now in 4.1 I need to do this asynchronously and I don't know how. Any help will be greatly appreciated.
EDIT
Here is what i have bu the Thread does not start
final String serviceURL = "urlString";
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == JOB_COMPLETE) {
String xml = (String) msg.obj;
Document doc = GetDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl);
}
super.handleMessage(msg);
}
};
Thread t = new Thread() {
#Override
public void run() {
String xml = CallWebService(serviceURL);
Message msg = Message.obtain(mHandler, JOB_COMPLETE, xml);
msg.sendToTarget();
}
};
t.start();
EDIT
So I am trying the async way and it still wont work. Its not hitting the GetDomElement at all. Here is the code.
//I call this in my onCreate()
new getAppInfo().execute("http://webservice.example.com");
private class getAppInfo extends AsyncTask<String, Void, String> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected String doInBackground(String... urls) {
return CallWebService(urls[0]);
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(String xml) {
Document doc = GetDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName("details");
getChildElements(nl);
}
}
You have to implement an AsyncTask:
http://developer.android.com/reference/android/os/AsyncTask.html
Btw this is needed from Android 3 (if I remember well).
I've implemented this in my app, you can browse my code here: https://github.com/enrichman/roma-tre/blob/master/src/com/roma3/infovideo/utility/rss/RssTask.java
Hope this help
http://www.techrepublic.com/blog/app-builder/using-androids-asynctask-to-handle-long-running-io/670?pg=2&tag=content;siu-container
Define a Handler in your main ui thread in activity onCreate for example
private Handler mHandler;
private static int JOB_COMPLETE = 1;
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if(msg.what == JOB_COMPLETE) {
String xml = (String) msg.obj;
// do whatever you want with that string
}
super.handleMessage(msg);
}
};
Then run all your long jobs in background thread
final String url = "...........";
Thread t = new Thread() {
#Override
public void run() {
String xml = CallWebService(url);
Message msg = Message.obtain(mHandler, JOB_COMPLETE, xml);
msg.sendToTarget();
}
};
t.start();
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged
see android developers page
Do your network related task using Async task or try using safe threads