我在Android中遇到了一个奇怪的HTTP问题。 我正在尝试从远程服务器获取图片并将其显示在设备上。 如果图片是小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()返回从不超过65kb。虽然InputStream本身具有正确的长度(在调试器中可见)。
答案 0 :(得分:0)
可用()
将返回从输入流中读取的字节数而不会阻塞。因此,它将是可以在不阻塞的情况下从网络读取的返回数据。
尝试:
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);
显然不是有更有效的方法来做到这一点,但可能是一个切入点。如果您需要更多帮助,请告诉我。
编辑:当然,你必须避免在UI线程中进行阻塞调用,正如人们所建议的那样。
答案 1 :(得分:0)
认为您需要知道 bis.available()将始终返回小于65Kb,因为最大IP数据包大小为65535字节。 InputStream将返回总大小
由于您在任何时间点只给出了一个读取语句,因此数据数组总是小于65kb。 (即第一个数据包的数据)
你可以做的是使用BitmapFactory.decodeStream(InputStream is)
并给InputStream bis它将读取Stream中的所有字节并为你提供位图
<强> 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是因为通过Internet获取Next Packet可能会有一些延迟