处理java.lang.OutOfMemoryError?

时间:2014-01-27 10:28:49

标签: android memory-leaks wallpaper

我制作了一个壁纸设置应用程序,在我的设备(Nexus 5)上它工作得很好但是在Galaxy TAB,Fame甚至是Optimus上它会产生java.lang.OutOfMemory错误。我知道我不应该在一个应用程序中使用如此多的ImageView,或者我应该这样做?好吧,问题是,如果我能以某种方式修复此应用程序,或者我应该更改整个应用程序结构,我不会。

我将向您展示我的APP的小型演示文稿

MainActivity:

 package app.technozed.cablewallpapershd;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.WallpaperManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

 public class MainActivity extends Activity implements OnClickListener {

ImageView display;
int toPhone;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    System.gc();
    toPhone = R.drawable.wal1;
    display = (ImageView) findViewById(R.id.WPdisplay);
    ImageView image1 = (ImageView) findViewById(R.id.WPimg1);
    ImageView image2 = (ImageView) findViewById(R.id.WPimg2);
    ImageView image3 = (ImageView) findViewById(R.id.WPimg3);
    ImageView image4 = (ImageView) findViewById(R.id.WPimg4);
    ImageView image5 = (ImageView) findViewById(R.id.WPimg5);
    ImageView image6 = (ImageView) findViewById(R.id.WPimg6);
    ImageView image7 = (ImageView) findViewById(R.id.WPimg7);
    ImageView image8 = (ImageView) findViewById(R.id.WPimg8);
    ImageView image9 = (ImageView) findViewById(R.id.WPimg9);
    ImageView image10 = (ImageView) findViewById(R.id.WPimg10);
    Button setWall = (Button) findViewById(R.id.BsetWall);
    image1.setOnClickListener(this);
    image2.setOnClickListener(this);
    image3.setOnClickListener(this);
    image4.setOnClickListener(this);
    image5.setOnClickListener(this);
    image6.setOnClickListener(this);
    image7.setOnClickListener(this);
    image8.setOnClickListener(this);
    image9.setOnClickListener(this);
    image10.setOnClickListener(this);
    setWall.setOnClickListener(this);
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

**public Bitmap decodeAndResizeFile(File f) {**
    try {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 70;

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE
                    || height_tmp / 2 < REQUIRED_SIZE)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {
    }
    return null;
}

@Override
public void onClick(View v) {
    switch (v.getId()){
    case R.id.WPimg1:
         display.setImageResource(R.drawable.wal1);
         toPhone = R.drawable.wal1;
         **File file=new File(Uri.parse(String.valueOf(toPhone)));
         Bitmap bmpp = decodeAndResizeFile(file);
        display.setImageBitmap(bm)(bmpp);**

         break;
    case R.id.WPimg2:
         display.setImageResource(R.drawable.wal2);
         toPhone = R.drawable.wal2;
         break;
    case R.id.WPimg3:
         display.setImageResource(R.drawable.wal3);
         toPhone = R.drawable.wal3;
         break;
    case R.id.WPimg4:
         display.setImageResource(R.drawable.wal4);
         toPhone = R.drawable.wal4;
         break;
    case R.id.WPimg5:
         display.setImageResource(R.drawable.wal5);
         toPhone = R.drawable.wal5;
         break;
    case R.id.WPimg6:
         display.setImageResource(R.drawable.wal6);
         toPhone = R.drawable.wal6;
         break;
    case R.id.WPimg7:
         display.setImageResource(R.drawable.wal7);
         toPhone = R.drawable.wal7;
         break;
    case R.id.WPimg8:
         display.setImageResource(R.drawable.wal8);
         toPhone = R.drawable.wal8;
         break;
    case R.id.WPimg9:
         display.setImageResource(R.drawable.wal9);
         toPhone = R.drawable.wal9;
         break;
    case R.id.WPimg10:
         display.setImageResource(R.drawable.wal10);
         toPhone = R.drawable.wal10;
         break;
    case R.id.BsetWall:
         try{
             WallpaperManager.getInstance(getApplicationContext()).setResource(toPhone);
             Toast.makeText(getApplicationContext(), "Wallpaper was set!", Toast.LENGTH_SHORT).show();
         } catch(IOException e) {
             e.printStackTrace();
             Toast.makeText(getApplicationContext(), "No privileges!", Toast.LENGTH_SHORT).show();
         }
         break;
    }
    }
    }

这是我的布局XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".BasicScreenActivity"
android:layout_gravity="center_vertical"
android:background="@drawable/background" >
     <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="75dp"
    android:orientation="horizontal" />
 <ImageView 
    android:id="@+id/WPdisplay"
    android:src="@drawable/wall1"
    android:layout_width="wrap_content"
    android:layout_height="0dip"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:contentDescription="@string/desc" />
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center" >
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<ImageView 
    android:id="@+id/WPimg1"
    android:src="@drawable/w1"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg2"
    android:src="@drawable/w2"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView  
    android:id="@+id/WPimg3"
    android:src="@drawable/w3"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg4"
    android:src="@drawable/w4"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg5"
    android:src="@drawable/w5"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg6"
    android:src="@drawable/w6"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg7"
    android:src="@drawable/w7"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg8"
    android:src="@drawable/w8"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg9"
    android:src="@drawable/w9"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />
<ImageView 
    android:id="@+id/WPimg10"
    android:src="@drawable/w10"
    android:layout_width="125dp"
    android:layout_height="125dp"
    android:padding="1dp"
    android:contentDescription="@string/desc" />

</LinearLayout>
</HorizontalScrollView>
               <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="25dp"
    android:orientation="horizontal" />
<Button
    android:id="@+id/BsetWall"
    android:layout_width="200dp"
    android:layout_height="28dp"
    android:background="@drawable/btn"
    android:layout_gravity="center"
    android:paddingBottom="8dp" />
</LinearLayout>

以下是错误消息

   java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:500)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:353)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785)
at android.content.res.Resources.loadDrawable(Resources.java:1935)
at android.content.res.Resources.getDrawable(Resources.java:664)
at android.widget.ImageView.resolveUri(ImageView.java:611)
at android.widget.ImageView.setImageResource(ImageView.java:354)
at app.technozed.despicablemewallpapershd.MainActivity.onClick(MainActivity.java:334)
at android.view.View.performClick(View.java:4147)
at android.view.View$PerformClick.run(View.java:17161)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:4787)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(Native Method)

如你所见,我已经添加了垃圾收集器,但它并没有真正帮助。有任何想法吗?建议?

2 个答案:

答案 0 :(得分:0)

    public Bitmap decodeAndResizeFile(File f) {
            try {
                // Decode image size
                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(new FileInputStream(f), null, o);

                // The new size we want to scale to
                final int REQUIRED_SIZE = 70;

                // Find the correct scale value. It should be the power of 2.
                int width_tmp = o.outWidth, height_tmp = o.outHeight;
                int scale = 1;
                while (true) {
                    if (width_tmp / 2 < REQUIRED_SIZE
                            || height_tmp / 2 < REQUIRED_SIZE)
                        break;
                    width_tmp /= 2;
                    height_tmp /= 2;
                    scale *= 2;
                }
                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = scale;
                return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
            } catch (FileNotFoundException e) {
            }
            return null;
        }





Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };
            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);

File file = new File(picturePath);// 
Bitmap bmpp = decodeAndResizeFile(file);

答案 1 :(得分:0)

Try to use this ur code that modifying me 

@Override
public void onClick(View v) {
           System.gc();
    switch (v.getId()){

  case R.id.WPimg1:

         toPhone = R.drawable.wall1;
 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);

         break;
    case R.id.WPimg2:

         toPhone = R.drawable.wall2;
 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg3:

         toPhone = R.drawable.wall3;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg4:

         toPhone = R.drawable.wall4;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg5:

         toPhone = R.drawable.wall5;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg6:

         toPhone = R.drawable.wall6;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg7:

         toPhone = R.drawable.wall7;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg8:

         toPhone = R.drawable.wall8;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg9:

         toPhone = R.drawable.wall9;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.WPimg10:

         toPhone = R.drawable.wall10;

 File file=new File(Uri.parse(String.valueOf(toPhone)));
 Bitmap bmpp = decodeAndResizeFile(file);
display.setImageBitmap(bm)(bmpp);
         break;
    case R.id.BsetWall:
         try{
                 WallpaperManager.getInstance(getApplicationContext()).setResource(toPhone);
             Toast.makeText(getApplicationContext(), "Wallpaper was set!", Toast.LENGTH_SHORT).show();
         } catch(IOException e) {
             e.printStackTrace();
             Toast.makeText(getApplicationContext(), "No privileges!", Toast.LENGTH_SHORT).show();
         }
         break;
    }
    }