将网页保存到外部存储会导致应用崩溃

时间:2013-09-09 15:30:36

标签: java android eclipse

我正在尝试使用以下方法将网页保存到外部存储空间:

public void saveWebPage(String url, String fileName){
    try {
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response;
        response = httpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        InputStream is = entity.getContent();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null){
            sb.append(line + "\n");
        }
        String resString = sb.toString();
        is.close();
        File file = new File(Environment.getExternalStorageDirectory().toString() + "/Android/data/com.whizzapps.stpsurniki/" + fileName + ".html");
        file.createNewFile();
        FileOutputStream f1 = new FileOutputStream(file, false);
        PrintStream p = new PrintStream(f1);
        p.print(resString);
        p.close();
        f1.close();
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

当我调用该方法时,应用程序崩溃,这是logcat:

09-09 17:26:22.304: E/AndroidRuntime(14507): FATAL EXCEPTION: main
09-09 17:26:22.304: E/AndroidRuntime(14507): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.whizzapps.stpsurniki/com.whizzapps.stpsurniki.Scheudele}: android.os.NetworkOnMainThreadException
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.os.Looper.loop(Looper.java:137)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.ActivityThread.main(ActivityThread.java:5103)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at java.lang.reflect.Method.invokeNative(Native Method)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at java.lang.reflect.Method.invoke(Method.java:525)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at dalvik.system.NativeStart.main(Native Method)
09-09 17:26:22.304: E/AndroidRuntime(14507): Caused by: android.os.NetworkOnMainThreadException
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at java.net.InetAddress.getAllByName(InetAddress.java:214)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at com.whizzapps.stpsurniki.Scheudele.saveWebPage(Scheudele.java:135)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at com.whizzapps.stpsurniki.Scheudele.getWebView(Scheudele.java:66)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at com.whizzapps.stpsurniki.Scheudele.onCreate(Scheudele.java:50)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.Activity.performCreate(Activity.java:5133)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-09 17:26:22.304: E/AndroidRuntime(14507):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
09-09 17:26:22.304: E/AndroidRuntime(14507):    ... 11 more

有人告诉我把它放在UI线程中,但我不知道ui线程在哪一行代码中。我只是把它放在活动类文件中的其他方法旁边。

新代码:

private class downloadWebPage extends AsyncTask<String, Void, Void> {

    @Override
    protected Void doInBackground(String... params) {
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response;
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            InputStream is = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null){
                sb.append(line + "\n");
            }
            String resString = sb.toString();
            is.close();
            File file = new File(Environment.getExternalStorageDirectory().toString() + "/Android/data/com.whizzapps.stpsurniki/" + fileName + ".html");
            file.createNewFile();
            FileOutputStream f1 = new FileOutputStream(file, false);
            PrintStream p = new PrintStream(f1);
            p.print(resString);
            p.close();
            f1.close();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

}

1 个答案:

答案 0 :(得分:0)

异常清楚地表明android.os.NetworkOnMainThreadException,这意味着您应该始终只在一个单独的主题中调用Network

解决方案:创建一个新主题,然后进行Network调用。

您可以使用Android文档中的AsyncTaskThe AsyncTask class provides one of the simplest ways to fire off a new task from the UI thread

有关详细信息,请参阅android link


仔细阅读有关AsyncTask的文档。

异步任务使用的三种类型如下:

  1. Params,执行时发送给任务的参数类型。
  2. 进度,后台计算期间发布的进度单位的类型。
  3. 结果,背景计算结果的类型
  4. 在您的情况下,您应该使用Params向该方法发送参数(例如网址和文件名)