Java Android:位图作为字符串传输,导致内存不足错误
我正在从事一个Android项目,在这个项目中,我从我们的服务器加载图像,同时加载有关餐厅的其他信息。问题是,加载要花很多时间,每当我尝试再次加载信息,或将手机从横向移动到potrait,或反之亦然,我都会出现内存不足错误 正如我在网上查到的,用户说问题是因为位图。在服务器端,我将Java Android:位图作为字符串传输,导致内存不足错误,java,android,memory,bitmap,out-of-memory,Java,Android,Memory,Bitmap,Out Of Memory,我正在从事一个Android项目,在这个项目中,我从我们的服务器加载图像,同时加载有关餐厅的其他信息。问题是,加载要花很多时间,每当我尝试再次加载信息,或将手机从横向移动到potrait,或反之亦然,我都会出现内存不足错误 正如我在网上查到的,用户说问题是因为位图。在服务器端,我将PNG的转换为字符串并传输它们,然后将字符串转换为位图并显示。为什么整个加载时间约为4-5秒,并且会崩溃。有人能帮我吗 Android代码: 餐厅列表活动: public class getListOfRestaur
PNG的
转换为字符串并传输它们,然后将字符串转换为位图并显示。为什么整个加载时间约为4-5秒,并且会崩溃。有人能帮我吗
Android代码:
餐厅列表活动:
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();
}
});
}
}
公共类getListOfRestaurantsForUser扩展异步任务{
RestaurantList RestaurantList=null;
getListOfRestaurantsForUser(RestaurantList RestaurantList){
this.restaurantList=restaurantList;
}
@凌驾
受保护的响应在后台(双倍…双倍){
双倍经度=双倍[0];
双纬度=双纬度[1];
Log.d(“经度”,String.valueOf(经度));
final RestTemplate RestTemplate=StaticRestTemplate.getRest();
HttpHeaders requestHeaders=新的HttpHeaders();
添加(“Cookie”、“JSSessionId=“+StaticRestTemplate.jsSessionId”);
setAccept(Collections.singletonList(新媒体类型(“应用程序”、“json”));
HttpEntity requestEntity=新的HttpEntity(requestHeaders);
restemplate.getMessageConverters().add(新映射Jackson2HttpMessageConverter());
返回restemplate.exchange(restaurantListURL+经度+“/”+纬度,HttpMethod.GET,requestEntity,RestRestaurant[].class);
}
@凌驾
PostExecute上的受保护无效(ResponseEntity ResponseEntity){
RestRestaurant[]restRestaurantList=responseEntity.getBody();
Collections.addAll(restosAsList、restRestaurantList);
ArrayList RestaurantSarayHashList=新ArrayList();
用于(休息室休息室:休息室列表){
HashMap restDisplay=新建HashMap();
restDisplay.put(restaurantid,String.valueOf(restRestaurant.getRestaurantId());
put(restaurantName,restRestaurant.getRestaurantName());
restDisplay.put(restaurantInstance,String.valueOf(restRestaurant.getDistanceFromUser());
restDisplay.put(restaurantDetails,restRestaurant.getRestaurantDetails());
restDisplay.put(restoProfilePicture,restRestaurant.getProfilePicture());
restaurantsArrayHashList.add(restDisplay);
}
listView=(listView)findViewById(R.id.restoList);
restaurantListAdapter=新的restaurantListAdapter(restaurantList,restaurantsArrayHashList);
setAdapter(restaurantListAdapter);
setOnItemClickListener(新的AdapterView.OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父级、视图、,
内部位置,长id){
int restaurantId=restosalist.get(position.getRestaurantId();
意向意向=新意向(RestaurantList.this,MenuCardList.class);
意向。额外支付(“restaurantid”,restaurantid);
星触觉(意向);
完成();
}
});
}
}
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;
}
@覆盖
公共视图getView(int位置、视图转换视图、视图组父视图){
视图=转换视图;
if(convertView==null){
视图=充气机。充气(R.布局。单个餐厅详细信息,空);
TextView restaurantName=(TextView)view.findViewById(R.id.restaurantName);
TextView distanceFromUser=(TextView)view.findViewById(R.id.distanceFromUser);
TextView restaurantDetails=(TextView)view.findViewById(R.id.restaurantDetails);
ImageView RestoImageView=(ImageView)view.findViewById(R.id.Resturatimage);
HashMapRestaurantList;
restaurantList=data.get(位置);
restaurantName.setText(restaurantList.get(restaurantList.restaurantName));
restaurantName.setTypeface(Typeface.DEFAULT_BOLD);
restaurantName.SettexSize(TypedValue.COMPLEX\u UNIT\u SP,15);
double distance=double.valueOf(restaurantList.get(restaurantList.restaurantstance));
如果(距离<1000){
distance fromUser.setText(“Entfernung”+restaurantList.get(restaurantList.restaurantInstance)+“m”);
}否则{
distance fromUser.setText(“Entfernung”+字符串.valueOf(distance/1000)+“km”);
}
setText(restaurantList.get(restaurantList.restaurantDetails));
setImageBitmap(convertByteArrayToBitmap(restaurantList.get(restaurantList.restoProfilePicture));
}
返回视图;
}@覆盖
公共视图getView(int位置、视图转换视图、视图组父视图){
视图=转换视图;
if(convertView==null){
视图=充气机。充气(R.布局。单个餐厅详细信息,空);
TextView restaurantName=(TextView)view.findViewById(R.id.restaurantName);
TextView distanceFromUser=(TextView)view.findViewById(R.id.distanceFromUser);
TextView restaurantDetails=(TextView)view.findViewById(R.id.restaurantDetails);
ImageView RestoImageView=(ImageView)view.findViewById(R.id.Resturatimage);
HashMapRestaurantList;
restaurantList=data.get(位置);
restaurantName.setText(restaurantList.get(RestaurantLi
@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;
}
Picasso.load(StaticRestTemplate.baseURL+"restaurantimage/"+restaurantList.get(RestaurantList.restoProfilePicture))
.config(Bitmap.Config.RGB_565)
.fit()
.centerInside()
.into(restoImage);