gpt4 book ai didi

java - 安卓 : Bitmaps transmitted as String causing out of memory errors

转载 作者:行者123 更新时间:2023-11-29 20:09:01 25 4
gpt4 key购买 nike

我正在开发一个 Android 项目,在该项目中我从我们的服务器加载图像,同时加载有关餐馆的其他信息。问题是,加载需要花费大量时间,每当我尝试再次加载信息或将手机从横向移动到纵向或反之时,我都会遇到内存不足错误。

正如我在网上查到的,用户说的问题是因为位图。在服务器端,我将 PNG 的 转换为字符串并传输它们,然后将字符串转换为位图并显示。为什么整个加载时间大约 4-5 秒并崩溃。谁能帮我。

安卓代码:

餐厅列表 Activity :

 public class getListOfRestaurantsForUser extends AsyncTask<Double,Void,ResponseEntity<RestRestaurant[]>>{

RestaurantList restaurantList = null;

getListOfRestaurantsForUser(RestaurantList restaurantList){
this.restaurantList = restaurantList;
}


@Override
protected ResponseEntity<RestRestaurant[]> doInBackground(Double... doubles) {
double longitude = doubles[0];
double latitude = doubles[1];
Log.d("Longitude",String.valueOf(longitude));
final RestTemplate restTemplate = StaticRestTemplate.getRest();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
requestHeaders.setAccept(Collections.singletonList(new MediaType("application", "json")));
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
return restTemplate.exchange(restaurantListURL+longitude+"/"+latitude, HttpMethod.GET, requestEntity, RestRestaurant[].class);
}

@Override
protected void onPostExecute(ResponseEntity<RestRestaurant[]> responseEntity){
RestRestaurant[] restRestaurantList = responseEntity.getBody();
Collections.addAll(restosAsList, restRestaurantList);

ArrayList<HashMap<String, String>> restaurantsArrayHashList = new ArrayList<>();
for(RestRestaurant restRestaurant : restosAsList){
HashMap<String, String> restDisplay = new HashMap<>();
restDisplay.put(restaurantid, String.valueOf(restRestaurant.getRestaurantId()));
restDisplay.put(restaurantName, restRestaurant.getRestaurantName());
restDisplay.put(restaurantDistance, String.valueOf(restRestaurant.getDistanceFromUser()));
restDisplay.put(restaurantDetails,restRestaurant.getRestaurantDetails());
restDisplay.put(restoProfilePicture,restRestaurant.getProfilePicture());
restaurantsArrayHashList.add(restDisplay);
}

listView = (ListView) findViewById(R.id.restosList);
restaurantListAdapter = new RestaurantListAdapter(restaurantList, restaurantsArrayHashList);

listView.setAdapter(restaurantListAdapter);

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {

int restaurantId = restosAsList.get(position).getRestaurantId();
Intent intent = new Intent(RestaurantList.this, MenuCardList.class);
intent.putExtra("restaurantid", restaurantId);
startActivity(intent);
finish();
}
});
}
}

RestaurantList 适配器:

 @Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
view = inflater.inflate(R.layout.individual_restaurant_detail, null);
TextView restaurantName = (TextView) view.findViewById(R.id.resturantName);

TextView distanceFromUser = (TextView) view.findViewById(R.id.distanceFromUser);
TextView restaurantDetails = (TextView) view.findViewById(R.id.restaurantDetails);
ImageView restoImage = (ImageView) view.findViewById(R.id.resturantImage);
HashMap<String, String> restaurantList;
restaurantList = data.get(position);
restaurantName.setText(restaurantList.get(RestaurantList.restaurantName));
restaurantName.setTypeface(Typeface.DEFAULT_BOLD);
restaurantName.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
double distance = Double.valueOf(restaurantList.get(RestaurantList.restaurantDistance));
if(distance < 1000) {
distanceFromUser.setText("Entfernung " + restaurantList.get(RestaurantList.restaurantDistance)+"m");
}else {
distanceFromUser.setText("Entfernung " + String.valueOf(distance/1000) +"km");
}
restaurantDetails.setText(restaurantList.get(RestaurantList.restaurantDetails));
restoImage.setImageBitmap(convertByteArrayToBitmap(restaurantList.get(RestaurantList.restoProfilePicture)));

}
return view;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
view = inflater.inflate(R.layout.individual_restaurant_detail, null);
TextView restaurantName = (TextView) view.findViewById(R.id.resturantName);

TextView distanceFromUser = (TextView) view.findViewById(R.id.distanceFromUser);
TextView restaurantDetails = (TextView) view.findViewById(R.id.restaurantDetails);
ImageView restoImage = (ImageView) view.findViewById(R.id.resturantImage);
HashMap<String, String> restaurantList;
restaurantList = data.get(position);
restaurantName.setText(restaurantList.get(RestaurantList.restaurantName));
restaurantName.setTypeface(Typeface.DEFAULT_BOLD);
restaurantName.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
double distance = Double.valueOf(restaurantList.get(RestaurantList.restaurantDistance));
if(distance < 1000) {
distanceFromUser.setText("Entfernung " + restaurantList.get(RestaurantList.restaurantDistance)+"m");
}else {
distanceFromUser.setText("Entfernung " + String.valueOf(distance/1000) +"km");
}
restaurantDetails.setText(restaurantList.get(RestaurantList.restaurantDetails));
restoImage.setImageBitmap(convertByteArrayToBitmap(restaurantList.get(RestaurantList.restoProfilePicture)));

}
return view;
}

private Bitmap convertByteArrayToBitmap(String string){
try {
byte [] encodeByte= Base64.decode(string, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
} catch (Exception ignored){}
return null;

}

服务器端代码:

@Override
public List<Restaurant> getNearbyRestaurants(double longitude, double latitude) {
BASE64Encoder base64Encoder = new BASE64Encoder();
final int R = 6371; // Radius of the earth
List<Restaurant> restaurantList = this.listRestaurants();
List<Restaurant> nearbyRestaurantList = new ArrayList<>();
for(Restaurant restaurant : restaurantList){
Double latDistance = toRad(latitude-restaurant.getLatitude());
Double lonDistance = toRad(longitude-restaurant.getLongitude());
Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) +
Math.cos(toRad(latitude)) * Math.cos(toRad(restaurant.getLatitude())) *
Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
Double distance = R * c;
restaurant.setDistanceFromUser(distance);
if(distance < 10){
restaurant.setDistanceFromUser((restaurant.getDistanceFromUser()*1000));
nearbyRestaurantList.add(restaurant);
}

String restaurantIdentifierImageString = this.restaurantImageService.getProfileIdentifierForRestaurant(restaurant.getRestaurantId());

if(!(restaurantIdentifierImageString == null)){

try {
try {
File imagePath = new File(restaurantImagePath + restaurantIdentifierImageString +".png");
BufferedImage bufferedImage = ImageIO.read(imagePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
restaurant.setProfilePicture( base64Encoder.encode(byteArrayOutputStream.toByteArray()));

} catch (Exception e) {
File imagePath = new File(defaultProfilePath);
BufferedImage bufferedImage = ImageIO.read(imagePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
restaurant.setProfilePicture(base64Encoder.encode(byteArrayOutputStream.toByteArray()));
}
}catch (Exception e){
e.printStackTrace();
}

}
}

Collections.sort(nearbyRestaurantList, new Comparator<Restaurant>() {
@Override
public int compare(Restaurant o1, Restaurant o2) {
if(o1.getDistanceFromUser() > o2.getDistanceFromUser()){
return 1;
}
if(o1.getDistanceFromUser() < o2.getDistanceFromUser()){
return -1;
}
return 0;
}
});

return nearbyRestaurantList;
}

错误日志:

 Caused by: java.lang.OutOfMemoryError: Failed to allocate a 13176356 byte allocation with 370616 free bytes and 361KB until OOM
at java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:83)
at java.lang.StringBuilder.<init>(StringBuilder.java:67)
at com.fasterxml.jackson.core.util.TextBuffer.contentsAsString(TextBuffer.java:346)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishAndReturnString(UTF8StreamJsonParser.java:2412)
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:285)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:32)

如果需要更多信息,请告诉我。谢谢。

更新

Image retrieval method :

@RequestMapping(value = "/restaurantimage/{identifier}")
public HttpEntity<byte[]> getPhoto(@PathVariable String identifier) {
boolean flag = false;
try {
byte[] image;
try {
image = org.apache.commons.io.FileUtils.readFileToByteArray(new File(restaurantImagePath + identifier +".png"));
} catch (FileNotFoundException e) {
flag = true;
image = org.apache.commons.io.FileUtils.readFileToByteArray(new File(defaultProfilePath));
e.printStackTrace();
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
headers.setContentLength(image.length);
return new HttpEntity<>(image, headers);
} catch (IOException ignored) {
}
return null;
}

最佳答案

我不知道你的服务器端有什么要求,但是对于移动应用程序,分配给应用程序的内存是非常有限的。您可能发送的位图必须是几千字节,当它被接收时,您将其存储在字符串或字节数组中,然后将其写在一个字符串中。这会消耗应用程序的大量内存,还会产生性能问题。

作为它的替代方法,您可以在 json 字符串中提供来自服务器的图像的 url,然后将该 url 传递给某些 Imagehelper/Lazyloading 库(如 Volley)的方法。

关于java - 安卓 : Bitmaps transmitted as String causing out of memory errors,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35294714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com