Android Java:从HTTPS URL获取Bitmap后App无法启动,求SQLite存储方法
先解决你的App崩溃问题
你写的getBitmapFromURL函数直接在主线程发起网络请求了,Android从4.0开始禁止主线程执行网络操作,会抛出NetworkOnMainThreadException导致App崩溃。必须把网络请求放到异步线程里,比如用协程或者AsyncTask:
示例(Kotlin协程,Java可改用AsyncTask):
CoroutineScope(Dispatchers.IO).launch { val bitmap = getBitmapFromURL("https://xxx.com/image.jpg") withContext(Dispatchers.Main) { imageView.setImageBitmap(bitmap) } }
图片存储到SQLite的三种常用方法
1. 存储Bitmap的字节数组(推荐)
把Bitmap转换成字节数组,存入SQLite的BLOB类型字段,是最常用的方式。
转字节数组存库:
// Bitmap转byte[] public static byte[] bitmapToByteArray(Bitmap bitmap) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); return stream.toByteArray(); } // 存入SQLite ContentValues values = new ContentValues(); values.put("image_blob", bitmapToByteArray(bitmap)); db.insert("images_table", null, values);
从库读取转Bitmap:
// 从Cursor读取byte[]并转回Bitmap byte[] blob = cursor.getBlob(cursor.getColumnIndex("image_blob")); Bitmap bitmap = BitmapFactory.decodeByteArray(blob, 0, blob.length);
2. 存储图片本地路径(适合大图片)
不存图片本身,只存图片在本地存储的路径,SQLite里用TEXT类型字段存储路径字符串。这种方式不会让数据库体积膨胀,适合大尺寸图片。
步骤:
- 先把Bitmap保存到本地存储(比如内部存储的files目录):
public static String saveBitmapToLocal(Context context, Bitmap bitmap, String fileName) { File file = new File(context.getFilesDir(), fileName); try (FileOutputStream fos = new FileOutputStream(file)) { bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos); return file.getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); return null; } }
- 把返回的路径字符串存入SQLite:
ContentValues values = new ContentValues(); values.put("image_path", saveBitmapToLocal(context, bitmap, "my_image.jpg")); db.insert("images_table", null, values);
- 读取时通过路径加载Bitmap:
String path = cursor.getString(cursor.getColumnIndex("image_path")); Bitmap bitmap = BitmapFactory.decodeFile(path);
3. 存储Base64编码字符串(不推荐大图片)
把Bitmap转成Base64编码的字符串,存入SQLite的TEXT字段。这种方式会让数据体积比字节数组大30%左右,只适合极小的图片(比如图标)。
转Base64存库:
public static String bitmapToBase64(Bitmap bitmap) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] bytes = stream.toByteArray(); return Base64.encodeToString(bytes, Base64.DEFAULT); } // 存入SQLite ContentValues values = new ContentValues(); values.put("image_base64", bitmapToBase64(bitmap)); db.insert("images_table", null, values);
读取转Bitmap:
String base64Str = cursor.getString(cursor.getColumnIndex("image_base64")); byte[] bytes = Base64.decode(base64Str, Base64.DEFAULT); Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
内容的提问来源于stack exchange,提问作者Vinhjay
相关产品推荐
相关产品推荐

