В HTTP-запросе отсутствуют данные - PullRequest
0 голосов
/ 15 марта 2012

Привет, у меня странная проблема с HTTP в Android. Я пытаюсь получить изображение с удаленного сервера и отобразить его на устройстве. Если изображение небольшого формата JPEG, это не проблема. но если изображение увеличится в размере, оно не будет работать (показаны только части изображения).

Вот мой полный демонстрационный код:

public class HTTP_testActivity extends Activity {

private ImageView ivPicture;
private Button btGetImage;  


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ivPicture = (ImageView) findViewById(R.id.ivpiture1);
    btGetImage = (Button) findViewById(R.id.btGetPicture1);
    btGetImage.setOnClickListener(new Button.OnClickListener() 
    {
        public void onClick(View arg0) 
        {
            URI uri;
            try {


                uri = new URI("");
                URLConnection connection =  uri.toURL().openConnection();
                connection.setUseCaches(true);
                connection.connect();

                BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
                Log.d("TEST","Length of Input " +bis.available());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Log.d("TEST","Length of Input after wait " +bis.available());
                byte[] data = new byte[640*480*5];
                bis.read(data);
                Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, jdata.length);
                if (bmp != null)
                {
                    ivPicture.setImageBitmap(bmp);
                }
                bis.close();
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            Log.d("TEST", e.getMessage());
            e.printStackTrace();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            Log.d("TEST", e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.d("TEST", e.getMessage());
            e.printStackTrace();
        }
        }
    });
}

Может кто-то видит, что я делаю не так? Я понял, что до сих пор: bis.available () возвращает не более 65 КБ. Хотя сам InputStream имеет правильную длину (видно в отладчике).

Ответы [ 2 ]

0 голосов
/ 15 марта 2012

Считает, что вам необходимо знать bis.available () всегда будет возвращать менее 65 КБ, поскольку максимальный размер IP-пакета составляет 65535 байт. InputStream вернет вам общий размер

Поскольку вы указали только один оператор чтения в любой момент времени, массив данных всегда будет меньше 65 КБ. (т.е. данные первого пакета)

Что вы можете сделать, это использовать BitmapFactory.decodeStream(InputStream is) и дать InputStream bis, он будет читать все байты в потоке и выдавать вам Bitmap

EDITED

ИСПОЛЬЗУЙТЕ ЭТУ ФУНКЦИЮ

это даст вам все байты из InputStream

 public static byte[] ReadToEOF(InputStream stream) throws Exception
    {
        try {
            ByteArrayOutputStream array = new ByteArrayOutputStream();
            int read = 0;
            byte[] receivedData = new byte[5000];
            while((read = stream.read(receivedData)) > 0)
            {
                array.write(receivedData, 0, read);
                if(!(stream instanceof FileInputStream) && stream.available() == 0)
                {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                    if(stream.available() == 0)
                        break;
                }
            }
            return array.toByteArray();
        } catch (Exception e) {
            // TODO: handle exception
            throw e;
        }
    }

Thread.Sleep потому что для получения следующего пакета через Интернет может быть некоторая задержка

0 голосов
/ 15 марта 2012

доступно ()

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

попробуйте с:

            InputStream bis = new InputStream(connection.getInputStream());
            Log.d("TEST","Length of Input " +bis.available());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            int read = 0;
            byte[] buffer = new byte[SIZE_OF_IMAGE];
            byte[] inBuff = new byte[32678]
            while ((read = bis.read(inBuff, 0, 32768)) > 0) {
                   // copy in buffer what have been read
                   // from the input stream
            }

            // close the is
            Bitmap bmp = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);

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

Редактировать: конечно, вы должны избегать блокирования вызовов в потоке пользовательского интерфейса, как предлагали люди.

...