-1

Head First AndroidNASA の Image of the Day から RSS フィードを取得するために、displayのコードを変更しました。を使用AsyncTaskしてデータを取得し、それを UI スレッドに戻して更新することにしました。ただし、ここでいくつかの奇妙な結果が得られます。
ここに画像の説明を入力 ここに画像の説明を入力 右がボタンクリック後のUIです。十分に奇妙です。

以下は私のコードですActivity

package com.example.nasadailyimage;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;

public class NasaDailyImage extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button b = (Button) findViewById(R.id.button);
        //get feeds only when button is clicked!
        b.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                new AsyncRetriever().execute(new IotdHandler()); // Get the feeds !!
            }
        });
    }
//------------------------------------------------------------------------------
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.nasa_daily_image, menu);
        return true;
    }
//------------------------------------------------------------------------------
    /**
     * This method is called by onPostExecute and is used to update the UI.
     * It first checks if an error occured while parsing the RSS feed.
     * If yes, it displays "Error" in all TextViews and displays an 
     * AlertDialog.
     * Else, it displays the new data.
     * @param hasErrorOccured
     * @param reply
     */
    public synchronized void resetDisplay(boolean hasErrorOccured,IotdHandler reply){
        if(hasErrorOccured){

            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                    this);

                // set title
                alertDialogBuilder.setTitle("An error has occured while retrieving feed");

                // set dialog message
                alertDialogBuilder
                    .setMessage("Click to exit")
                    .setCancelable(false)
                    .setNegativeButton("Exit",new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog,int id) {
                            // if this button is clicked, just close
                            // the dialog box and do nothing
                            dialog.cancel();
                        }
                    });
                // create alert dialog
                AlertDialog alertDialog = alertDialogBuilder.create();

                // show it
                alertDialog.show();


            TextView textHeader = (TextView) findViewById(R.id.textHeader);
            TextView date = (TextView) findViewById(R.id.date);
            ImageView img = (ImageView) findViewById(R.id.image);
            TextView desc = (TextView) findViewById(R.id.desc);

            textHeader.setText("Error");
            date.setText("Error");
            desc.setText("Error");

            return;
        }else{
            TextView textHeader = (TextView) findViewById(R.id.textHeader);
            TextView date = (TextView) findViewById(R.id.date);
            ImageView img = (ImageView) findViewById(R.id.image);
            TextView desc = (TextView) findViewById(R.id.desc);

            textHeader.setText(reply.getTitle());
            date.setText(reply.getDate());
            img.setImageBitmap(reply.getImage());
            desc.setText(reply.getDescription());
        }
    }
//------------------------------------------------------------------------------
    /**
     * This class retrieves data from the RSS feed. I am using AsyncTask because
     * it is not a good practice to block the UI thread while performing 
     * network operations.
     *
     */
    class AsyncRetriever extends AsyncTask<IotdHandler,Void,IotdHandler>{

        @Override
        protected IotdHandler doInBackground(IotdHandler... arg0) {
            IotdHandler handler = arg0[0];
            handler.processFeed(); // get the RSS feed data !
            return handler;
        }
//------------------------------------------------------------------------------    
        @Override
        protected void onPostExecute(IotdHandler fromInBackground){
            resetDisplay(fromInBackground.errorOccured,fromInBackground);
        }
//------------------------------------------------------------------------------
    }
}  

IotdHandler

public class IotdHandler extends DefaultHandler{
    private String url = "http://www.nasa.gov/rss/image_of_the_day.rss";
    /**
     * Since the events  get called differently, you need to keep
     * a track of which tag you are in.
     */

    private boolean inTitle = false;
    private boolean inDescription = false;
    private boolean inItem = false;
    private boolean inDate = false;
    public boolean errorOccured = false;
    boolean firstItemHit = false;

    private Bitmap image = null;
    private String title = null;
    private StringBuffer description = new StringBuffer();
    private String date = null;
//------------------------------------------------------------------------------
    public void processFeed(){
        try{
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            InputStream stream = new URL(url).openStream();
            parser.parse(stream, this);
        }catch(Exception e){
            errorOccured = true;
        }
    }
//------------------------------------------------------------------------------
    private Bitmap getBitmap(String url){
        try{
            HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection();
            con.setDoInput(true);
            con.connect();
            InputStream input = con.getInputStream();
            Bitmap bmp = BitmapFactory.decodeStream(input);
            input.close();
            return bmp;
        }catch(Exception e){
            errorOccured = true;
            return null;
        }
    }
//------------------------------------------------------------------------------
    @Override
    public void startElement(String uri,String localName,String qName, 
            Attributes attr) throws SAXException{
            if(localName.equals("item")){ 
                if(localName.equals("title")){inTitle = true;}
                if(localName.equals("description")){inDescription = true;}
                if(localName.equals("pubDate")){inDate = true;}
                if(localName.equals("enclosure")){
                    String url = attr.getValue(0);
                    getBitmap(url);
                }
            }

    }
//------------------------------------------------------------------------------
    @Override
    public void characters(char[] ch,int start,int length){
        String charData = new String(ch);
            if(inTitle){
                title = charData;
            }
            if(inDescription){
                description.append(charData);
            }
            if(inDate){
                date = charData;
            }
    }
//------------------------------------------------------------------------------
    public Bitmap getImage(){return image;}
    public String getTitle(){return title;}
    public StringBuffer getDescription(){return description;}
    public String getDate(){return date;}
//------------------------------------------------------------------------------
}

これを解決するにはどうすればよいですか?

4

1 に答える 1

2

問題は IotdHandler の startElement 関数にあると思います

基本的に、localName が「item」に等しいかどうかを確認し、その if ブロック内で localName が「title」、「description」などに等しいかどうかを確認します。 localName が「item」に等しい場合に評価される

チェックを外すことができます

if(localName.equals("アイテム"))

これらの内部の if ステートメントが true と評価される可能性があるか、タイトル、説明などの一致が item ノード内にあることを確認したい場合は、次のように変更できます。

        if(localName.equals("item")){inItem = true;}
        if(inItem){
            if(localName.equals("title")){inTitle = true;}
            if(localName.equals("description")){inDescription = true;}
            if(localName.equals("pubDate")){inDate = true;}
            if(localName.equals("enclosure")){
                String url = attr.getValue(0);
                getBitmap(url);
            }
        }

ブロック内にいるかどうかを判断するために使用しているすべてのブール値では、endElement 関数 ala をオーバーライドして、それらを false に設定する必要があります。

@Override
public void endElement(String uri,String localName,String qName) throws SAXException{
        if(localName.equals("item")){inItem = false;}
        if(localName.equals("title")){inTitle = false;}
        if(localName.equals("description")){inDescription = false;}
        if(localName.equals("pubDate")){inDate = false;}
}
于 2013-07-23T05:32:58.643 に答える