在 SQliteDatabase 中保存图像时出现 OutOfMemoryError
Posted
技术标签:
【中文标题】在 SQliteDatabase 中保存图像时出现 OutOfMemoryError【英文标题】:OutOfMemoryError on Saving image in SQliteDatabase 【发布时间】:2017-01-14 17:16:48 【问题描述】:我在 sqlite 数据库中保存图像时遇到这个错误,图像大小只有 240KB 我已经通过一些解决方案但无法解决这个问题我的代码在数据库中保存和获取图像
public class MainActivity extends AppCompatActivity
SQLiteDatabase db;
ImageView img,img_get;
Button btn_save,btn_get;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img=(ImageView)findViewById(R.id.img_save);
img_get=(ImageView)findViewById(R.id.img_get);
btn_get=(Button)findViewById(R.id.btn_get);
btn_save=(Button)findViewById(R.id.btn_save);
db= openOrCreateDatabase("Mydb", MODE_PRIVATE, null);
db.execSQL("create table if not exists hello(name varchar, a blob)");
btn_save.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
saveimage(v);
);
btn_get.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
getimage(v);
);
public void saveimage(View view)
byte[] image=new byte[R.drawable.red];
ContentValues value=new ContentValues();
value.put("name","hatib abrar");
value.put("a",image);
db.insert("hello",null,value);
Toast.makeText(getApplicationContext(),"Saved",Toast.LENGTH_SHORT).show();
public void getimage(View view)
Cursor c=db.rawQuery("select * from hello",null);
if (c.moveToNext())
String name=c.getString(0);
byte[] image=c.getBlob(1);
Bitmap bm= BitmapFactory.decodeByteArray(image,0,image.length);
img_get.setImageBitmap(bm);
Toast.makeText(getApplicationContext(),"Error getting image",Toast.LENGTH_SHORT).show();
LogCat 显示此错误 投掷
OutOfMemoryError "未能分配 2130837597 字节 分配 16777216 个空闲字节和 151MB 直到 OOM" 09-07 09:49:59.651 21823-21823/com.example.e6530.imagesaving D/androidRuntime:关闭 VM 09-07 09:49:59.651 21823-21823/com.example.e6530.imagesaving E/AndroidRuntime:致命 例外:主要 进程:com.example.e6530.imagesaving,PID:21823 java.lang.OutOfMemoryError:分配 2130837597 字节失败 分配 16777216 个空闲字节和 151MB 直到 OOM 在 com.example.e6530.imagesaving.MainActivity.saveimage(MainActivity.java:51) 在 com.example.e6530.imagesaving.MainActivity$1.onClick(MainActivity.java:36) 在 android.view.View.performClick(View.java:4793) 在 android.view.View$PerformClick.run(View.java:19971) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:135) 在 android.app.ActivityThread.main(ActivityThread.java:5669) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
【问题讨论】:
你为什么不把你的图片保存在SD卡之类的?将图像存储在数据库中是不好的做法,您可以将路径存储在 db 中,实际图像可以存储在 sd 卡中。 生成的位图大小不取决于图像的大小。这取决于该图像的分辨率 大图???? @IntelliJAmiya 图片大小只有 220KB 检查以下答案。逻辑完美。 【参考方案1】:你的问题出在这一行:
byte[] image=new byte[R.drawable.red];
通常 R.drawable 是一些大整数。例如 10 亿,因此您尝试创建十亿字节的数组。而且内存很大。请不要将资源 id 作为数组大小传递。
更新
请参阅this 答案和this 页面来处理如何从资源中检索位图并将其转换为字节数组。可能您需要编写如下内容:
Resource r = ...;
Bitmap bitmap = Bitmap.decodeResource(r, R.drawable.red);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitmapdata = stream.toByteArray();
【讨论】:
是的,我认为问题在于我应该如何将图像分配给字节?我正在测试这个模块,因为我必须从列表中获取 youtube 视频的缩略图并将其存储到 sqlite 数据库 让我看看这个兄弟【参考方案2】:这个:
byte[] image=new byte[R.drawable.red];
不做你认为它做的事。 R.drawable.red
是一个生成的整数 ID,它可能非常高。在您的情况下,类似于 2130837597,这是您尝试分配的字节数。
您必须首先加载图像,然后获取其字节并将它们加载到数据库中。快速搜索出现this for example。
【讨论】:
让我检查一下兄弟,是的,你是对的,它向我展示了大数字,我无法得到它 感谢兄弟帮助我解决了问题:)以上是关于在 SQliteDatabase 中保存图像时出现 OutOfMemoryError的主要内容,如果未能解决你的问题,请参考以下文章
在 WPF C# 中保存图像时出现错误 System.UnauthorizedAccessException 在 mscorlib.dll 中发生