每当我尝试设置图像时,都会出现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 () );
}
}
}