【问题标题】:Imageview and OutOfMemory in AndroidAndroid 中的 Imageview 和 OutOfMemory
【发布时间】:2011-07-25 10:27:53
【问题描述】:

你好 Stackoverflow 朋友,

我需要一个应用程序,使用相机捕获图像并重复显示在图像视图中。拍照后我将这张照片发送到服务器。对于这个过程,我使用名为 myBackgroundUploader 的 AsynTask 类。当我单击按钮时,我调用了 Asysnctask。我完成了,但是在拍摄了 2 三张照片后,我得到了内存不足错误并且我的应用程序强制关闭。我试图回收(),空值但没有用。谁能告诉我如何避免这个错误。这是我得到的日志。

    onCreate()
    {
    setContentView(R.layout.detail_profile);

    String fname=new File(getFilesDir(), "MyFile.jpeg").getAbsolutePath();
     if(imgView!=null)
               {
                   imgView.destroyDrawingCache();
               }
                imgView=(ImageView)findViewById(R.id.imageView1);
                imgView.setImageURI(Uri.fromFile(new File(fname)));

    }


public void onClick(View v) {

                 if(checkInternetConnection()==false)
                {
                     new AlertDialog.Builder(detailProfile.this).setTitle("Warning!").setMessage("No Internet connection").setIcon(R.drawable.icon).setNeutralButton("Close", null).show();

                }   if(diTask!=null)
                        {
                            AsyncTask.Status diStatus=diTask.getStatu();
                            if(diStatus!=AsyncTask.Status.FINISHED)
                            {
                                return;
                            }

                        }
                        fileprocess();
                        diTask=new myBackgroundUploader(detailProfile.this);
                        diTask.execute("url for server");

}

 myBackgroundUploader.java

protected void onPreExecute()
    {

        progDailog = ProgressDialog.show(mcontext,
                "Syncing with server ", "Please wait....",
                true);

    }
    protected Bitmap doInBackground(String...pram)
    {
        Log.v("doback","uploading,,");

        uploadImage(pram[0]); //here parm[0]is my server url
        return null;

    }
    protected void onPostExecute(Bitmap bm)
    {

    }

    public void uploadImage(String...urls)
    {
         String fname=new File(mcontext.getFilesDir(),"MyFile.jpeg").getAbsolutePath();
Bitmap testAB=null;
        BitmapFactory.Options options= new BitmapFactory.Options();
        options.inSampleSize = 4;
        testAB=BitmapFactory.decodeFile(fname, options);


        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        testAB.compress(Bitmap.CompressFormat.JPEG,50, bao);
        byte [] ba = bao.toByteArray();
        String ba1=Base64.encodeBytes(ba);
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("image",ba1));
        nameValuePairs.add(new BasicNameValuePair("address",detailProfile.address.getText().toString()));


        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(urls[0]);
        HttpParams param=new BasicHttpParams();
        HttpConnectionParams.setSoTimeout(param, 60000);
        httppost.setParams(param);
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        is =entity.getContent();
        progDailog.dismiss();
        //urls[0].recycle();
        ba=null;
        ba1=null;
        bao.flush();
        testAB.recycle();


      }



07-25 15:39:38.613: ERROR/dalvikvm-heap(31423): 9830400-byte external allocation too large for this process.
07-25 15:39:38.640: ERROR/GraphicsJNI(31423): VM won't let us allocate 9830400 bytes
07-25 15:39:38.640: DEBUG/dalvikvm(31423): GC_FOR_MALLOC freed 1K, 48% free 2904K/5511K, external 21335K/23354K, paused 16ms
07-25 15:39:38.644: DEBUG/skia(31423): --- decoder->decode returned false
07-25 15:39:38.656: WARN/dalvikvm(31423): threadid=9: thread exiting with uncaught exception (group=0x40015560)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423): FATAL EXCEPTION: AsyncTask #1
07-25 15:39:38.664: ERROR/AndroidRuntime(31423): java.lang.RuntimeException: An error occured while executing doInBackground()
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.lang.Thread.run(Thread.java:1019)


07-25 15:39:38.664: ERROR/AndroidRuntime(31423): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:284)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:309)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at com.rodasys.profile.myBackgroundUploader.uploadImage(myBackgroundUploader.java:133)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at com.rodasys.profile.myBackgroundUploader.doInBackground(myBackgroundUploader.java:57)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at com.rodasys.profile.myBackgroundUploader.doInBackground(myBackgroundUploader.java:1)

提前致谢

【问题讨论】:

  • 没有代码示例很难猜出问题出在哪里。但可能你在某处有内存泄漏
  • 我经历过很多次。请在此处发布您的代码,以便每个人都可以帮助您摆脱困境。
  • 嗨 matekm 我更新了我的问题并添加了我的代码。
  • 嗨 Kristiono Setyadi 我更新了我的问题并添加了我的代码

标签: java android


【解决方案1】:

是的,imageview 是一个静态文件。公共静态ImageView imgView

这似乎是导致内存泄漏并因此导致内存不足的问题。 您可能想阅读这篇关于如何避免它的优秀文章:http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/

简而言之:不要使用静态实例变量。删除static 应该没问题(如果它不会损害您的代码逻辑),否则您将不得不重新设计没有包含 ImageView 的静态字段的活动。

【讨论】:

    【解决方案2】:

    我认为您应该在对图像进行任何繁重操作之前执行recycle。因此,我建议您尝试以下操作,而不是做您所做的事情:

    if (testAB != null) {
        testAB.recycle();
    }
    
    // do your heavy image operation here
    

    在对图像执行某些操作时,不要忘记使用 AsyncTask 等后台进程,尤其是在将图像分配给 UI 元素时,例如图像视图。

    并尝试将解码后的图像放入您的 ImageView 中,而不是原始图像,因为原始图像的尺寸可能总是比解码后的图像大。

    让我知道这是否适合你。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多