试图用图像发送表单PHP服务器时,在Android的内存泄漏 [英] Memory leak in Android when trying to send a form with image to PHP server
问题描述
我在这个文件中的内存泄漏,我找不到在什么地方,但我认为这是在图像周围 - > (位图BM = BitmapFactory.de codeFILE(文件名))
,我已经尝试了许多不同的方法,但我不能让它的工作。
包prod.vegs;
//这里,但不是所有的进口需要写,现在他们都:-)
公共类ProductForm延伸活动{
私有静态诠释TAKE_PICTURE = 1;
私有静态诠释SELECT_PICTURE = 2;
// JSON响应节点名称
私有静态字符串KEY_SUCCESS =成功;
私有静态字符串ERROR_MSG =ERROR_MSG;
私有静态字符串KEY_TYPES =亚型;
私有静态字符串TYPE_NAME =名;
私有静态字符串TYPE_ID =id_type;
私有静态字符串PRODUCT_ID =id_product;
私人的JSONObject JSON;
私人JSONParser jsonParser;
私人字符串吧codeSTR;
私人字符串的文件名;
私人诠释code;
私人ProgressDialog对话框;
私人类型类[]的项目;
私人类型类[]分项目;
//声明的资产对象
微调型;
微调亚型;
TextView的ERRORMSG;
TextView的描述;
TextView的名称;
按钮摄像头;
按钮库;
意向意图;
ImageView的preVIEW;
捆绑包;
的LinearLayout errorMsgContainer;
上下文语境;
公共无效的onCreate(包冰柱){
super.onCreate(冰柱);
的setContentView(R.layout.product_form);
上下文=这一点;
叠B = getIntent()getExtras()。
酒吧codeSTR = b.getString(栏code);
jsonParser =新JSONParser();
对话框=新ProgressDialog(本);
dialog.setMessage(的getString(R.string.loading));
dialog.setTitle(的getString(R.string.progress));
dialog.setCancelable(真正的);
//设置资产
名称=(TextView中)findViewById(R.id.productName);
说明=(TextView中)findViewById(R.id.productDescription);
ERRORMSG =(TextView中)findViewById(R.id.error_msg);
errorMsgContainer =(的LinearLayout)findViewById(R.id.error_msg_container);
类型=(微调)findViewById(R.id.productParentType);
亚型=(微调)findViewById(R.id.productType);
摄像头=(按钮)findViewById(R.id.productCamera);
画廊=(按钮)findViewById(R.id.productGallery);
preVIEW =(ImageView的)findViewById(R.id.product preVIEW);
文件名= Environment.getExternalStorageDirectory()+的String.Format(的getString(R.string.api_product_form_picture_file),酒吧codeSTR);
布尔fromScanner = b.getBoolean(扫描);
如果(fromScanner ==真){
AlertDialog.Builder alertbox =新AlertDialog.Builder(本);
alertbox.setMessage(的getString(R.string.insert_product));
alertbox.setPositiveButton(的getString(R.string.yes)
新DialogInterface.OnClickListener(){
公共无效的onClick(DialogInterface arg_1,INT arg_num){
最后的函数功能=新功能();
名单<的NameValuePair> PARAMS =新的ArrayList<的NameValuePair>();
字符串URL =的String.Format(的getString(R.string.api_product_form_types_url)的getString(R.string.api_url));
JSON = function.loadJSONUrl(URL,则params);
如果(JSON!= NULL){
尝试 {
如果(json.getString(KEY_SUCCESS)!= NULL){
字符串解析度= json.getString(KEY_SUCCESS);
如果(的Integer.parseInt(RES)== 1){
JSONArray类型= json.getJSONArray(KEY_TYPES);
项目= convertJSONArray(类型);
SpinAdapter listViewArrayAdapter =新SpinAdapter(背景下,android.R.layout.simple_spinner_item,项目);
listViewArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
type.setAdapter(listViewArrayAdapter);
type.setOnItemSelectedListener(新OnItemSelectedListener(){
公共无效onItemSelected(适配器视图<>母公司,视图V,INT POS,长ID){
尝试 {
字符串URL =的String.Format(的getString(R.string.api_subtypes_id_url)的getString(R.string.api_url),((类型类)type.getSelectedItem())的getId());
名单<的NameValuePair> PARAMS =新的ArrayList<的NameValuePair>();
JSONObject的json_subtypes = function.loadJSONUrl(URL,PARAMS);
如果(json_subtypes.getString(KEY_SUCCESS)!= NULL){
JSONArray亚型= json_subtypes.getJSONArray(KEY_TYPES);
分项目= convertJSONArray(亚型);
SpinAdapter subTypeAdapter =新SpinAdapter(背景下,android.R.layout.simple_spinner_item,分项目);
subTypeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
subtype.setAdapter(subTypeAdapter);
subtype.setPrompt(Selecciona拉cateogría);
}
}赶上(例外五){
e.printStackTrace();
}
}
公共无效onNothingSelected(适配器视图<>的args){
//自动生成方法存根
}
});
type.setPrompt(Selecciona拉cateogría);
//摄像机的动作
camera.setOnClickListener(新View.OnClickListener(){
公共无效的onClick(视图查看){
意图=新的意图(MediaStore.ACTION_IMAGE_CAPTURE);
INT timeMili =(int)的(System.currentTimeMillis的());
文件名= Environment.getExternalStorageDirectory()+/+ timeMili +.JPG;
乌里输出= Uri.fromFile(新文件(文件名));
intent.putExtra(MediaStore.EXTRA_OUTPUT,输出);
code = TAKE_PICTURE;
startActivityForResult(意向,code);
}
});
//画廊行动
gallery.setOnClickListener(新View.OnClickListener(){
公共无效的onClick(视图查看){
意图=新的意图(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
code = SELECT_PICTURE;
startActivityForResult(意向,code);
}
});
//形式的按钮
Button按钮=(按钮)findViewById(R.id.button);
button.setOnClickListener(新View.OnClickListener(){
公共无效的onClick(视图查看){
如果(!NetworkHelper.CheckNetworkStatus(view.getContext())){
返回;
}
捆绑=新包();
bundle.putString(栏code,酒吧codeStr.toString());
bundle.putString(姓名,name.getText()的toString());
bundle.putString(描述,description.getText()的toString());
bundle.putString(TYPE_ID,((类型类)subtype.getSelectedItem())的getId());
如果(_checkFormValues()){
新SendDataJSON()执行(视图);
} 其他 {
Toast.makeText(view.getContext(),的getString(R.string.error_form_incomplete),Toast.LENGTH_LONG).show();
}
}
});
} 其他 {
errorMsg.setText(json.getString(ERROR_MSG));
errorMsgContainer.setVisibility(LinearLayout.VISIBLE);
}
}
}赶上(JSONException E){
e.printStackTrace();
}
} 其他 {
}
}
})。setNegativeButton(否,
新DialogInterface.OnClickListener(){
公共无效的onClick(DialogInterface为arg0,INT ARG1){
意图myIntent =新的意图(ProductForm.this,CaptureActivity.class);
startActivity(myIntent);
完();
}
})。显示();
} 其他 {
完();
}
}
类SendDataJSON扩展的AsyncTask<查看,太虚,视图> {
@覆盖
受保护的视图doInBackground(查看...查看){
字符串URL =的String.Format(的getString(R.string.api_product_form_url)的getString(R.string.api_url));
HttpPost httpPost =新HttpPost(URL);
尝试 {
//添加数据
MultipartEntity实体=新MultipartEntity();
档案照片=新的文件(文件名);
如果(photo.exists()){
//创建COM pressed图像发送
//创建要发送的图像文件
文件SD = Environment.getExternalStorageDirectory();
文件数据= Environment.getDataDirectory();
如果{SD =数据(sd.canWrite()!); }
串destinationFolderPath = SD +/+的getString(R.string.app_dir)+/;
字符串destinationImageName =photo_+ bundle.getString(栏code)+.JPG;
//创建存储的文件夹
文件destinationFolder =新的文件(destinationFolderPath);
如果(!destinationFolder.exists()){
destinationFolder.mkdirs();
}
文件目的地=新的文件(destinationFolder,destinationImageName);
FileOutputStream中出=新的FileOutputStream(目标);
位图BM = BitmapFactory.de codeFILE(文件名);
INT宽度= bm.getWidth();
INT高= bm.getHeight();
INT MAX_VALUE = 1024;
INT最大= Math.max(宽度,高度);
如果(MAX> MAX_VALUE){
宽度=宽* MAX_VALUE /最大;
高度=身高* MAX_VALUE /最大;
}
//使新的大小值的新形象
尝试 {
位图BM2 = Bitmap.createScaledBitmap(宽多重峰,宽度,高度,真);
//的COM preSS图像
bm2.com preSS(比较pressFormat.JPEG,75出);
了out.flush();
out.close();
目标=新的文件(destinationFolder,destinationImageName);
FileBody filePhoto =新FileBody(目标);
entity.addPart(形象,filePhoto);
}赶上(例外五){
Log.w(ProductForm.class.getSimpleName(),E);
}
}
共享preferences userSettings = getShared preferences(用户preferences,Context.MODE_PRIVATE);
字符集字符= Charset.forName(UTF-8);
entity.addPart(栏code,新StringBody(bundle.getString(栏code),字符));
entity.addPart(名,新StringBody(bundle.getString(姓名),字符));
entity.addPart(说明,新StringBody(bundle.getString(说明),字符));
entity.addPart(id_type,新StringBody(bundle.getString(TYPE_ID)));
entity.addPart(UID,新StringBody(userSettings.getString(UID,),字符));
httpPost.setEntity(实体);
HttpClient的HttpClient的=新DefaultHttpClient();
httpclient.execute(httpPost);
}赶上(IOException异常E){
//
}
返回次[0];
}
@覆盖
在preExecute保护无效(){
dialog.setMax(100);
dialog.setProgress(0);
dialog.show();
}
@覆盖
保护无效onPostExecute(查看视图){
//重定向到产品页面
的setContentView(R.layout.product_bar code);
字符串URL =的String.Format(的getString(R.string.api_product_bar code_url)的getString(R.string.api_url),bundle.getString(栏code));
新LoadJSONBar code()执行(URL)。
}
}
//将数据发送到服务器并接收响应
私有类LoadJSONBar code扩展的AsyncTask<字符串,无效的JSONObject> {
@覆盖
受保护的JSONObject doInBackground(字符串...网址){
名单<的NameValuePair> PARAMS =新的ArrayList<的NameValuePair>();
JSON =新的JSONObject();
JSON = jsonParser.getJSONFromUrl(网址[0],则params);
返回JSON;
}
@覆盖
在preExecute保护无效(){
dialog.setMax(100);
dialog.setProgress(0);
dialog.show();
}
@覆盖
保护无效onPostExecute(JSONObject的JSON){
如果(JSON!= NULL){
尝试 {
如果(json.getString(KEY_SUCCESS)!= NULL){
字符串解析度= json.getString(KEY_SUCCESS);
如果(的Integer.parseInt(RES)== 1){
查看查看= findViewById(R.id.productBar codeXML的);
意图myIntent =新的意图(view.getContext(),Product.class);
叠B =新包();
b.putString(ID,json.getString(产品));
myIntent.putExtras(B);
。view.getContext()startActivity(myIntent);
} 其他 {
errorMsg.setText(json.getString(ERROR_MSG));
errorMsgContainer.setVisibility(LinearLayout.VISIBLE);
}
dialog.dismiss();
}
}赶上(例外五){
e.printStackTrace();
}
}
}
}
保护无效onActivityResult(INT申请code,INT结果code,意图数据){
如果(要求code == TAKE_PICTURE){
如果(数据!= NULL){
如果(data.hasExtra(数据)){
preview.setImageBitmap((位图)data.getParcelableExtra(数据));
preview.setVisibility(ImageView.VISIBLE);
}
} 其他 {
preview.setImageBitmap(BitmapFactory.de codeFILE(文件名));
preview.setVisibility(ImageView.VISIBLE);
新MediaScannerConnectionClient(){
私人MediaScannerConnection MSC = NULL; {
MSC =新MediaScannerConnection(getApplicationContext(),这一点); msc.connect();
}
公共无效onMediaScannerConnected(){
msc.scanFile(文件名,NULL);
}
公共无效onScanCompleted(字符串路径,开放的URI){
msc.disconnect();
}
};
}
}否则,如果(要求code == SELECT_PICTURE){
如果(数据!= NULL){
乌里selectedImage = data.getData();
InputStream的是;
的String [] filePathColumn = {MediaStore.Images.Media.DATA};
光标光标= getContentResolver()查询(selectedImage,filePathColumn,NULL,NULL,NULL);
cursor.moveToFirst();
INT参数:columnIndex = cursor.getColumnIndex(filePathColumn [0]);
文件名= cursor.getString(参数:columnIndex);
cursor.close();
尝试 {
是= getContentResolver()openInputStream(selectedImage)。
的BufferedInputStream双=新的BufferedInputStream(是);
点阵位图= BitmapFactory.de codeStream(之二);
preview.setImageBitmap(位);
preview.setVisibility(ImageView.VISIBLE);
}赶上(FileNotFoundException异常E){
}
}
}
}
私人类型类[] convertJSONArray(JSONArray JSONArray),其中{
INT的len = jsonArray.length();
类型类[] T =新类型类[LEN]
如果(jsonArray!= NULL){
的for(int i = 0; I< LEN;我++){
尝试 {
JSONObject的O = jsonArray.getJSONObject(我);
T [i] =新类型类();
T [I] .setName(o.getString(TYPE_NAME));
T [I] .setId(o.getString(TYPE_ID));
}赶上(JSONException E){
e.printStackTrace();
}
}
}
返回吨;
}
保护的布尔_checkFormValues(){
布尔结果= TRUE;
如果(name.getText()。长度()== 0){
name.requestFocus();
结果= FALSE;
}
如果(((类型类)subtype.getSelectedItem())。的getId()== NULL){
subtype.requestFocus();
结果= FALSE;
}
返回结果;
}
}
错误日志
11-07 23:55:26.914:E / AndroidRuntime(15457):致命异常:AsyncTask的#3
11-07 23:55:26.914:E / AndroidRuntime(15457):java.lang.RuntimeException的:执行doInBackground时出错()
11-07 23:55:26.914:E / AndroidRuntime(15457):在android.os.AsyncTask $ 3.done(AsyncTask.java:278)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.util.concurrent.FutureTask中$ Sync.innerSetException(FutureTask.java:273)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:307)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.lang.Thread.run(Thread.java:864)
11-07 23:55:26.914:E / AndroidRuntime(15457):java.lang.OutOfMemoryError:产生的原因(堆大小= 35491KB,分配= 27993KB)
11-07 23:55:26.914:E / AndroidRuntime(15457):在android.graphics.BitmapFactory.nativeDe codeFILE(本机方法)
11-07 23:55:26.914:E / AndroidRuntime(15457):在android.graphics.BitmapFactory.de codeFILE(BitmapFactory.java:373)
11-07 23:55:26.914:E / AndroidRuntime(15457):在android.graphics.BitmapFactory.de codeFILE(BitmapFactory.java:443)
11-07 23:55:26.914:E / AndroidRuntime(15457):在prod.vegs.ProductForm $ SendDataJSON.doInBackground(ProductForm.java:272)
11-07 23:55:26.914:E / AndroidRuntime(15457):在prod.vegs.ProductForm $ SendDataJSON.doInBackground(ProductForm.java:1)
11-07 23:55:26.914:E / AndroidRuntime(15457):在android.os.AsyncTask $ 2.call(AsyncTask.java:264)
11-07 23:55:26.914:E / AndroidRuntime(15457):在java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)
11-07 23:55:26.914:E / AndroidRuntime(15457):4 ...更多
位图是非常大内存的消费者。有两个加载到内存可能是大问题。您应该考虑使用<一个href="http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html">BitmapFactory.Options当你去code新位图。此外,你不需要 BM 2
。相反,更换符合这样的:
BM = Bitmap.createScaledBitmap(BM,宽度,高度,真正的);
最后,如果你没有其他选择,你可以使用应用程序的属性提升你的应用程序的堆大小安卓largeHeap =真正的
在 AndroidManifest。 XML 的。应该没有必要使用此选项 - 并且应该只能算是极图形密集型应用程序
修改
另外一个链接,你可以找到最优化的位图的使用有所帮助:<一href="http://developer.android.com/training/tv/optimizing-layouts-tv.html#HandleLargeBitmaps">http://developer.android.com/training/tv/optimizing-layouts-tv.html#HandleLargeBitmaps
I have a memory leak in this file, I cannot find where exactly, but I think is the image around --> (Bitmap bm = BitmapFactory.decodeFile(filename))
, I have tried many different ways but I can't get it to work.
package prod.vegs;
//All imports here but not need to write them all now :-)
public class ProductForm extends Activity {
private static int TAKE_PICTURE = 1;
private static int SELECT_PICTURE = 2;
//JSON Response node names
private static String KEY_SUCCESS = "success";
private static String ERROR_MSG = "error_msg";
private static String KEY_TYPES = "subtypes";
private static String TYPE_NAME = "name";
private static String TYPE_ID = "id_type";
private static String PRODUCT_ID = "id_product";
private JSONObject json;
private JSONParser jsonParser;
private String barcodeStr;
private String filename;
private int code;
private ProgressDialog dialog;
private TypeClass[] items;
private TypeClass[] sub_items;
//Declare assets objects
Spinner type;
Spinner subtype;
TextView errorMsg;
TextView description;
TextView name;
Button camera;
Button gallery;
Intent intent;
ImageView preview;
Bundle bundle;
LinearLayout errorMsgContainer;
Context context;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.product_form);
context = this;
Bundle b = getIntent().getExtras();
barcodeStr = b.getString("barcode");
jsonParser = new JSONParser();
dialog = new ProgressDialog(this);
dialog.setMessage(getString(R.string.loading));
dialog.setTitle(getString(R.string.progress));
dialog.setCancelable(true);
//Set assets
name = (TextView) findViewById(R.id.productName);
description = (TextView) findViewById(R.id.productDescription);
errorMsg = (TextView) findViewById(R.id.error_msg);
errorMsgContainer = (LinearLayout) findViewById(R.id.error_msg_container);
type = (Spinner) findViewById(R.id.productParentType);
subtype = (Spinner) findViewById(R.id.productType);
camera = (Button) findViewById(R.id.productCamera);
gallery = (Button) findViewById(R.id.productGallery);
preview = (ImageView) findViewById(R.id.productPreview);
filename = Environment.getExternalStorageDirectory() + String.format(getString(R.string.api_product_form_picture_file), barcodeStr);
Boolean fromScanner = b.getBoolean("scanner");
if (fromScanner == true) {
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
alertbox.setMessage(getString(R.string.insert_product));
alertbox.setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg_1, int arg_num) {
final Functions function = new Functions();
List<NameValuePair> params = new ArrayList<NameValuePair>();
String url = String.format(getString(R.string.api_product_form_types_url), getString(R.string.api_url));
json = function.loadJSONUrl(url, params);
if(json != null){
try {
if (json.getString(KEY_SUCCESS) != null) {
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
JSONArray types = json.getJSONArray(KEY_TYPES);
items = convertJSONArray(types);
SpinAdapter listViewArrayAdapter = new SpinAdapter(context, android.R.layout.simple_spinner_item, items);
listViewArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
type.setAdapter(listViewArrayAdapter);
type.setOnItemSelectedListener(new OnItemSelectedListener(){
public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) {
try {
String url = String.format(getString(R.string.api_subtypes_id_url), getString(R.string.api_url), ((TypeClass) type.getSelectedItem()).getId());
List<NameValuePair> params = new ArrayList<NameValuePair>();
JSONObject json_subtypes = function.loadJSONUrl(url, params);
if (json_subtypes.getString(KEY_SUCCESS) != null) {
JSONArray subtypes = json_subtypes.getJSONArray(KEY_TYPES);
sub_items = convertJSONArray(subtypes);
SpinAdapter subTypeAdapter = new SpinAdapter(context, android.R.layout.simple_spinner_item, sub_items);
subTypeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
subtype.setAdapter(subTypeAdapter);
subtype.setPrompt("Selecciona la cateogría");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void onNothingSelected(AdapterView<?> args) {
//Auto-generated method stub
}
});
type.setPrompt("Selecciona la cateogría");
//camera action
camera.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
int timeMili = (int) (System.currentTimeMillis());
filename = Environment.getExternalStorageDirectory() + "/" + timeMili + ".jpg";
Uri output = Uri.fromFile(new File(filename));
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
code = TAKE_PICTURE;
startActivityForResult(intent, code);
}
});
//gallery action
gallery.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
code = SELECT_PICTURE;
startActivityForResult(intent, code);
}
});
//button of the form
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (!NetworkHelper.CheckNetworkStatus(view.getContext())) {
return;
}
bundle = new Bundle();
bundle.putString("barcode", barcodeStr.toString());
bundle.putString("name", name.getText().toString());
bundle.putString("description", description.getText().toString());
bundle.putString("type_id", ((TypeClass) subtype.getSelectedItem()).getId());
if (_checkFormValues()) {
new SendDataJSON().execute(view);
} else {
Toast.makeText( view.getContext(), getString(R.string.error_form_incomplete), Toast.LENGTH_LONG).show();
}
}
});
} else {
errorMsg.setText(json.getString(ERROR_MSG));
errorMsgContainer.setVisibility(LinearLayout.VISIBLE);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
}
}
}).setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent myIntent = new Intent(ProductForm.this, CaptureActivity.class);
startActivity(myIntent);
finish();
}
}).show();
} else {
finish();
}
}
class SendDataJSON extends AsyncTask<View, Void, View>{
@Override
protected View doInBackground(View... views) {
String url = String.format(getString(R.string.api_product_form_url),getString(R.string.api_url));
HttpPost httpPost = new HttpPost(url);
try {
// Add your data
MultipartEntity entity = new MultipartEntity();
File photo = new File(filename);
if (photo.exists()) {
//create the compressed image to send
//create the file to send the image
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (!sd.canWrite()) { sd = data; }
String destinationFolderPath = sd + "/" + getString(R.string.app_dir) + "/";
String destinationImageName= "photo_" + bundle.getString("barcode") + ".jpg";
//create the folder to store it
File destinationFolder = new File(destinationFolderPath);
if (!destinationFolder.exists()) {
destinationFolder.mkdirs();
}
File destination = new File(destinationFolder, destinationImageName);
FileOutputStream out = new FileOutputStream(destination);
Bitmap bm = BitmapFactory.decodeFile(filename);
int width = bm.getWidth();
int height = bm.getHeight();
int max_value = 1024;
int max = Math.max(width,height);
if (max > max_value) {
width = width * max_value / max;
height = height * max_value / max;
}
//Make the new image with the new size values
try {
Bitmap bm2 = Bitmap.createScaledBitmap(bm, width, height, true);
//Compress the image
bm2.compress(CompressFormat.JPEG, 75, out);
out.flush();
out.close();
destination = new File(destinationFolder, destinationImageName);
FileBody filePhoto = new FileBody(destination);
entity.addPart("image", filePhoto);
} catch (Exception e) {
Log.w(ProductForm.class.getSimpleName(), e);
}
}
SharedPreferences userSettings = getSharedPreferences("UserPreferences", Context.MODE_PRIVATE);
Charset chars = Charset.forName("UTF-8");
entity.addPart("barcode", new StringBody(bundle.getString("barcode"),chars));
entity.addPart("name", new StringBody(bundle.getString("name"),chars));
entity.addPart("description", new StringBody(bundle.getString("description"),chars));
entity.addPart("id_type", new StringBody(bundle.getString("type_id")));
entity.addPart("uid",new StringBody(userSettings.getString("uid", ""),chars));
httpPost.setEntity(entity);
HttpClient httpclient = new DefaultHttpClient();
httpclient.execute(httpPost);
} catch (IOException e) {
//
}
return views[0];
}
@Override
protected void onPreExecute() {
dialog.setMax(100);
dialog.setProgress(0);
dialog.show();
}
@Override
protected void onPostExecute(View view) {
//redirect to the product page
setContentView(R.layout.product_barcode);
String url = String.format(getString(R.string.api_product_barcode_url), getString(R.string.api_url), bundle.getString("barcode"));
new LoadJSONBarcode().execute(url);
}
}
//Send data to server and receive respond
private class LoadJSONBarcode extends AsyncTask<String, Void, JSONObject>{
@Override
protected JSONObject doInBackground(String... urls) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
json = new JSONObject();
json = jsonParser.getJSONFromUrl(urls[0], params);
return json;
}
@Override
protected void onPreExecute() {
dialog.setMax(100);
dialog.setProgress(0);
dialog.show();
}
@Override
protected void onPostExecute(JSONObject json) {
if (json != null) {
try {
if (json.getString(KEY_SUCCESS) != null) {
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
View view = findViewById(R.id.productBarcodeXML);
Intent myIntent = new Intent(view.getContext(), Product.class);
Bundle b = new Bundle();
b.putString("id", json.getString(PRODUCT_ID));
myIntent.putExtras(b);
view.getContext().startActivity(myIntent);
} else {
errorMsg.setText(json.getString(ERROR_MSG));
errorMsgContainer.setVisibility(LinearLayout.VISIBLE);
}
dialog.dismiss();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE) {
if (data != null) {
if (data.hasExtra("data")) {
preview.setImageBitmap((Bitmap) data.getParcelableExtra("data"));
preview.setVisibility(ImageView.VISIBLE);
}
} else {
preview.setImageBitmap(BitmapFactory.decodeFile(filename));
preview.setVisibility(ImageView.VISIBLE);
new MediaScannerConnectionClient() {
private MediaScannerConnection msc = null; {
msc = new MediaScannerConnection(getApplicationContext(), this); msc.connect();
}
public void onMediaScannerConnected() {
msc.scanFile(filename, null);
}
public void onScanCompleted(String path, Uri uri) {
msc.disconnect();
}
};
}
} else if (requestCode == SELECT_PICTURE){
if (data != null){
Uri selectedImage = data.getData();
InputStream is;
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filename = cursor.getString(columnIndex);
cursor.close();
try {
is = getContentResolver().openInputStream(selectedImage);
BufferedInputStream bis = new BufferedInputStream(is);
Bitmap bitmap = BitmapFactory.decodeStream(bis);
preview.setImageBitmap(bitmap);
preview.setVisibility(ImageView.VISIBLE);
} catch (FileNotFoundException e) {
}
}
}
}
private TypeClass[] convertJSONArray(JSONArray jsonArray){
int len = jsonArray.length();
TypeClass[] t = new TypeClass[len];
if (jsonArray != null) {
for (int i=0;i<len;i++){
try {
JSONObject o = jsonArray.getJSONObject(i);
t[i] = new TypeClass();
t[i].setName(o.getString(TYPE_NAME));
t[i].setId(o.getString(TYPE_ID));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return t;
}
protected boolean _checkFormValues() {
boolean result = true;
if (name.getText().length() == 0) {
name.requestFocus();
result = false;
}
if (((TypeClass) subtype.getSelectedItem()).getId() == null){
subtype.requestFocus();
result = false;
}
return result;
}
}
Error Log
11-07 23:55:26.914: E/AndroidRuntime(15457): FATAL EXCEPTION: AsyncTask #3
11-07 23:55:26.914: E/AndroidRuntime(15457): java.lang.RuntimeException: An error occured while executing doInBackground()
11-07 23:55:26.914: E/AndroidRuntime(15457): at android.os.AsyncTask$3.done(AsyncTask.java:278)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.lang.Thread.run(Thread.java:864)
11-07 23:55:26.914: E/AndroidRuntime(15457): Caused by: java.lang.OutOfMemoryError: (Heap Size=35491KB, Allocated=27993KB)
11-07 23:55:26.914: E/AndroidRuntime(15457): at android.graphics.BitmapFactory.nativeDecodeFile(Native Method)
11-07 23:55:26.914: E/AndroidRuntime(15457): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:373)
11-07 23:55:26.914: E/AndroidRuntime(15457): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:443)
11-07 23:55:26.914: E/AndroidRuntime(15457): at prod.vegs.ProductForm$SendDataJSON.doInBackground(ProductForm.java:272)
11-07 23:55:26.914: E/AndroidRuntime(15457): at prod.vegs.ProductForm$SendDataJSON.doInBackground(ProductForm.java:1)
11-07 23:55:26.914: E/AndroidRuntime(15457): at android.os.AsyncTask$2.call(AsyncTask.java:264)
11-07 23:55:26.914: E/AndroidRuntime(15457): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-07 23:55:26.914: E/AndroidRuntime(15457): ... 4 more
Bitmaps are very big memory consumers. Having two loaded into memory could be the big issue. You should consider using BitmapFactory.Options when you decode a new bitmap. Also, you don't need bm2
. Instead, replace that line with this:
bm = Bitmap.createScaledBitmap(bm, width, height, true);
Finally, if you have no other options, you can increase your app's heap size using the Application attribute android:largeHeap="true"
in your AndroidManifest.xml. This option should not be needed - and should only be considered for extremely graphic-intensive applications.
EDIT
Another link you may find helpful for optimizing Bitmap usage: http://developer.android.com/training/tv/optimizing-layouts-tv.html#HandleLargeBitmaps
这篇关于试图用图像发送表单PHP服务器时,在Android的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!