Below is the code which is basically owrking…well mostly. It works on all phones I was testing, but fails on the client phone, I can’t use. Which part of this code could cause NetworkOnMainThreadException?
It’s really straight forward. What I do in onPostExecute() is:
- Geting InputStream from onBackground()
- Aborting if InputStream is null, aborting if null.
- Checking external storage avalibility, aborting if not.
- Creating file from InputStream
- Checking PDF viewer avalibility, aborting if not avalible
-
Opening newly created 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 ); } }
Also including a stack trace. There is one more clue. Client is retrieving InputStream using SSL, and I’m not. Unfortunately can’t debug it with SSL yet.
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)
Though you are using
AsyncTask, itsonPostExecute()method is executed on UI thread (to let you update your views etc). Actually, the only method ofAsyncTaskexecuted in separate thread isdoInBackground(), so you have to perform all operations involving I/O (disk, network), only in this method, otherwise you’ll get an exception.Refer to this for details.