2016-04-25 98 views
0

因此,我正在从基于天气的应用程序中抽取XML,从雅虎天气api中解析并显示信息。我有一个异步任务,在doInBackground方法中拉取xml并使用stringBuilder保存xml,然后在onPostExecute中将XML解析为我需要的格式。我试图在post执行中在mCondImg ImageView中设置图像,看起来似乎无法使其工作。最后,我想有condImg在每个XML代码更改WeatherApp,在解析XML时使用setImageResource()设置内部图像和AsyncTask()

公共API调用: https://query.yahooapis.com/v1/public/yql?q=select%20 *%20from%20weather.forecast%20where%20woeid%20英寸%20(选择%20woeid%20from%20geo.places (1)%20where%20text%3D%22warrensburg%2C%20mo%22)&格式= XML & ENV =商店%3A%2F%2Fdatatables.org%2Falltableswithkeys

WeatherFragment.java(包含所有的片段实际解析的axml和asynctask类)

import android.app.ProgressDialog; 
import android.content.Context; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Handler; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.TextView; 

import org.xmlpull.v1.XmlPullParser; 
import org.xmlpull.v1.XmlPullParserFactory; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.io.StringReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 



    public class WeatherFragment extends Fragment { 

     static TextView mLocation, mCondition, mForecast1, mForecast2, mForecast3, mForecast4, mForecast5; 
     Handler handler; 
     ImageView mCondImg; 



    private OnFragmentInteractionListener mListener; 

    public WeatherFragment() { 
     handler = new Handler(); 
    } 

    public static WeatherFragment newInstance(String param1, String param2) { 
     WeatherFragment fragment = new WeatherFragment(); 
     Bundle args = new Bundle(); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_weather, container, false); 
     mLocation = (TextView) rootView.findViewById(R.id.location); 
     mCondition = (TextView) rootView.findViewById(R.id.condition); 
     mForecast1 = (TextView) rootView.findViewById(R.id.forecast1); 
     mForecast2 = (TextView) rootView.findViewById(R.id.forecast2); 
     mForecast3 = (TextView) rootView.findViewById(R.id.forecast3); 
     mForecast4 = (TextView) rootView.findViewById(R.id.forecast4); 
     mForecast5 = (TextView) rootView.findViewById(R.id.forecast5); 
     mCondImg = (ImageView) rootView.findViewById(R.id.condImg); 
     new RetrieveData().execute(); 
     return rootView; 
    } 

    // TODO: Rename method, update argument and hook method into UI event 
    public void onButtonPressed(Uri uri) { 
     if (mListener != null) { 
      mListener.onFragmentInteraction(uri); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mListener = null; 
    } 

    public interface OnFragmentInteractionListener { 
     void onFragmentInteraction(Uri uri); 
    } 

    public void changeCity(String city){ 
     //updateWeatherData(city); 
    } 
} 

class RetrieveData extends AsyncTask<Void, Void, String> { 

    public static String str; 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
    } 

    @Override 
    protected String doInBackground(Void... urls) { 
     try { 
      URL url = new URL("https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22warrensburg%2C%20mo%22)&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"); 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
      try { 
       BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); 
       StringBuilder stringBuilder = new StringBuilder(); 
       String line; 
       while ((line = bufferedReader.readLine()) != null) { 
        stringBuilder.append(line).append("\n"); 
       } 
       bufferedReader.close(); 
       str = stringBuilder.toString(); 

       return stringBuilder.toString(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return "Error getting weather data"; 
    } 


    protected void onPostExecute(String response) { 
     if (response == null) { 
      response = "Error"; 
     } 

     // Parse xml 
     try { 
      int forecastCounter = 1; 
      XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 
      XmlPullParser parser = factory.newPullParser(); 
      parser.setInput(new StringReader(str)); 
      String tagName = null; 
      int event = parser.getEventType(); 

      while (event != XmlPullParser.END_DOCUMENT) { 
       tagName = parser.getName(); 
       if (event == XmlPullParser.START_TAG) { 

        if (tagName.equals("yweather:location")) { 
         WeatherFragment.mLocation.setText(parser.getAttributeValue(null, "city")); 
         WeatherFragment.mLocation.append(", " + parser.getAttributeValue(null, "region")); 

        } 
        else if (tagName.equals("yweather:condition")) { 
         WeatherFragment.mCondition.setText("Current temperature: " + parser.getAttributeValue(null, "temp") + "\nCurrent conditions: " + parser.getAttributeValue(null, "text")); 
         if (tagName.equals("yweather:code")) { 
          mCondImg.setImageResource(R.drawable.ic_snow); 
         } 
        } 
        else if (tagName.equals("yweather:forecast")) { 
         switch (forecastCounter) { 
          case 1: 
           WeatherFragment.mForecast1.setText(parser.getAttributeValue(null, "day") + " - High: " + parser.getAttributeValue(null, "high") + " - Low: " + parser.getAttributeValue(null, "low") + " - " + parser.getAttributeValue(null, "text")); 
           forecastCounter++; 
           if (WeatherFragment.mCondition.getText().equals("28")) { 
            //WeatherFragment.mCondImg.setImageResource(R.drawable.ic_sunny);//This works 
           } 
           break; 
          case 2: 
           WeatherFragment.mForecast2.setText(parser.getAttributeValue(null, "day") + " - High: " + parser.getAttributeValue(null, "high") + " - Low: " + parser.getAttributeValue(null, "low") + " - " + parser.getAttributeValue(null, "text")); 
           forecastCounter++; 
           break; 
          case 3: 
           WeatherFragment.mForecast3.setText(parser.getAttributeValue(null, "day") + " - High: " + parser.getAttributeValue(null, "high") + " - Low: " + parser.getAttributeValue(null, "low") + " - " + parser.getAttributeValue(null, "text")); 
           forecastCounter++; 
           break; 
          case 4: 
           WeatherFragment.mForecast4.setText(parser.getAttributeValue(null, "day") + " - High: " + parser.getAttributeValue(null, "high") + " - Low: " + parser.getAttributeValue(null, "low") + " - " + parser.getAttributeValue(null, "text")); 
           forecastCounter++; 
           break; 
          case 5: 
           WeatherFragment.mForecast5.setText(parser.getAttributeValue(null, "day") + " - High: " + parser.getAttributeValue(null, "high") + " - Low: " + parser.getAttributeValue(null, "low") + " - " + parser.getAttributeValue(null, "text")); 
           forecastCounter++; 
           break; 
         } 

        } 
       } 
       event = parser.next(); 
      } 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
     //mWeatherData.setText(str); 

    } 

} 

WeatherFragment.x ml(用于设计片段样式)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center" 
    android:orientation="vertical" > 


    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="-140sp" 
     android:textSize="30sp" 
     android:id="@+id/location"/> 

    <ImageView 
     android:layout_width="300px" 
     android:layout_height="300px" 
     android:src="@drawable/ic_sunny" 
     android:id="@+id/condImg" 
     /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left" 
     android:layout_marginLeft="15sp" 
     android:layout_marginBottom="7sp" 
     android:id="@+id/condition"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:layout_marginBottom="10sp" 
     android:textSize="20sp" 
     android:text="@string/multiForecast" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left" 
     android:layout_marginLeft="15sp" 
     android:layout_marginBottom="7sp" 
     android:id="@+id/forecast1" /> 


    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left" 
     android:layout_marginLeft="15sp" 
     android:layout_marginBottom="7sp" 
     android:id="@+id/forecast2" /> 



    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left" 
     android:layout_marginLeft="15sp" 
     android:layout_marginBottom="7sp" 
     android:id="@+id/forecast3" /> 


    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left" 
     android:layout_marginLeft="15sp" 
     android:layout_marginBottom="7sp" 
     android:id="@+id/forecast4" /> 



    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="left" 
     android:layout_marginLeft="15sp" 
     android:layout_marginBottom="7sp" 
     android:id="@+id/forecast5" /> 

    <!--<ScrollView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 


    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/weather_data" 
     /> 

    </ScrollView>--> 

</LinearLayout> 
+0

不相关的问题,但你应该在'doInBackground()'中解析XML,而不是在'onPostExecute()'中解析 – Karakuri

回答

0

问题是您要将代码中的名称空间添加到代码中。例如,给定本文标签:

<yweather:condition 
    xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" 
    code="29" 
    date="Sun, 24 Apr 2016 09:00 PM CDT" 
    temp="68" 
    text="Partly Cloudy" /> 

标记名称"condition",不"yweather:condition"。命名空间是"yweather"。您的正确的标签检查应该是这样的:

if ("condition".equals(tagName)) 

如果你还需要检查的命名空间相匹配,你可以做这样的:

if ("condition".equals(tagName) && "yweather".equals(parser.getNamespace()) 

值得一提的是,你的代码在主(UI)线程上执行XML解析,因为你正在使用onPostExecute()。您应该在doInBackground()内部进行解析; 应仅保留用于修改UI的最小数量的代码。

您可以利用的事实,AsyncTask是参数化,并具有doInBackground()返回一个类定义来保存解析的结果,就像这样:

private static class WeatherResults { 
    private int conditionImage; 
    private String condition; 
    private String location; 
    ... 
} 

class RetrieveData extends AsyncTask<Void, Void, WeatherResults> { 
    @Override 
    protected String doInBackground(Void... params) { 
     WeatherResults weatherResults = new WeatherResults(); 
     // make web call 
     // parse XML and set results, e.g. 
     // weatherResults.conditionImage = R.drawable.ic_snow; 

     return weatherResults; 
     // you can return null instead if there's an error 
    } 

    @Override 
    protected void onPostExecute(WeatherResults result) { 
     if (result == null) { 
      // show error state 
      return; 
     } 

     // update the UI 
     mCondImg.setImageResource(result.conditionImage); 
     // etc. 
    } 
}