Java android weather application hangs/freezes when entering wrong city name -
i new android programming , first app. iam using eclipse ide , run app on samsung galaxy s4. application works great when enter city name exists. when enter city name doesn't exist freezes , lags lot. can't click on button or can't edit text. using api.openweathermap.org obtain weather information in xml format, parse , show on screen. if try information city unrecognized such reply : {"message":"error: not found city","cod":"404"}
in json format. tried find solution don't know if correct , why application hangs. tried convert reply form api string , check if contains "404"
or not. post source code below :
mainactivity.java :
package com.example.michal.myapplication; import com.example.michal.myapplication.r; import android.content.context; import android.content.intent; import android.content.sharedpreferences; import android.graphics.color; import android.graphics.typeface; import android.support.v7.app.actionbaractivity; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.provider.settings; import android.view.menu; import android.view.menuitem; import android.view.view; import android.webkit.urlutil; import android.widget.button; import android.widget.edittext; import android.widget.textview; import android.widget.toast; public class mainactivity extends appcompatactivity { edittext texteditmiasto,texteditkraj,textedittemperatura,texteditwilgotnosc,texteditcisnienie; private string urladres = "http://api.openweathermap.org/data/2.5/weather?q="; private string urltryb = "&mode=xml"; private myxmlparser obj; button btnok,btnclear; protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); btnok=(button)findviewbyid(r.id.button); btnclear=(button)findviewbyid(r.id.buttonclr); texteditmiasto=(edittext)findviewbyid(r.id.edittext); texteditkraj=(edittext)findviewbyid(r.id.edittext2); textedittemperatura=(edittext)findviewbyid(r.id.edittext3); texteditwilgotnosc=(edittext)findviewbyid(r.id.edittext4); texteditcisnienie=(edittext)findviewbyid(r.id.edittext5); texteditmiasto.settextcolor(color.white); texteditkraj.settextcolor(color.white); textedittemperatura.settextcolor(color.white); texteditwilgotnosc.settextcolor(color.white); texteditcisnienie.settextcolor(color.white); /* intent addaccountintent = new intent(settings.action_add_account); addaccountintent.setflags(intent.flag_activity_new_document); addaccountintent.putextra(settings.extra_authorities, new string[]{"com.example.michal.myapplication"}); startactivity(addaccountintent); */ btnok.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { string url = texteditmiasto.gettext().tostring(); string finalurl = urladres + url + urltryb; texteditkraj.settext(finalurl); obj = new myxmlparser(finalurl); obj.fetchxml(); while(obj.parsingcomplete); texteditkraj.settext("kraj : "+obj.getkraj()); textedittemperatura.settext("temperatura : "+obj.gettemperatura()+" "+obj.gettemperaturaunit()); texteditwilgotnosc.settext("wilgotnosc : "+obj.getwilgotnosc()+" "+obj.getwilgotnoscunit()); texteditcisnienie.settext("cisnienie : "+obj.getcisnienie()+" "+obj.getcisnienieunit()); } }); btnclear.setonclicklistener(new view.onclicklistener() { @override public void onclick(view arg0) { texteditmiasto.settext(""); texteditkraj.settext(""); textedittemperatura.settext(""); texteditwilgotnosc.settext(""); texteditcisnienie.settext(""); } }); } @override public boolean oncreateoptionsmenu(menu menu) { // inflate menu; adds items action bar if present. // getmenuinflater().inflate(r.menu.menu_mai\, menu); return true; } @override public boolean onoptionsitemselected(menuitem item) { // handle action bar item clicks here. action bar // automatically handle clicks on home/up button, long // specify parent activity in androidmanifest.xml. int id = item.getitemid(); //noinspection simplifiableifstatement if (id == r.id.action_settings) { return true; } return super.onoptionsitemselected(item); } }
myxmlparser.java :
package com.example.michal.myapplication; import org.xmlpull.v1.xmlpullparser; import org.xmlpull.v1.xmlpullparserexception; import org.xmlpull.v1.xmlpullparserfactory; import android.webkit.urlutil; import android.widget.toast; import java.io.bufferedinputstream; import java.io.ioexception; import java.io.inputstream; import java.io.sequenceinputstream; import java.io.stringbufferinputstream; import java.io.stringreader; import java.io.stringwriter; import java.net.httpurlconnection; import java.net.url; import java.nio.buffer; import org.apache.commons.io.ioutils; public class myxmlparser { private string kraj = "county"; private string temperatura = "temperature"; private string wilgotnosc = "humidity"; private string cisnienie = "pressure"; private string temperaturaunit=" "; private string wilgotnoscunit=" "; private string cisnienieunit=""; private string urlstring = " "; private xmlpullparserfactory xmlfactoryobject; public volatile boolean parsingcomplete = true; boolean flaga=true; public void setkraj(string kraj) { this.kraj = kraj; } public void settemperatura(string temperatura) { this.temperatura = temperatura; } public void setwilgotnosc(string wilgotnosc) { this.wilgotnosc = wilgotnosc; } public void setcisnienie(string cisnienie) { this.cisnienie = cisnienie; } public void settemperaturaunit(string temperaturaunit) { this.temperaturaunit = temperaturaunit; } public void setwilgotnoscunit(string wilgotnoscunit) { this.wilgotnoscunit = wilgotnoscunit; } public void setcisnienieunit(string cisnienieunit) { this.cisnienieunit = cisnienieunit; } public myxmlparser(string url){ this.urlstring = url; } public string getkraj(){ return kraj; } public string gettemperatura(){ return temperatura; } public string getwilgotnosc(){ return wilgotnosc; } public string getcisnienie(){ return cisnienie; } public void parsexmlandstoreit(xmlpullparser myparser) { int event; string text=null; boolean flaga=true; try { event = myparser.geteventtype(); //if(text.equals("{\'message\':\'error: not found city\',\'cod\':\'404\'}")==true) // return; while (event != xmlpullparser.end_document) { //if(event!=xmlpullparser.start_tag||event!=xmlpullparser.text||event!=xmlpullparser.end_tag||event == xmlpullparser.end_document) // break; string name=myparser.getname(); switch (event){ case xmlpullparser.start_tag: break; case xmlpullparser.text: text = myparser.gettext(); break; case xmlpullparser.end_tag: if(name.equals("country")){ kraj = text; } else if(name.equals("humidity")){ wilgotnosc = myparser.getattributevalue(null,"value"); wilgotnoscunit=myparser.getattributevalue(null,"unit"); } else if(name.equals("pressure")){ cisnienie = myparser.getattributevalue(null,"value"); cisnienieunit=myparser.getattributevalue(null,"unit"); } else if(name.equals("temperature")){ temperatura = myparser.getattributevalue(null,"value"); temperaturaunit=myparser.getattributevalue(null,"unit"); } else{ } break; } event = myparser.next(); } parsingcomplete = false; } catch (xmlpullparserexception e) { e.printstacktrace(); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } } public string gettemperaturaunit() { return temperaturaunit; } public string getwilgotnoscunit() { return wilgotnoscunit; } public string getcisnienieunit() { return cisnienieunit; } public void fetchxml(){ thread thread=new thread(new runnable() { @override public void run() { try { url url = new url(urlstring); httpurlconnection conn = (httpurlconnection)url.openconnection(); conn.setreadtimeout(10000 /* milliseconds */); conn.setconnecttimeout(15000 /* milliseconds */); conn.setrequestmethod("get"); conn.setdoinput(true); conn.connect(); inputstream stream = conn.getinputstream(); bufferedinputstream input=new bufferedinputstream(stream); input.mark(100000); stringwriter writer = new stringwriter(); ioutils.copy(input, writer,"utf-8"); string thestring = writer.tostring(); input.reset(); if(thestring.contains("404")==false) { xmlfactoryobject = xmlpullparserfactory.newinstance(); xmlpullparser myparser = xmlfactoryobject.newpullparser(); myparser.setfeature(xmlpullparser.feature_process_namespaces, true); myparser.setinput(input, null); parsexmlandstoreit(myparser); } writer.close(); stream.close(); conn.disconnect(); } catch (exception e) { e.printstacktrace(); } } }); thread.start(); } }
androidmanifest.xml :
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.michal.myapplication" android:installlocation="preferexternal"> <uses-permission android:name="android.permission.internet"/> <application android:allowbackup="true" android:label="@string/app_name" android:theme="@style/apptheme" > <activity android:name="com.example.michal.myapplication.mainactivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> </manifest>
logcat :
05-31 10:54:17.051: i/dalvikvm(8052): not find method android.content.res.typedarray.getchangingconfigurations, referenced method android.support.v7.internal.widget.tinttypedarray.getchangingconfigurations 05-31 10:54:17.051: w/dalvikvm(8052): vfy: unable resolve virtual method 408: landroid/content/res/typedarray;.getchangingconfigurations ()i 05-31 10:54:17.051: d/dalvikvm(8052): vfy: replacing opcode 0x6e @ 0x0002 05-31 10:54:17.051: i/dalvikvm(8052): not find method android.content.res.typedarray.gettype, referenced method android.support.v7.internal.widget.tinttypedarray.gettype 05-31 10:54:17.051: w/dalvikvm(8052): vfy: unable resolve virtual method 430: landroid/content/res/typedarray;.gettype (i)i 05-31 10:54:17.051: d/dalvikvm(8052): vfy: replacing opcode 0x6e @ 0x0002 05-31 10:54:17.101: d/dalvikvm(8052): gc_for_alloc freed 154k, 44% free 14579k/25840k, paused 19ms, total 20ms 05-31 10:54:17.131: i/dalvikvm-heap(8052): grow heap (frag case) 34.536mb 15892496-byte allocation 05-31 10:54:17.251: i/dalvikvm(8052): not find method android.content.res.resources.getdrawable, referenced method android.support.v7.internal.widget.resourceswrapper.getdrawable 05-31 10:54:17.251: w/dalvikvm(8052): vfy: unable resolve virtual method 371: landroid/content/res/resources;.getdrawable (ilandroid/content/res/resources$theme;)landroid/graphics/drawable/drawable; 05-31 10:54:17.251: d/dalvikvm(8052): vfy: replacing opcode 0x6e @ 0x0002 05-31 10:54:17.251: i/dalvikvm(8052): not find method android.content.res.resources.getdrawablefordensity, referenced method android.support.v7.internal.widget.resourceswrapper.getdrawablefordensity 05-31 10:54:17.251: w/dalvikvm(8052): vfy: unable resolve virtual method 373: landroid/content/res/resources;.getdrawablefordensity (iilandroid/content/res/resources$theme;)landroid/graphics/drawable/drawable; 05-31 10:54:17.251: d/dalvikvm(8052): vfy: replacing opcode 0x6e @ 0x0002
and after time receive :
05-31 10:55:57.008: i/dalvikvm(8052): threadid=3: reacting signal 3 05-31 10:55:57.258: d/dalvikvm(8052): jit unchain threadid=1 05-31 10:55:57.309: i/dalvikvm(8052): wrote stack traces '/data/anr/traces.txt'
thanks in advance help.
this because of how doing threading. your:
while(obj.parsingcomplete);
... locking main ui thread. don't that! use asynctask parsing in background thread , update ui in main thread on background task completion rather waiting in main ui thread , spinning off background thread manually.
Comments
Post a Comment