我正在开发一个应用程序,在这个应用程序中,我可以为一个回收视图选择一个背景(一个回收视图后面的图像视图)。从图库中选择图片后,我想把它发送到firebase。然而,当上传图片时,我的应用程序被冻结,我无法滚动回收视图。
我的代码。
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
/* code */
else if (requestCode == BG_GALLERY_REQUEST_CODE) {
val selectedPicture = data?.data
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = applicationContext.contentResolver.query(selectedPicture!!, filePathColumn, null, null, null)
cursor!!.moveToFirst()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
val bitmap = BitmapFactory.decodeFile(picturePath)
cursor.close()
backgroundUtils.salvarBackground(bitmap)
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap?.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream)
val dadosImagem = byteArrayOutputStream.toByteArray()
val storageReference = ConfiguracaoFirebase.getFirebaseStorage()
val imagemRef = storageReference
.child("imagens")
.child("backgrounds")
.child(UsuarioFirebase.getId() +
FileUtils.IMAGE_EXTENSION)
val uploadTask = imagemRef.putBytes(dadosImagem)
uploadTask.addOnSuccessListener {
imagemRef.downloadUrl.addOnSuccessListener { uri ->
ConfiguracaoFirebase.backgroundRef()
.child(UsuarioFirebase.getId())
.setValue(uri)
Log.e("upload", uri.toString())
}
}.addOnFailureListener { exception ->
Log.e("upload", exception.message)
}
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Log.i("REQUEST", "canceled")
} else {
toast(getString(R.string.oops_ocorreu_algum_erro))
}
}
我也尝试在AsyncTask中执行上传代码,但问题依然存在。如何解决这个错误?
先谢谢你
在新的线程中设置图片这样的。
Thread timer = new Thread()
{
public void run()
{
try
{
sleep(2000);
runOnUiThread(new Runnable() {
public void run() {
splash.setImageResource(R.drawable.billboard_image);
}
});
sleep(2000);
runOnUiThread(new Runnable() {
public void run() {
splash.setImageResource(R.drawable.square);
}
});
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
System.out.println("finally");
}
}
};
timer.start();
可能是因为所有的生命周期方法都在android的主线程上运行。而你使用的是长期运行的资源密集型任务,如 BitmapFactory.decodeFile()
, Bitmap.compress()
等在回调(函数onActivityResult)本身。
你应该使用其他线程来做这件事,但是等待线程本身就是一个密集型的资源,而且每次你要发送图片的时候创建一个新的线程是不利的。
你可以在这里使用coroutine,使用ViewModel。
// Dispatchers.Default is used for resource intensive tasks and is backed by a CommonPool of threads, that can be reused with another coroutine
// NonCancellable overrides the job on ViewModelScope to become non-cancellable
viewModelOwner.viewModelScope.launch(Dispatchers.Default + NonCancellable) {
// Your intensive task right here
// if you want to do some operation like updating ui just use runOnUiThread{/* code */}
}