试图用图像发送表单PHP服务器时,在Android的内存泄漏 [英] Memory leak in Android when trying to send a form with image to PHP server

查看:172
本文介绍了试图用图像发送表单PHP服务器时,在Android的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这个文件中的内存泄漏,我找不到在什么地方,但我认为这是在图像周围 - > (位图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,长I​​D){
                                            尝试 {
                                                字符串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_IM​​AGE_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆