File Upload to server issues in Android

2019-09-07 11:57发布

问题:

i have code for file uploading to server its code working individual but this implemented in my app its goto exception all the time

here is my code

 public int uploadFile(String sourceFileUri) {
    String fileName = sourceFileUri;

    HttpURLConnection conn = null;
    DataOutputStream dos = null;
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024;
    File sourceFile = new File(sourceFileUri);

    if (!sourceFile.isFile()) {

       // dialog.dismiss();

        Log.e("uploadFile", "Source File not exist :"
                + selectedFilePath);

        runOnUiThread(new Runnable() {
            public void run() {
              //  messageText.setText("Source File not exist :"
                      //  + selectedFilePath);
            }
        });

        return 0;

    } else {
        int serverResponseCode = 0;

        try {

            // open a URL connection to the Servlet
            FileInputStream fileInputStream = new FileInputStream(sourceFile);
            URL url = new URL(uploadurl);

            // Open a HTTP  connection to  the URL
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true); // Allow Inputs
            conn.setDoOutput(true); // Allow Outputs
            conn.setUseCaches(false); // Don't use a Cached Copy
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("ENCTYPE", "multipart/form-data");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            conn.setRequestProperty("userfile", fileName);

            dos = new DataOutputStream(conn.getOutputStream());

            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos.writeBytes("Content-Disposition: form-data; name=\"userfile\";filename=\""
                    + fileName + "\"" + lineEnd);

            dos.writeBytes(lineEnd);

            // create a buffer of  maximum size
            bytesAvailable = fileInputStream.available();

            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];

            // read file and write it into form...
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            while (bytesRead > 0) {

                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            }

            // send multipart form data necesssary after file data...
            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            // Responses from the server (code and message)
            serverResponseCode = conn.getResponseCode();
            String serverResponseMessage = conn.getResponseMessage();
            final String response;
            Log.i("uploadFile", "HTTP Response is : "
                    + serverResponseMessage + ": " + serverResponseCode + serverResponseMessage);
            String data;
            if (serverResponseCode == 200) {

                final HttpURLConnection finalConn = conn;
                runOnUiThread(new Runnable() {
                    public void run() {

                            /*String msg = "File Upload Completed.\n\n See uploaded file here : \n\n"
                                          +" http://www.androidexample.com/media/uploads/"
                                          +uploadFileName;*/

                        //messageText.setText(msg);
                        String data = null;
                        BufferedReader in = null;
                        try {
                            in = new BufferedReader(new
                                    InputStreamReader(
                                    finalConn.getInputStream()));
                            StringBuilder result = new StringBuilder();
                            String line;

                            while ((line = in.readLine()) != null) {

                                result.append(line);

                                data = result.toString();
                                break;
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }


                        Toast.makeText(Individual_Message.this, "File Upload Complete." + data,
                                Toast.LENGTH_SHORT).show();
                    }
                });
            }

            //close the streams //
            fileInputStream.close();
            dos.flush();
            dos.close();

        } catch (MalformedURLException ex) {

            //dialog.dismiss();
            ex.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    //messageText.setText("MalformedURLException Exception : check script url.");
                    Toast.makeText(Individual_Message.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
                }
            });

            Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
        } catch (Exception e) {

            // dialog.dismiss();
            e.printStackTrace();

            runOnUiThread(new Runnable() {
                public void run() {
                    //  messageText.setText("Got Exception : see logcat ");
                    Toast.makeText(Individual_Message.this, "Got Exception : see logcat ",
                            Toast.LENGTH_SHORT).show();
                }
            });
            Log.e("Upload file", "Exception : "
                    + e.getMessage(), e);
        }
        //dialog.dismiss();
        return serverResponseCode;

    }
}

individually running get exact result but inside my app

get log cat like

    V/Selected File Path:: /storage/emulated/0/temporary_file_0.jpg
V/FA: Activity resumed, time: 268130823
V/FA: Inactivity, disconnecting from AppMeasurementService
W/System.err: android.os.NetworkOnMainThreadException
W/System.err:     at          android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
W/System.err:     at      libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249)
W/System.err:     at libcore.io.IoBridge.recvfrom(IoBridge.java:549)
W/System.err:     at  java.net.PlainSocketImpl.read(PlainSocketImpl.java:481)
W/System.err:     at java.net.PlainSocketImpl.-    wrap0(PlainSocketImpl.java)
W/System.err:     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
W/System.err:     at com.android.okhttp.okio.Okio$2.read(Okio.java:135)
W/System.err:     at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
W/System.err:     at com.android.okhttp.okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
W/System.err:     at com.android.okhttp.internal.http.HttpConnection.isReadable(HttpConnection.java:155)
W/System.err:     at com.android.okhttp.Connection.isReadable(Connection.java:235)
W/System.err:     at com.android.okhttp.OkHttpClient$1.isReadable(OkHttpClient.java:91)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:350)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute HttpURLConnectionImpl.java:437)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:245)
W/System.err:     at technologies.codegreen.com.drzonesample.My_Messages.Individual_Message.uploadFile(Individual_Message.java:355)
W/System.err:     at technologies.codegreen.com.drzonesample.My_Messages.Individual_Message$2.onClick(Individual_Message.java:148)
W/System.err:     at android.view.View.performClick(View.java:5204)
W/System.err:     at android.view.View$PerformClick.run(View.java:21153)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err:     at android.os.Looper.loop(Looper.java:148)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5480)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E/Upload file: Exception : null
           android.os.NetworkOnMainThreadException
               at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
               at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:249)
               at libcore.io.IoBridge.recvfrom(IoBridge.java:549)
               at java.net.PlainSocketImpl.read(PlainSocketImpl.java:481)
               at java.net.PlainSocketImpl.-wrap0(PlainSocketImpl.java)
               at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:237)
               at com.android.okhttp.okio.Okio$2.read(Okio.java:135)
               at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
               at com.android.okhttp.okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
               at com.android.okhttp.internal.http.HttpConnection.isReadable(HttpConnection.java:155)
               at com.android.okhttp.Connection.isReadable(Connection.java:235)
               at com.android.okhttp.OkHttpClient$1.isReadable(OkHttpClient.java:91)
               at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:350)
               at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:340)
               at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
               at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
               at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437)
               at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
               at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:245)
               at technologies.codegreen.com.drzonesample.My_Messages.Individual_Message.uploadFile(Individual_Message.java:355)
               at technologies.codegreen.com.drzonesample.My_Messages.Individual_Message$2.onClick(Individual_Message.java:148)
               at android.view.View.performClick(View.java:5204)
               at android.view.View$PerformClick.run(View.java:21153)
               at android.os.Handler.handleCallback(Handler.java:739)
               at android.os.Handler.dispatchMessage(Handler.java:95)
               at android.os.Looper.loop(Looper.java:148)
               at android.app.ActivityThread.main(ActivityThread.java:5480)
               at java.lang.reflect.Method.invoke(Native Method)
               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

回答1:

NetworkOnMainThreadException is thrown when your application attempts to perform networking operation on its main thread.

Use AsyncTask and run your code in it



回答2:

To avoid the application not responding error, android avoids you to do any long operation in UI thread synchronously. 
You have do to it in a separated thread asynchronously as follows.  

Create a different class 
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {             
//write your code of file download. 
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

and in upload file method just call this. 

new DownloadFilesTask().execute(url1, url2, url3);

Theory https://developer.android.com/reference/android/os/AsyncTask.html