0

我正在使用 asynctask 从给定的 URL 下载 xml。我从首选项屏幕获取网址。ñ

现在我正在尝试捕获一些错误,以便应用程序不会崩溃,但会为错误提供一个很好的祝酒词。

如果用户忘记了 URL 之前的“http://”,它已经可以工作了。但是,当 URL 格式良好但没有任何内容可供下载时,应用程序仍然崩溃,我不知道如何捕获此错误:我认为 IOException 会捕获此错误,但事实并非如此。

@Override
protected void onPreExecute() {
    progressDialog = new ProgressDialog(mContext);
    progressDialog.setTitle("XML downloaden");
    progressDialog.setMessage("Downloading xml:");
    progressDialog.setMax(100);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.show();
}

    @Override
protected Void doInBackground(Void... params) {

    FileOutputStream fos = null;
    InputStream inputStream = null;
    HttpURLConnection conn = null;
    try {
        fos = mContext.openFileOutput("xmlapp.xml", Context.MODE_PRIVATE);

        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(mContext);
        String start = prefs.getString("pref_key_url",
                "http://sdesigns.be/eindwerk/web6/");

        URL url;
        url = new URL(start + "source/pages.xml");
        conn = (HttpURLConnection) url.openConnection();

            byte[] buffer = new byte[64];
            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                int bytesToDownload = conn.getContentLength();
                int bytesDownloaded = 0;
                inputStream = conn.getInputStream();
                int len = 0;
                while ((len = inputStream.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                    bytesDownloaded += len;
                    publishProgress((float) bytesDownloaded / bytesToDownload);
                }
                inputStream.close();
                fos.close();
            } 



    } catch (MalformedURLException e) {
        this.e = e;
    } catch (IOException e) {
        this.e = e;
    } 
    finally {
         conn.disconnect();
    }

    return null;
}

@Override
protected void onPostExecute(Void result) {

    if (progressDialog != null) {
        progressDialog.dismiss();
        progressDialog = null;
    }
    if (e == null) {
        List<String> images = new XmlParserSax(mContext).getImagesList();
        DownloadImages di = new DownloadImages(mContext);
        di.execute(images);
    } else {
        Toast.makeText(mContext,
                "Check the url!" + e.toString(),
                Toast.LENGTH_LONG).show(); //show the error
    }

}

编辑

堆栈跟踪:

    04-19 10:18:40.904: E/WindowManager(2425): Activity com.example.eindwerkappv1.Preferences has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41a97848 that was originally added here
04-19 10:18:40.904: E/WindowManager(2425): android.view.WindowLeaked: Activity com.example.eindwerkappv1.Preferences has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@41a97848 that was originally added here
04-19 10:18:40.904: E/WindowManager(2425):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:344)
04-19 10:18:40.904: E/WindowManager(2425):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:267)
04-19 10:18:40.904: E/WindowManager(2425):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
04-19 10:18:40.904: E/WindowManager(2425):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
04-19 10:18:40.904: E/WindowManager(2425):  at android.view.Window$LocalWindowManager.addView(Window.java:537)
04-19 10:18:40.904: E/WindowManager(2425):  at android.app.Dialog.show(Dialog.java:278)
04-19 10:18:40.904: E/WindowManager(2425):  at com.example.eindwerkappv1.DownloadXml.onPreExecute(DownloadXml.java:38)
04-19 10:18:40.904: E/WindowManager(2425):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:561)
04-19 10:18:40.904: E/WindowManager(2425):  at android.os.AsyncTask.execute(AsyncTask.java:511)
04-19 10:18:40.904: E/WindowManager(2425):  at com.example.eindwerkappv1.Preferences$1.onPreferenceClick(Preferences.java:48)
04-19 10:18:40.904: E/WindowManager(2425):  at android.preference.Preference.performClick(Preference.java:941)
04-19 10:18:40.904: E/WindowManager(2425):  at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:202)
04-19 10:18:40.904: E/WindowManager(2425):  at android.widget.AdapterView.performItemClick(AdapterView.java:292)
04-19 10:18:40.904: E/WindowManager(2425):  at android.widget.AbsListView.performItemClick(AbsListView.java:1068)
04-19 10:18:40.904: E/WindowManager(2425):  at android.widget.AbsListView$PerformClick.run(AbsListView.java:2525)
04-19 10:18:40.904: E/WindowManager(2425):  at android.widget.AbsListView$1.run(AbsListView.java:3186)
04-19 10:18:40.904: E/WindowManager(2425):  at android.os.Handler.handleCallback(Handler.java:605)
04-19 10:18:40.904: E/WindowManager(2425):  at android.os.Handler.dispatchMessage(Handler.java:92)
04-19 10:18:40.904: E/WindowManager(2425):  at android.os.Looper.loop(Looper.java:137)
04-19 10:18:40.904: E/WindowManager(2425):  at android.app.ActivityThread.main(ActivityThread.java:4441)
04-19 10:18:40.904: E/WindowManager(2425):  at java.lang.reflect.Method.invokeNative(Native Method)
04-19 10:18:40.904: E/WindowManager(2425):  at java.lang.reflect.Method.invoke(Method.java:511)
04-19 10:18:40.904: E/WindowManager(2425):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
04-19 10:18:40.904: E/WindowManager(2425):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
04-19 10:18:40.904: E/WindowManager(2425):  at dalvik.system.NativeStart.main(Native Method)
4

1 回答 1

0

conn.setReadTimeout(10000);您可能需要在打开连接之前通过 using 来考虑 Socket 超时的可能性,然后添加一个 catch 子句来处理SocketTimeoutException。请注意,我选择的 10000 毫秒超时是任意的。

一个主要问题是您没有正确处理服务器返回 HTTP_OK 以外的响应时发生的情况。即使(conn.getResponseCode() == HttpURLConnection.HTTP_OK)为假,也不会捕获到异常。MalformedURLException仅在 URL 中的格式错误以及IOException您尝试从关闭的套接字或类似内容中读取的情况下抛出。没有什么可以捕获 HTTP_NOT_FOUND。我想快速解决这个问题的方法是elseif(conn.getResponseCode() == HttpURLConnection.HTTP_OK).

else {
    e = new Exception();
}

这样,在 onPostExecute() 中 e 就不会为空。这当然不是很好的做法,但它适用于您的代码。

编辑:以下代码对我来说很好。我必须填写一些你没有包括在内的领域。

private class DownloadTask extends AsyncTask<Void, Float, Void> {
    Context mContext;
    ProgressDialog progressDialog;
    Exception e;

    DownloadTask(Context context) {
        mContext = context;
    }

    @Override
    protected void onPreExecute() {
        progressDialog = new ProgressDialog(mContext);
        progressDialog.setTitle("XML downloaden");
        progressDialog.setMessage("Downloading xml:");
        progressDialog.setMax(100);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.show();
    }

    @Override
    protected void onProgressUpdate(Float... values) {
        for( float val : values) {
            progressDialog.setProgress((int)(val*100f));
        }
    }

    @Override
    protected Void doInBackground(Void... params) {

        FileOutputStream fos = null;
        InputStream inputStream = null;
        HttpURLConnection conn = null;
        try {
            fos = mContext.openFileOutput("xmlapp.xml", Context.MODE_PRIVATE);

            SharedPreferences prefs = PreferenceManager
                    .getDefaultSharedPreferences(mContext);
            String start = prefs.getString("pref_key_url",
                    "http://sdesigns.be/eindwerk/web6/");

            URL url;
            url = new URL(start);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setRequestMethod("GET");
            conn.setReadTimeout(50000);
            conn.connect();

                byte[] buffer = new byte[64];
                if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    int bytesToDownload = conn.getContentLength();
                    int bytesDownloaded = 0;
                    inputStream = conn.getInputStream();
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                        bytesDownloaded += len;
                        publishProgress((float) bytesDownloaded / bytesToDownload);
                    }
                    inputStream.close();
                    fos.close();
                } else {
                    e = new Exception("URL not found.");
                }

        } catch (Exception e) {
            //since you don't differentiate exceptions and just check if e is null, you might as well just have one catch block
            this.e = e;
        }
        finally {
            try {
             conn.disconnect();
            } catch (Exception e) {}
            conn = null;
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {

        if (progressDialog != null) {
            progressDialog.dismiss();
            progressDialog = null;
        }
        if (e == null) {
            Toast.makeText(mContext,
                    "Success!",
                    Toast.LENGTH_LONG).show();
            List<String> images = new XmlParserSax(mContext).getImagesList();
            DownloadImages di = new DownloadImages(mContext);
            di.execute(images);
        } else {
            Toast.makeText(mContext,
                    "Check the url!" + e.toString(),
                    Toast.LENGTH_LONG).show(); //show the error
        }

    }
}
于 2013-04-18T14:33:01.450 回答