设置图像时出现内存不足错误

时间:2014-01-22 22:41:45

标签: android gridview imageview

每当我尝试设置图像时,都会出现OOM错误。

我的EditProfileFragment.java

package org.text.me.actionBar.edit.fragments;

import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.quickblox.core.QBCallback;
import com.quickblox.core.result.Result;
import org.text.me.R;
import org.text.me.actionBar.definitions.Queries;
import org.text.me.actionBar.edit.activity.ChangeNameActivity;
import org.text.me.actionBar.edit.activity.ChangePasswordActivity;
import org.text.me.actionBar.gallery.activity.GalleryActivity;
import org.text.me.actionBar.holder.DataHolder;
import org.text.me.actionBar.utils.bitmap.BitmapUtility;

import static android.widget.ImageView.ScaleType.FIT_CENTER;
import static org.text.me.actionBar.definitions.Constants.TAG;
import static org.text.me.actionBar.preferences.SharedConstants.PROFILE_PICTURE_PATH;
import static org.text.me.actionBar.preferences.SharedConstants.SIGN_IN_USER_FULL_NAME;
import static org.text.me.actionBar.preferences.SharedPrefs.getStringPrefs;

public class EditProfileFragment extends Fragment implements View.OnClickListener, QBCallback {

private View        editProfileView;
private ImageView   ivProfilePicture;
private TextView    tvFullName;
private ImageButton ibPassword;
private ImageButton ibName;

private ProgressDialog progressDialog;

private String fullName = null;

private Bitmap DEFAULT_PROFILE_PICTURE = null;
private Bitmap PROFILE_PICTURE         = null;
private int    GALLERY                 = 1;

private static       int                   DEFAULT_WIDTH            = 300;
private static       int                   DEFAULT_HEIGHT           = 250;
private static final int                   DEFAULT_COMPRESS_QUALITY = 100;
private static final Bitmap.CompressFormat DEFAULT_COMPRESS_FORMAT  = Bitmap.CompressFormat.PNG;
private static final boolean               fileIsPublic             = false;

private static final String FOLDER_NAME     = "Text Me";
private static final String SUB_FOLDER_NAME = "Profile Pictures";
private static       String FILE_NAME       = null;

public static EditProfileFragment getInstance () {
    return new EditProfileFragment ();
}

@Override
public void onCreate (Bundle savedInstanceState) {
    super.onCreate ( savedInstanceState );
    setHasOptionsMenu ( false );
}

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    editProfileView = inflater.inflate ( R.layout.fragment_edit_profile, container, false );
    setupUi ();
    setupProgressDialog ();

    return editProfileView;
}

private void setupUi () {
    tvFullName = (TextView) editProfileView.findViewById ( R.id.tvName );
    ivProfilePicture = (ImageView) editProfileView.findViewById ( R.id.ivEditProfilePicture );
    ibPassword = (ImageButton) editProfileView.findViewById ( R.id.ibPassword );
    ibName = (ImageButton) editProfileView.findViewById ( R.id.ibName );

    tvFullName.setText ( getStringPrefs ( getActivity (), SIGN_IN_USER_FULL_NAME ) );

    if ( getStringPrefs ( getActivity (), PROFILE_PICTURE_PATH ).equals ( null ) || getStringPrefs ( getActivity
                                                                                                             (),
                                                                                                     PROFILE_PICTURE_PATH ).equals ( "path" ) )
        setupDefaultProfilePicture ();
    else
        setupProfilePicture ();


    ibName.setOnClickListener ( this );
    ibPassword.setOnClickListener ( this );
    ivProfilePicture.setOnClickListener ( this );
}

private void setupProgressDialog () {
    progressDialog = new ProgressDialog ( this.getActivity () );
    progressDialog.setMessage ( getResources ().getString ( R.string.loading ) );
    progressDialog.setCancelable ( false );
}

private void setupDefaultProfilePicture () {
    DEFAULT_PROFILE_PICTURE = BitmapUtility.decodeSampledBitmapFromResource (
            getResources (),
            R.drawable.action_people,
            DEFAULT_WIDTH,
            DEFAULT_HEIGHT );
    ivProfilePicture.setScaleType ( FIT_CENTER );
    ivProfilePicture.setImageBitmap ( DEFAULT_PROFILE_PICTURE );
}

private void setupProfilePicture () {
    if ( PROFILE_PICTURE != null ) PROFILE_PICTURE.recycle ();

    BitmapFactory.Options options = new BitmapFactory.Options ();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    options.inInputShareable = true;
    options.inPurgeable = true;
    PROFILE_PICTURE = BitmapFactory.decodeFile ( getStringPrefs ( getActivity (), PROFILE_PICTURE_PATH ),
                                                 options );
    Log.w ( TAG, PROFILE_PICTURE.toString () );
    ivProfilePicture.setImageBitmap ( PROFILE_PICTURE );
}

@Override
public void onClick (View v) {
    switch ( v.getId () ) {
        case R.id.ibPassword:
            startActivity ( new Intent ( this.getActivity (), ChangePasswordActivity.class ) );
            break;

        case R.id.ibName:
            startActivity ( new Intent ( this.getActivity (), ChangeNameActivity.class ) );
            break;

        case R.id.ivEditProfilePicture:
            Intent intent = new Intent ( getActivity (), GalleryActivity.class );
            startActivity ( intent );
            break;
    }
}

@Override
public void onComplete (Result result) {

}

@Override
public void onComplete (Result result, Object query) {
    Queries queryType = (Queries) query;
    if ( result.isSuccess () ) {
        switch ( queryType ) {
            case QUERY_UPDATE_USER_INFO:
                DataHolder.getDataHolder ().getSignInUser ().setFullName ( fullName );
                progressDialog.dismiss ();
                Toast.makeText ( this.getActivity (), getResources ().getString ( R.string
                                                                                          .action_edit_successful ),

                                 Toast.LENGTH_SHORT ).show ();
                break;
        }
    } else {
        progressDialog.hide ();
        Toast.makeText ( this.getActivity (), result.getErrors ().get ( 0 ).toString (),
                         Toast.LENGTH_SHORT ).show ();
        Log.e ( TAG, result.getErrors ().toString () );
    }
}
}

我的GalleryActivity.java

package org.text.me.actionBar.gallery.activity;

import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.TypedValue;
import android.widget.GridView;
import org.text.me.R;
import org.text.me.actionBar.gallery.adapter.GalleryAdapter;
import org.text.me.actionBar.gallery.helper.GalleryUtils;

import java.util.ArrayList;

import static org.text.me.actionBar.gallery.helper.GalleryConstants.GRID_PADDING;
import static org.text.me.actionBar.gallery.helper.GalleryConstants.NUM_OF_COLS;

public class GalleryActivity extends ActionBarActivity {

private ActionBar actionBar;
private ArrayList<String> imagePaths = new ArrayList<String> ();
private GalleryAdapter mAdapter;
private GridView       gvGallery;
private int            colWidth;
private GalleryUtils   galleryUtils;

@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate ( savedInstanceState );
    setContentView ( R.layout.activity_grid_view_gallery );

    setupActionBar ();
    setupGallery ();
}

private void setupActionBar () {
    actionBar = getSupportActionBar ();
    actionBar.setDisplayHomeAsUpEnabled ( true );
    actionBar.setTitle ( "Gallery" );
}

private void setupGallery () {
    gvGallery = (GridView) findViewById ( R.id.gvGallery );

    galleryUtils = new GalleryUtils ( this );
    initialiseGridView ();
    imagePaths = galleryUtils.getFilePaths ();
    mAdapter = new GalleryAdapter ( GalleryActivity.this, imagePaths, colWidth );
    gvGallery.setAdapter ( mAdapter );
}

private void initialiseGridView () {
    Resources resources = getResources ();

    float padding = TypedValue.applyDimension ( TypedValue.COMPLEX_UNIT_DIP, GRID_PADDING,
                                                resources.getDisplayMetrics () );
    colWidth = (int) ( ( galleryUtils.getScreenWidth () - ( ( NUM_OF_COLS + 1 ) * padding ) ) / NUM_OF_COLS );
    gvGallery.setNumColumns ( NUM_OF_COLS );
    gvGallery.setColumnWidth ( colWidth );
    gvGallery.setStretchMode ( GridView.NO_STRETCH );
    gvGallery.setPadding ( (int) padding, (int) padding, (int) padding, (int) padding );
    gvGallery.setHorizontalSpacing ( (int) padding );
    gvGallery.setVerticalSpacing ( (int) padding );
}
}

我的GalleryAdapter.class

package org.text.me.actionBar.gallery.adapter;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import org.text.me.actionBar.gallery.activity.FullScreenImageActivity;
import org.text.me.actionBar.utils.bitmap.BitmapUtility;

import java.util.ArrayList;

import static org.text.me.actionBar.definitions.Constants.IMAGE_PATH;
import static org.text.me.actionBar.preferences.SharedConstants.PROFILE_PICTURE_PATH;
import static org.text.me.actionBar.preferences.SharedPrefs.setStringPrefs;

public class GalleryAdapter extends BaseAdapter {

private Activity activity;
private ArrayList<String> filePaths = new ArrayList<String> ();
private int imageWidth;

public GalleryAdapter (Activity activity, ArrayList<String> filePaths, int imageWidth) {
    this.activity = activity;
    this.filePaths = filePaths;
    this.imageWidth = imageWidth;
}

@Override
public int getCount () {
    return this.filePaths.size ();
}

@Override
public Object getItem (int position) {
    return this.filePaths.get ( position );
}

@Override
public long getItemId (int position) {
    return position;
}

@Override
public View getView (int position, View convertView, ViewGroup parent) {
    ImageView imageView;
    if ( convertView == null ) imageView = new ImageView ( activity );
    else imageView = (ImageView) convertView;

    Bitmap image = BitmapUtility.decodeFileForGallery ( filePaths.get ( position ), imageWidth,
                                                        imageWidth );
    imageView.setScaleType ( ImageView.ScaleType.CENTER_CROP );
    imageView.setLayoutParams ( new GridView.LayoutParams ( imageWidth, imageWidth ) );
    imageView.setImageBitmap ( image );

    imageView.setOnClickListener ( new onImageClickListener ( position ) );

    return imageView;
}

class onImageClickListener implements View.OnClickListener {
    int position;

    public onImageClickListener (int position) {
        this.position = position;
    }

    @Override
    public void onClick (View v) {
        Intent intent = new Intent ( activity, FullScreenImageActivity.class );
        intent.putExtra ( IMAGE_PATH, filePaths.get ( position ) );
        setStringPrefs ( activity.getApplicationContext (), PROFILE_PICTURE_PATH,
                         filePaths.get ( position ) );
        activity.startActivity ( intent );
    }
}
}

我的FullScreenImageActivity.class

package org.text.me.actionBar.gallery.activity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import org.text.me.R;
import org.text.me.actionBar.gallery.helper.GalleryUtils;
import org.text.me.actionBar.main.activity.MainActionBarActivity;

import static org.text.me.actionBar.definitions.Constants.IMAGE_PATH;

public class FullScreenImageActivity extends ActionBarActivity implements View.OnClickListener {

private ActionBar    actionBar;
private GalleryUtils galleryUtils;
private String imagePosition = null;
private ImageView ivFullScreen;
private Button    bApplyImage;
private Bitmap    bitmap;

@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate ( savedInstanceState );
    setContentView ( R.layout.activity_full_screen_image );

    setupActionBar ();
    setupUi ();
    setupImage ();
}

private void setupActionBar () {
    actionBar = getSupportActionBar ();
    actionBar.setDisplayHomeAsUpEnabled ( true );
}

private void setupUi () {
    ivFullScreen = (ImageView) findViewById ( R.id.ivFullScreen );
    bApplyImage = (Button) findViewById ( R.id.bApplyImage );

    bApplyImage.setOnClickListener ( this );
}

private void setupImage () {
    galleryUtils = new GalleryUtils ( this );
    Intent intent = getIntent ();
    imagePosition = intent.getStringExtra ( IMAGE_PATH );

    BitmapFactory.Options options = new BitmapFactory.Options ();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    options.inInputShareable = true;
    options.inPurgeable = true;
    bitmap = BitmapFactory.decodeFile ( imagePosition, options );

    ivFullScreen.setImageBitmap ( bitmap );
}

@Override
public void onClick (View v) {
    switch ( v.getId () ) {
        case R.id.bApplyImage:
            startActivity ( new Intent ( FullScreenImageActivity.this, MainActionBarActivity.class ) );
            finish ();
            break;
    }
}
}

当我从FullScreenImageActivity导航到EditProfileFragment类时,我收到以下错误:

01-23 03:58:59.607    9655-9655/org.text.me E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
        at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
        at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:284)
        at org.text.me.actionBar.gallery.activity.FullScreenImageActivity.setupImage(FullScreenImageActivity.java:58)
        at org.text.me.actionBar.gallery.activity.FullScreenImageActivity.onCreate(FullScreenImageActivity.java:34)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1626)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1678)
        at android.app.ActivityThread.access$1500(ActivityThread.java:118)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:932)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:130)
        at android.app.ActivityThread.main(ActivityThread.java:3698)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:507)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633)
        at dalvik.system.NativeStart.main(Native Method)

但是当我重新打开我的应用程序时,它会设置图像。 第一次设置图像时如何避免OOM?请尽快帮我解决代码。

可能是错误发生,因为我正在尝试设置在FullScreenImageActivity.java类中打开的MainActionBarActivity.java中的图像。我认为当FullScreenImageActivity.java类关闭时,VM堆不会被回收,或者在MainActionbarActivity.java类中加载图像时应用程序崩溃。

这是我的MainActionBarActivity.java类的代码:

package org.text.me.actionBar.edit.fragments;

import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.quickblox.core.QBCallback;
import com.quickblox.core.QBCallbackImpl;
import com.quickblox.core.result.Result;
import com.quickblox.module.content.QBContent;
import com.quickblox.module.content.model.QBFile;
import com.quickblox.module.content.result.QBFileUploadTaskResult;
import com.quickblox.module.users.QBUsers;
import com.quickblox.module.users.model.QBUser;
import org.text.me.R;
import org.text.me.actionBar.definitions.Queries;
import org.text.me.actionBar.edit.activity.ChangeNameActivity;
import org.text.me.actionBar.edit.activity.ChangePasswordActivity;
import org.text.me.actionBar.gallery.activity.GalleryActivity;
import org.text.me.actionBar.holder.DataHolder;
import org.text.me.actionBar.utils.bitmap.BitmapUtility;
import org.text.me.actionBar.utils.external_storage.ExternalStorageUtils;

import java.io.File;

import static android.widget.ImageView.ScaleType.FIT_CENTER;
import static org.text.me.actionBar.definitions.Constants.TAG;
import static org.text.me.actionBar.preferences.SharedConstants.*;
import static org.text.me.actionBar.preferences.SharedPrefs.*;

public class EditProfileFragment extends Fragment implements View.OnClickListener, QBCallback {

private View        editProfileView;
private ImageView   ivProfilePicture;
private TextView    tvFullName;
private ImageButton ibPassword;
private ImageButton ibName;

private ProgressDialog progressDialog;

private String fullName = null;

private Bitmap DEFAULT_PROFILE_PICTURE = null;
private Bitmap PROFILE_PICTURE         = null;

private static       int                   DEFAULT_WIDTH            = 300;
private static       int                   DEFAULT_HEIGHT           = 250;
private static final int                   DEFAULT_COMPRESS_QUALITY = 100;
private static final Bitmap.CompressFormat DEFAULT_COMPRESS_FORMAT  = Bitmap.CompressFormat.PNG;
private static final boolean               fileIsPublic             = false;

public static EditProfileFragment getInstance () {
    return new EditProfileFragment ();
}

@Override
public void onCreate (Bundle savedInstanceState) {
    super.onCreate ( savedInstanceState );
    setHasOptionsMenu ( false );
}

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    editProfileView = inflater.inflate ( R.layout.fragment_edit_profile, container, false );
    setupUi ();
    setupProgressDialog ();

    return editProfileView;
}

private void setupUi () {
    tvFullName = (TextView) editProfileView.findViewById ( R.id.tvName );
    ivProfilePicture = (ImageView) editProfileView.findViewById ( R.id.ivEditProfilePicture );
    ibPassword = (ImageButton) editProfileView.findViewById ( R.id.ibPassword );
    ibName = (ImageButton) editProfileView.findViewById ( R.id.ibName );

    tvFullName.setText ( getStringPrefs ( getActivity (), SIGN_IN_USER_FULL_NAME ) );

    if ( getStringPrefs ( getActivity (), PROFILE_PICTURE_PATH ).equals ( null ) )
        setupDefaultProfilePicture ();
    else
        setupProfilePicture ();


    ibName.setOnClickListener ( this );
    ibPassword.setOnClickListener ( this );
    ivProfilePicture.setOnClickListener ( this );
}

private void setupProgressDialog () {
    progressDialog = new ProgressDialog ( this.getActivity () );
    progressDialog.setMessage ( getResources ().getString ( R.string.loading ) );
    progressDialog.setCancelable ( false );
}

private void setupDefaultProfilePicture () {
    DEFAULT_PROFILE_PICTURE = BitmapUtility.decodeSampledBitmapFromResource (
            getResources (),
            R.drawable.action_people,
            DEFAULT_WIDTH,
            DEFAULT_HEIGHT );
    ivProfilePicture.setScaleType ( FIT_CENTER );
    ivProfilePicture.setImageBitmap ( DEFAULT_PROFILE_PICTURE );
}

private void setupProfilePicture () {
    if ( PROFILE_PICTURE != null ) PROFILE_PICTURE.recycle ();

    BitmapFactory.Options options = new BitmapFactory.Options ();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    options.inInputShareable = true;
    options.inPurgeable = true;
    PROFILE_PICTURE = BitmapFactory.decodeFile ( getStringPrefs ( getActivity (), PROFILE_PICTURE_PATH ),
                                                 options );
    ivProfilePicture.setImageBitmap ( PROFILE_PICTURE );


    if ( !getBooleanPrefs ( getActivity (), IS_PROFILE_UPLOADED ) && !getStringPrefs ( getActivity (),
                                                                                       PROFILE_PICTURE_PATH )
            .equals ( null ) ) {

        File profilePicture = ExternalStorageUtils.saveBitmapToFile ( PROFILE_PICTURE, DEFAULT_COMPRESS_FORMAT,
                                                                      DEFAULT_COMPRESS_QUALITY,
                                                                      String.valueOf ( getIntPrefs ( getActivity
                                                                                                             (),
                                                                                                     SIGN_IN_USER_ID ) ) );
        QBContent.uploadFileTask ( profilePicture, fileIsPublic, new QBCallbackImpl () {
            @Override
            public void onComplete (Result result) {
                if ( result.isSuccess () ) {
                    //Get the uploaded file
                    QBFileUploadTaskResult taskResult = (QBFileUploadTaskResult) result;
                    QBFile file = taskResult.getFile ();
                    int uploadedFileId = file.getId ();

                    //Connect image to user
                    QBUser user = new QBUser ();
                    user.setId ( getIntPrefs ( getActivity (), SIGN_IN_USER_ID ) );
                    user.setFileId ( uploadedFileId );

                    QBUsers.updateUser ( user, new QBCallbackImpl () {
                        @Override
                        public void onComplete (Result result) {
                            if ( result.isSuccess () ) {
                                Toast.makeText ( getActivity (), getResources ().getString ( R.string
                                                                                                     .action_edit_successful ), Toast.LENGTH_SHORT ).show ();

                                setBooleanPrefs ( getActivity (), IS_PROFILE_UPLOADED, true );
                            } else {

                                Toast.makeText ( getActivity (), result.getErrors ().get ( 0 ).toString (),
                                                 Toast.LENGTH_SHORT ).show ();
                                Log.e ( TAG, result.getErrors ().toString () );
                            }
                        }
                    } );
                } else {
                    Toast.makeText ( getActivity (), result.getErrors ().get ( 0 ).toString (),
                                     Toast.LENGTH_SHORT ).show ();
                    Log.e ( TAG, result.getErrors ().toString () );
                }
            }
        } );
    }
}

@Override
public void onClick (View v) {
    switch ( v.getId () ) {
        case R.id.ibPassword:
            startActivity ( new Intent ( this.getActivity (), ChangePasswordActivity.class ) );
            break;

        case R.id.ibName:
            startActivity ( new Intent ( this.getActivity (), ChangeNameActivity.class ) );
            break;

        case R.id.ivEditProfilePicture:
            Intent intent = new Intent ( getActivity (), GalleryActivity.class );
            startActivity ( intent );
            break;
    }
}

@Override
public void onComplete (Result result) {

}

@Override
public void onComplete (Result result, Object query) {
    Queries queryType = (Queries) query;
    if ( result.isSuccess () ) {
        switch ( queryType ) {
            case QUERY_UPDATE_USER_INFO:
                DataHolder.getDataHolder ().getSignInUser ().setFullName ( fullName );
                progressDialog.dismiss ();
                Toast.makeText ( this.getActivity (), getResources ().getString ( R.string
                                                                                          .action_edit_successful ),

                                 Toast.LENGTH_SHORT ).show ();
                break;
        }
    } else {
        progressDialog.hide ();
        Toast.makeText ( this.getActivity (), result.getErrors ().get ( 0 ).toString (),
                         Toast.LENGTH_SHORT ).show ();
        Log.e ( TAG, result.getErrors ().toString () );
    }
}
}

0 个答案:

没有答案