0

次の方法で Web ページを外部ストレージに保存しようとしています。

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;
    }

}
4

1 に答える 1

0

例外は明確に示していますandroid.os.NetworkOnMainThreadException。これは、常に別Networkのスレッドでのみ呼び出しを行う必要があることを意味します。

解決策: 新しいスレッドを作成し、Network呼び出します。

AsyncTaskを使用できますThe AsyncTask class provides one of the simplest ways to fire off a new task from the UI threadAndroid ドキュメントから

詳細については、android リンクを参照してください。


についてのドキュメントをAsyncTask注意深く読んでください。

非同期タスクで使用される 3 つのタイプは次のとおりです。

  1. Params、実行時にタスクに送信されるパラメーターのタイプ。
  2. 進行状況、バックグラウンド計算中に発行された進行状況単位のタイプ。
  3. 結果、バックグラウンド計算の結果の型

あなたの場合、Paramsメソッドにパラメーターを送信するために使用する必要があります(例:urlとファイル名)

于 2013-09-09T15:35:00.623 に答える