Мое приложение зависает при отправке изображения в Firebase - PullRequest
0 голосов
/ 05 мая 2020

Я разрабатываю приложение, в котором я могу выбрать фон для recyclerview (просмотр изображения за recyclerview). Выбрав изображение из галереи, я хотел бы отправить его в firebase. Однако при загрузке изображения мое приложение зависает, и я не могу прокрутить файл recyclerview

Мой код:

    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, но проблема не исчезла. . Как решить эту ошибку?

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Установить изображения в новой цепочке следующим образом:

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();
0 голосов
/ 05 мая 2020

Возможно, потому что все методы жизненного цикла выполняются в основном потоке android. И вы используете длительные и ресурсоемкие задачи, такие как BitmapFactory.decodeFile(), Bitmap.compress(), et c в самом обратном вызове (функция onActivityResult).

Для этого вам следует использовать другие потоки, но подождите поток сам по себе является интенсивным ресурсом, и создание нового потока каждый раз, когда вы хотите отправить изображение, нецелесообразно.

Здесь вы можете использовать сопрограммы, используя 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 */}
}
...