Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 实现对内存不足错误的修复_Java_Android_Bitmap_Android Imageview_Android Image - Fatal编程技术网

Java 实现对内存不足错误的修复

Java 实现对内存不足错误的修复,java,android,bitmap,android-imageview,android-image,Java,Android,Bitmap,Android Imageview,Android Image,在我的小部件中,我有一个imageView,它从用户库中收集图像,然后将该图像设置为另一个活动中的背景。它工作得很好,但是当我尝试添加一个太大的图像文件(例如来自相机的图像)或上载许多图像文件时,会出现“内存不足”错误。在查看stackoverflow一段时间后,我注意到每个人都使用了以下基本方法: public static Bitmap decodeSampleImage(File f, int width, int height) { try { System.gc(); // F

在我的小部件中,我有一个imageView,它从用户库中收集图像,然后将该图像设置为另一个活动中的背景。它工作得很好,但是当我尝试添加一个太大的图像文件(例如来自相机的图像)或上载许多图像文件时,会出现“内存不足”错误。在查看stackoverflow一段时间后,我注意到每个人都使用了以下基本方法:

public static Bitmap decodeSampleImage(File f, int width, int height) {
try {
    System.gc(); // First of all free some memory

    // 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 requiredWidth = width;
    final int requiredHeight = height;

    // Find the scale value (as a power of 2)

    int sampleScaleSize = 1;

    while (o.outWidth / sampleScaleSize / 2 >= requiredWidth && o.outHeight / sampleScaleSize / 2 >= requiredHeight)
        sampleScaleSize *= 2;

    // Decode with inSampleSize

    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = sampleScaleSize;

    return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (Exception e) {
    Log.d(TAG, e.getMessage()); // We don't want the application to just throw an exception
}

return null;
}
我还注意到人们也回收了未使用的位图。我知道这是如何工作的,但我不知道我应该把它放在我的编码

下面是我的两个类(Personalize.java,其中用于收集背景的imageView是。它有imageView和两个按钮(一个用于从库中选择图像,然后将该图像显示到imageView中,另一个用于将该图像设置为背景)

首先是Personalize.java:

package com.example.awesomefilebuilderwidget;

IMPORTS

public class Personalize extends Activity implements View.OnClickListener {
Button button;
ImageView image; //the imageview for setting the background
ImageView image2; //the imageview for setting the icon (not focusing on)
Button btnChangeImage;
Button btnChangeImageForIcon;
Button btnSetBackground;
private static final int SELECT_PICTURE = 1;
private static final int SELECT_PICTURE_2 = 2;
private String  selectedImagePath;
Bitmap background;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personalize);

image = (ImageView) findViewById(R.id.imageView1);
image2 = (ImageView) findViewById(R.id.imageView2Icon);

Button btnChangeImage = (Button) findViewById(R.id.btnChangeImage);    
btnChangeImage.setOnClickListener(this);
Button btnChangeImageForIcon = (Button) findViewById(R.id.btnChangeImageForIcon); 
btnChangeImageForIcon.setOnClickListener(this);
Button btnSetBackground = (Button) findViewById(R.id.btnSetBackground);
btnSetBackground.setOnClickListener(this);

}

@Override 
public void onClick(View v) { 
switch (v.getId()) { 
case R.id.btnChangeImage: 
launchImageChooser(); 
break; 
case R.id.btnChangeImageForIcon: 
launchImageChooser(); 
break; 
case R.id.btnSetBackground: 
setBackgroundImageInDragAndDrop(); 
break; 
} 
} 

private void setBackgroundImageInDragAndDrop() {
Log.d("Personalize", "setBackgroundImageInDragAndDrop() called");
Intent i = getIntent();
//Convert bitmap to byte array to send back to activity
// See: http://stackoverflow.com/questions/11010386/send-bitmap-using-intent-android
ByteArrayOutputStream stream = new ByteArrayOutputStream();
background.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[]byteArray = stream.toByteArray();

i.putExtra("myBackgroundBitmap", byteArray);
setResult(RESULT_OK, i);
finish();
}

private void launchImageChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, SELECT_PICTURE);
}

public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor
        .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String imagePath = cursor.getString(column_index);
if(cursor != null) {
cursor.close();
}
return imagePath;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{

if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE)
{
    Uri selectedImageUri = data.getData();
    selectedImagePath = getPath(selectedImageUri);
    background = getAndDecodeImage(selectedImagePath);
    if(background != null){
        image.setImageBitmap(background); 
    }           
} else if (requestCode == SELECT_PICTURE_2)
{
    Uri selectedImageUri = data.getData();
    selectedImagePath = getPath(selectedImageUri);
    Bitmap b2 = getAndDecodeImage(selectedImagePath);
    if(b2 != null){
        image2.setImageBitmap(b2);
    }
}    
}
}

private Bitmap getAndDecodeImage(String  selectedImagePath){
try {
    Log.d("Personalize", "selectedImagePath: " + selectedImagePath);
    FileInputStream fileis=new FileInputStream(selectedImagePath);
    BufferedInputStream bufferedstream=new BufferedInputStream(fileis);
    byte[] bMapArray= new byte[bufferedstream.available()];
    bufferedstream.read(bMapArray);
    Bitmap bMap = BitmapFactory.decodeByteArray(bMapArray, 0, bMapArray.length);

    if (fileis != null) 
    {
        fileis.close();
    }
    if (bufferedstream != null) 
    {
        bufferedstream.close();
    }
    return bMap;
} catch (FileNotFoundException e) {                 
    e.printStackTrace();
} catch (IOException e) {                   
    e.printStackTrace();
}   
return null;
}


public boolean saveImageToInternalStorage(Bitmap image) {
   try {
      FileOutputStream fos = this.openFileOutput("desiredFilename.png",     Context.MODE_PRIVATE);
      image.compress(Bitmap.CompressFormat.PNG, 100, fos);
      fos.close();   
      return true;
   } catch (Exception e) {
   return false;
   }
}

}
下面是我的拖放App.java(重要部分的片段——收集位图并设置为背景):

package com.example.awesomefilebuilderwidget;
进口
公共类拖放应用程序扩展活动{
私有静态最终整数集_BACKGROUND=10;
私有ListView MListapInfo;
//搜索编辑文本
编辑文本输入搜索;
公共AppInfoAdapter;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//设置主屏幕的布局
setContentView(R.layout.拖放应用程序);
//导入按钮
按钮btnLinkToFeedback=(按钮)findViewById(R.id.btnLinkToFeedback);
按钮BTNLinkTopPersonalize=(按钮)findViewById(R.id.BTNLinkTopPersonalize);
//链接到个性化屏幕
btnLinkToPersonalize.setOnClickListener(新视图.OnClickListener(){
公共void onClick(视图){
意图i=新意图(getApplicationContext(),
个性化;
startActivityForResult(i,设置背景);
}
});
}
公共位图获取缩略图(字符串文件名){
位图缩略图=空;
试试{
File filePath=this.getFileStreamPath(文件名);
FileInputStream fi=新的FileInputStream(filePath);
缩略图=BitmapFactory.decodeStream(fi);
}捕获(例外情况除外){
e(“内部存储上的getThumbnail()”,例如getMessage());
} 
返回缩略图;
} 
@凌驾
ActivityResult上受保护的void(int请求代码、int结果代码、意图数据){
super.onActivityResult(请求代码、结果代码、数据);
Log.i(“拖放应用程序”,“请求代码:+requestCode+”,结果代码:+resultCode”);
如果(requestCode==SET\u BACKGROUND&&resultCode==RESULT\u OK){
字节[]byteArray=data.getByteArrayExtra(“myBackgroundBitmap”);
位图myBackground=BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
setBackgroundImage(myBackground);
} 
} 
@SuppressLint(“新API”)
私有void setBackgroundImage(位图){
RelativeLayout yourBackgroundView=(RelativeLayout)findViewById(R.id.rl\u拖放应用程序);
Drawable d=新的BitmapDrawable(getResources(),位图);
if(Build.VERSION.SDK\u INT

那么,在哪里可以实现这种编码,在哪里还可以去除内存中其他未使用的位图?(回收它们?)

这是Android位图课程吗?请剪掉你的代码,只留下相关部分。谢谢你,没读。@alex我把它剪了一段little@piotrpo谢谢你的链接,但我也想知道我在哪里可以实现回收到我的编码
package com.example.awesomefilebuilderwidget;

IMPORTS

public class Drag_and_Drop_App extends Activity {
private static final int SET_BACKGROUND = 10;

private ListView mListAppInfo;
// Search EditText
EditText inputSearch;
public AppInfoAdapter adapter;

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

    // set layout for the main screen
    setContentView(R.layout.drag_and_drop_app);

    // import buttons
    Button btnLinkToFeedback = (Button) findViewById(R.id.btnLinkToFeedback);
    Button btnLinkToPersonalize = (Button) findViewById(R.id.btnLinkToPersonalize);


    // Link to Personalize Screen
    btnLinkToPersonalize.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            Intent i = new Intent(getApplicationContext(),
                    Personalize.class);
            startActivityForResult(i, SET_BACKGROUND);

        }
    });

}
public Bitmap getThumbnail(String filename) { 
     Bitmap thumbnail = null; 
     try { 
     File filePath = this.getFileStreamPath(filename); 
     FileInputStream fi = new FileInputStream(filePath); 
     thumbnail = BitmapFactory.decodeStream(fi); 
     } catch (Exception ex) { 
     Log.e("getThumbnail() on internal storage", ex.getMessage()); 
     } 
     return thumbnail; 
     } 

     @Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     Log.i("Drag_and_Drop_App", "requestCode: " + requestCode + ", resultCode: " + resultCode); 
     if(requestCode == SET_BACKGROUND && resultCode == RESULT_OK){ 
     byte[] byteArray = data.getByteArrayExtra("myBackgroundBitmap"); 
     Bitmap myBackground = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length); 
     setBackgroundImage(myBackground); 
     } 
     } 

     @SuppressLint("NewApi") 
     private void setBackgroundImage(Bitmap bitmap) { 
     RelativeLayout yourBackgroundView = (RelativeLayout) findViewById(R.id.rl_drag_and_drop_app); 

     Drawable d = new BitmapDrawable(getResources(), bitmap); 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
     yourBackgroundView.setBackgroundDrawable(d); 
     } else { 
     yourBackgroundView.setBackground(d); 
     } 
     } 

     }