1

以下は、基本的に動作しているコードです...ほとんどの場合。テストしたすべての電話で動作しますが、クライアントの電話で失敗し、使用できません。このコードのどの部分が NetworkOnMainThreadException を引き起こす可能性がありますか?

それは本当に簡単です。私が onPostExecute() で行うことは次のとおりです。

  1. onBackground() から InputStream を取得する
  2. InputStream が null の場合は中止し、null の場合は中止します。
  3. 外部ストレージの可用性を確認しています。そうでない場合は中止します。
  4. InputStream からのファイルの作成
  5. PDF ビューアの有効性を確認し、無効な場合は中止します
  6. 新しく作成した PDF を開く

    @Override
    protected void onPostExecute(InputStream is) {
        super.onPostExecute(is);
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    
        if (is== null) {
            errorMessage = getString(R.string.error_server_communication);
            CustomDialogs.showErrorDialog( fragment.getActivity(), getString( R.string.error_title ), errorMessage );
            return;
        }
    
        //checking external storage avalibility
        if (!Tools.isWriteableExternalStorageAvalible()) {
            errorMessage = getString(R.string.error_no_external_storage);
            CustomDialogs.showErrorDialog( fragment.getActivity(), getString( R.string.error_title ), errorMessage );
            return;
        }               
    
        // opening pdf
        try {
            File directory = new File(Environment.getExternalStorageDirectory(), "MyApp");
            if (!directory.exists())
                directory.mkdirs();
    
            File file = new File(directory, "file.pdf");
    
            //usuwa poprzednio przechowywany wynik jesli taki byl
            if (file.exists()) 
                file.delete();
    
            file.createNewFile();                   
    
            // write the inputStream to a FileOutputStream
            OutputStream out = new FileOutputStream(file);
            out.write(IOUtils.toByteArray(is));
    
            is.close();
            out.flush();
            out.close();
    
            if (Tools.canDisplayPdf(fragment.getActivity())) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.fromFile(file), "application/pdf");
                startActivity( intent );
            } else {
                //user nie ma przegladarki pdf - komunikat
                errorMessage = getString(R.string.error_server_communication);
                CustomDialogs.showErrorDialog( fragment.getActivity(), getString( R.string.error_title ), errorMessage );
            }
    
        } catch (IOException e) {
            errorMessage = getString(R.string.error_server_communication);
            CustomDialogs.showErrorDialog( fragment.getActivity(), getString( R.string.error_title ), errorMessage );
        }
    }
    

スタック トレースも含まれます。もう1つ手がかりがあります。クライアントは SSL を使用して InputStream を取得していますが、そうではありません。残念ながら、まだ SSL でデバッグすることはできません。

12-05 21:34:02.648: E/AndroidRuntime(711): FATAL EXCEPTION: main
12-05 21:34:02.648: E/AndroidRuntime(711): android.os.NetworkOnMainThreadException
12-05 21:34:02.648: E/AndroidRuntime(711):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:668)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:174)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:188)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:178)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1383)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.commons.io.IOUtils.copy(IOUtils.java:1357)
12-05 21:34:02.648: E/AndroidRuntime(711):  at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:361)
12-05 21:34:02.648: E/AndroidRuntime(711):  at pl.luxmed.pp.activities.MedicalExaminationsActivity$OpenPdfAsyncTask.onPostExecute(MedicalExaminationsActivity.java:270)
12-05 21:34:02.648: E/AndroidRuntime(711):  at pl.luxmed.pp.activities.MedicalExaminationsActivity$OpenPdfAsyncTask.onPostExecute(MedicalExaminationsActivity.java:1)
12-05 21:34:02.648: E/AndroidRuntime(711):  at android.os.AsyncTask.finish(AsyncTask.java:631)
12-05 21:34:02.648: E/AndroidRuntime(711):  at android.os.AsyncTask.access$600(AsyncTask.java:177)
12-05 21:34:02.648: E/AndroidRuntime(711):  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
12-05 21:34:02.648: E/AndroidRuntime(711):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 21:34:02.648: E/AndroidRuntime(711):  at android.os.Looper.loop(Looper.java:137)
12-05 21:34:02.648: E/AndroidRuntime(711):  at android.app.ActivityThread.main(ActivityThread.java:4745)
12-05 21:34:02.648: E/AndroidRuntime(711):  at java.lang.reflect.Method.invokeNative(Native Method)
12-05 21:34:02.648: E/AndroidRuntime(711):  at java.lang.reflect.Method.invoke(Method.java:511)
12-05 21:34:02.648: E/AndroidRuntime(711):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-05 21:34:02.648: E/AndroidRuntime(711):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-05 21:34:02.648: E/AndroidRuntime(711):  at dalvik.system.NativeStart.main(Native Method)
4

2 に答える 2

5

を使用していますがAsyncTask、そのonPostExecute()メソッドは UI スレッドで実行されます (ビューなどを更新できるようにするため)。実際にはAsyncTask、別のスレッドで実行される唯一のメソッドであるdoInBackground()ため、I/O (ディスク、ネットワーク) を含むすべての操作をこのメソッドでのみ実行する必要があります。そうしないと、例外が発生します。

詳しくはこちらをご覧ください。

于 2012-12-06T11:16:20.987 に答える
3

Android Doc android.os.NetworkOnMainThreadExceptionandroid 2.3.3から、メイン UI スレッドで URL を呼び出すことはできないと明確に述べられています。クロスチェックして、この間違いをしていないことを確認してください

Android デベロッパーから

アプリケーションがメイン スレッドでネットワーク操作を実行しようとしたときにスローされる例外。これは、Honeycomb SDK 以上を対象とするアプリケーションでのみスローされます。

于 2012-12-06T11:23:00.317 に答える