0

サーバー上のURLからフィードを取得するために非同期タスク内で関数を実行していますが、インターネット接続がない場合はエラーメッセージが表示されてアプリケーションが停止します。

これを処理する方法がわかりません、とにかくここに私のコードがあります

フィードをフェッチする機能

   public void getContent(){
    // Initializing instance variables
    headlines = new ArrayList<String>();
    links = new ArrayList<String>();
    server_images = new ArrayList<String>();

    try {
        URL url = new URL("http://www.uglobal.org/androidServer/courses_list.xml");

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(false);
        XmlPullParser xpp = factory.newPullParser();

            // We will get the XML from an input stream
        xpp.setInput(getInputStream(url), "UTF_8");

            /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
             * However, we should take in consideration that the rss feed name also is enclosed in a "<title>" tag.
             * As we know, every feed begins with these lines: "<channel><title>Feed_Name</title>...."
             * so we should skip the "<title>" tag which is a child of "<channel>" tag,
             * and take in consideration only "<title>" tag which is a child of "<item>"
             *
             * In order to achieve this, we will make use of a boolean variable.
             */
        boolean insideItem = false;

            // Returns the type of current event: START_TAG, END_TAG, etc..
        int eventType = xpp.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG) {

                if (xpp.getName().equalsIgnoreCase("item")) {
                    insideItem = true;
                } else if (xpp.getName().equalsIgnoreCase("title")) {
                    if (insideItem)
                        headlines.add(xpp.nextText()); //extract the headline
                } else if (xpp.getName().equalsIgnoreCase("link")) {
                    if (insideItem)
                        links.add(xpp.nextText()); //extract the link of article
                } else if (xpp.getName().equalsIgnoreCase("image")) {
                    if (insideItem)
                        server_images.add(xpp.nextText()); //extract the link of article
                }
            }else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
                insideItem=false;
            }

            eventType = xpp.next(); //move to next element
        }

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public InputStream getInputStream(URL url) {
   try {
       return url.openConnection().getInputStream();
   } catch (IOException e) {
       return null;
     }
}

非同期タスク内でこの関数を実行するより

非同期タスク

    private class PostTask extends AsyncTask<String, Integer, String>{
    @Override

    protected void onPreExecute() {
        // TODO Auto-generated method stub
        progressDialog = ProgressDialog.show(ListViewImagesActivity.this, "Loading","Getting Feed ", true);
    }
    protected String doInBackground(String... arg0) {
        getContent();
        return null;
    }
    }

これで、インターネットに接続している場合は正常に機能しますが、接続を失うと、「アプリケーションが応答していません」というエラーでアプリケーションが強制終了されます。

ConnectivityManagerに依存したくない理由

Connectivity Managerはインターネット接続を探すだけですが、プロキシの背後で実行していて、インターネットにアクセスするためにプロキシサーバーにログインする必要がある場合はどうなりますか?

少なくとも私のアプリケーションが強制終了されるのを防ぐ方法はありますか?

4

1 に答える 1

2

素早い回答

確かに、try / catchブロックで例外を処理します。IDEが関数が例外をスローすることを通知しない場合でも、それらを発生させることができます。実際、それは今のところあなたのケースのようです。

完全にオフラインでアプリケーションを実行し、例外を発生させるすべての行をtry / catchブロックでラップしてみてください(もちろん、すべての例外をキャッチする限り、「問題のある」コード全体に対して1回のtry / catchで十分です)。


ヒントとコツ

ConnectivityManagerに依存したくないのは?それは悪い考えです。ConnectivityManagerは、大学のプロキシなどのエッジケースを処理しない場合がありますが、それでも保護レイヤーです。特に携帯電話では、事前に接続が失敗することが常にわかっている接続を開始する貴重な計算時間を無駄にしたくありません。

上級者向けのヒント:ダウンロードした文字列をXMLパーサーにフィードする前に、自分のコードにプロキシが存在するかどうかを確認することをお勧めします。最初の行を確認するだけです。そのWebサービスが適切なXMLを出力する場合、そのWebサービスには次のようなものが含まれている可能性があります。

<?xml version="1.0" encoding="UTF-8" ?>

したがって、最初の行が類似したもので始まっていない場合は、XMLではないことを確認できます。

逆に、リクエストの最初の行が次のようなものであるかどうかを確認することで、リクエストがプロキシログインページに乗っ取られたかどうかを知ることができます。

<!DOCTYPE....

また

<html....

これは非常に簡単で、httpプロキシの古典的な動作です。

このリンクを確認してください(readTwitterFeed()メソッドに特に注意してください)。XML用ではない場合でも、Androidで標準のRESTful WebService呼び出しがどのように行われるかを確認するのに役立ちます(少なくとも一方通行)。繰り返しになりますが、そのRESTful呼び出しからの出力を、上記で説明したフィルターに接続してから、お気に入りのXMLパーサーに接続するだけです(出力がこれらのサニテーションチェックに合格したと仮定します)。

結論は次のとおりです。自分の仕事をそれほど難しくしないでください。車輪の再発明をしないで、利用可能なものを巧妙な方法で使用してください。

乾杯。

于 2013-01-17T09:48:03.093 に答える