Android httpclient файл загрузки данных повреждения данных и времени ожидания - PullRequest
11 голосов
/ 04 февраля 2011

У меня проблемы с загрузкой изображений в Android.

Я использую Apache httpmime 4.1 lib код выглядит так:

MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

reqEntity.addPart("image", new FileBody(new File(AndorraApplication.getPhotosPath() + "/" + entity.getFileName()), "image/jpeg"));
resp = NetworkUtils.sendHttpRequestMultipart(EXPORT_PHOTOS_URI, reqEntity);

Класс NetworkUtils:

public class NetworkUtils {
    public static final int REGISTRATION_TIMEOUT = 3 * 1000; 
    public static final int WAIT_TIMEOUT = 5 * 1000;

    public static HttpResponse sendHttpRequestMultipart(String uri, MultipartEntity entity) {
        HttpClient mHttpClient = new DefaultHttpClient();
        final HttpParams params = mHttpClient.getParams();
        HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT);
        ConnManagerParams.setTimeout(params, WAIT_TIMEOUT);

        HttpPost post = new HttpPost(uri);
        post.addHeader(entity.getContentType());
        post.setEntity(entity);
        HttpResponse resp = mHttpClient.execute(post);
    }
}

иногда все работает нормально, но иногда (особенно при медленном соединении) изображение загружается очень поврежденным.пример здесь: http://pixelbirthcloud.com/574_orig.jpg

он не выдает никаких исключений.длина загруженного файла такая же, как и у исходного. Попытка изменить тип MIME на application / octet-stream или вообще удалить его.пытается играть с таймаутами.все тот же результат.Конечные пользователи загружают испорченные изображения почти все время (хотя мне удавалось получать изображения с броней только 2 раза). Сначала размер изображения составлял 2,5 мегабайта, но затем я уменьшил его до 500-700 кбайт.не решил проблему, хотя

не пытался изменить библиотеку apache .. возможно, это проблема ... но, насколько я читал в сети, никто не испытывал это с библиотекой httpmime.

что это можетбыть?теперь я полностью потерян: (

другая проблема в том, что тайм-ауты иногда не работают.

как, например, когда дело доходит до этой строки: HttpResponse resp = mHttpClient.execute (post); и яотключить соединение 3g, оно просто ждет 17-20 минут вместо 3 или 5 секунд ... и только потом выдает исключение. пробовал разные методы, например:

        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
        HttpProtocolParams.setUseExpectContinue(params, false);  
        HttpConnectionParams.setConnectionTimeout(params, 10000);
        HttpConnectionParams.setSoTimeout(params, 10000);
        ConnManagerParams.setMaxTotalConnections(params, 5);
        ConnManagerParams.setTimeout(params, 30000);

        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http",PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https",PlainSocketFactory.getSocketFactory(), 80));
        ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
        HttpClient httpclient = new DefaultHttpClient(manager, params);

, но все равно не работает :)

Ответы [ 3 ]

7 голосов
/ 04 февраля 2011

Смотрите мой код загрузки изображений, и он отлично работает для меня Этот класс загружает файл на сервер, а в конце также читает XML-ответ. Отфильтруйте код согласно вашему требованию. Для меня это работает довольно гладко


package com.classifieds;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;


import android.util.Log;

public class Uploader 
{

    private String Tag = "UPLOADER";
    private String urlString ;//= "YOUR_ONLINE_PHP";
    HttpURLConnection conn;
    String exsistingFileName ;

    private void uploadImageData(String existingFileName , String urlString)
    {
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        try {
            // ------------------ CLIENT REQUEST

            Log.e(Tag, "Inside second Method");

            FileInputStream fileInputStream = new FileInputStream(new File(
                    exsistingFileName));

            // open a URL connection to the Servlet

            URL url = new URL(urlString);

            // Open a HTTP connection to the URL

            conn = (HttpURLConnection) url.openConnection();

            // Allow Inputs
            conn.setDoInput(true);

            // Allow Outputs
            conn.setDoOutput(true);

            // Don't use a cached copy.
            conn.setUseCaches(false);

            // Use a post method.
            conn.setRequestMethod("POST");

            conn.setRequestProperty("Connection", "Keep-Alive");

            conn.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);

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

            dos.writeBytes(twoHyphens + boundary + lineEnd);
            dos
                    .writeBytes("Content-Disposition: post-data; name=uploadedfile;filename="
                            + exsistingFileName + "" + lineEnd);
            dos.writeBytes(lineEnd);

            Log.v(Tag, "Headers are written");

            // create a buffer of maximum size

            int bytesAvailable = fileInputStream.available();
            int maxBufferSize = 1000;
            // int bufferSize = Math.min(bytesAvailable, maxBufferSize);
            byte[] buffer = new byte[bytesAvailable];

            // read file and write it into form...

            int bytesRead = fileInputStream.read(buffer, 0, bytesAvailable);

            while (bytesRead > 0) {
                dos.write(buffer, 0, bytesAvailable);
                bytesAvailable = fileInputStream.available();
                bytesAvailable = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bytesAvailable);
            }

            // send multipart form data necesssary after file data...

            dos.writeBytes(lineEnd);
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

            // close streams
            Log.v(Tag, "File is written");
            fileInputStream.close();
            dos.flush();
            dos.close();

        } catch (MalformedURLException ex) {
            Log.e(Tag, "error: " + ex.getMessage(), ex);
        }

        catch (IOException ioe) {
            Log.e(Tag, "error: " + ioe.getMessage(), ioe);
        }


        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = null;
        try {
            sp = spf.newSAXParser();
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Get the XMLReader of the SAXParser we created.
        XMLReader xr = null;
        try {
            xr = sp.getXMLReader();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // Create a new ContentHandler and apply it to the XML-Reader
        MyExampleHandler1 myExampleHandler = new MyExampleHandler1();
        xr.setContentHandler(myExampleHandler);

        // Parse the xml-data from our URL. 
        try {
            xr.parse(new InputSource(conn.getInputStream()));
        //xr.parse(new InputSource(new java.io.FileInputStream(new java.io.File("login.xml")))); 
        } catch (MalformedURLException e) {
            Log.d("Net Disconnected", "NetDisconeeted");
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            Log.d("Net Disconnected", "NetDisconeeted");
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            Log.d("Net Disconnected", "NetDisconeeted");
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Parsing has finished.

    }

    public Uploader(String existingFileName, boolean isImageUploading , String urlString ) {

        this.exsistingFileName = existingFileName;
        this.urlString = urlString;

    }

    class MyExampleHandler1 extends DefaultHandler
    {
    // ===========================================================
    // Methods
    // ===========================================================

    @Override
    public void startDocument() throws SAXException {

    }

    @Override
    public void endDocument() throws SAXException {
        // Nothing to do
    }

    @Override
    public void startElement(String namespaceURI, String localName,
              String qName, Attributes atts) throws SAXException {


    }

    /** Gets be called on closing tags like:
     * </tag> */
    @Override
    public void endElement(String namespaceURI, String localName, String qName)
              throws SAXException {


    }

    /** Gets be called on the following structure:
     * <tag>characters</tag> */
    @Override
    public void characters(char ch[], int start, int length) {

     }
    }

}
4 голосов
/ 27 октября 2012

У меня была такая же проблема с повреждением на 80% моих загруженных файлов.Эмулятор не преминул загрузить.Поврежденные файлы были на 1k больше оригинальных.Затем я установил буфер выходного потока в 1 байт, и он начал работать без проблем.Наконец, я допустил, что это будет 8 байт, и у меня больше не было проблем с коррупцией.Буфер около 80 или 50, я не помню, тоже вышел из строя.Не понимаю, в чем проблема, но я рад, что так работает.Эта страница была очень вдохновляющей.

1 голос
/ 09 февраля 2011

ки.потратил 2 дня на тестирование этой проблемы и выяснил следующее:
при использовании tcpdump на Android выясняется, что данные не были повреждены, НО размер пакета tcp был 1516, что очень странно, потому что нормальный размер пакета Ethernet равен1500 и все, что больше 1516, слишком велико.
Я вручную изменил MTU на 576 (я полагаю, что это стандарт для ppp, которым на самом деле является 3G), и он отлично работает!150 из 150 изображений были загружены в обычном режиме!

это не решает реальной проблемы, потому что, я полагаю, невозможно изменить mtu на нерутированных устройствах, и вы должны менять его каждый раз при перезагрузкеустройство (или каждый раз, когда вы вызываете интерфейс - не уверен в этом, потому что не смог найти способ получить значение MTU через ifconfig).но, по крайней мере, я знаю, в чем проблема.
установка размера куска http на меньшее значение (пробовал 300 байт) не повлияла на него (я считаю, что это потому, что заголовки http сами по себе слишком велики) ... так... так что ничего =)

попытается опубликовать его в группе разработчиков Android на Google, но их модерация слишком медленная ... посмотрим ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...