Установка обоев образа хранилища Firebase внутри AsyncTask - PullRequest
0 голосов
/ 25 августа 2018

У меня небольшая проблема с настройкой обоев устройства, когда у меня есть код хранилища Firebase и AsyncTask.

Во-первых , правильно ли вообще содержать этот код в AsyncTask?

Во-вторых , обои успешно загружены и установлены,но по какой-то причине AsyncTask не ждет, пока это не завершится, прежде чем закрыть ProgressDialog и показать тост, сообщающий мне, что обои были установлены успешно.Что может быть не так?

В-третьих , даже несмотря на то, что код находится в doInBackground () AsyncTask, не похоже, что он на самом деле работает отдельно от основного потока, потому чтомоё приложение полностью зависает во время выполнения кода (и в конечном итоге размораживается после его завершения).

Есть ли у меня понимание?Я учусь на ходу и очень запутался.

Вот код для справки ниже.

private class wallpaperTaskHome extends AsyncTask<Void, Void, String> {

    private ProgressDialog dialog = new ProgressDialog(PhotoDetailsActivity.this);

onPreExecute ()

    @Override
    protected void onPreExecute() {

        // Progress dialog to show user that the app is working...
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setMessage(getString(R.string.wallpaper_please_wait));
        dialog.show();
    }

doInBackground ()

    @Override
    protected String doInBackground(Void... params) {

        // Get Intent data from intent passed from Photos.java class.
        Intent intent = getIntent();
        int position = intent.getExtras().getInt("Image int");

        final StorageReference fullSizeImagesStoragePath = mStorageRef.child("images_full_size/" + position + ".jpg");
        fullSizeImagesStoragePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {

                // Retrieve a WallpaperManager
                final WallpaperManager wallpaperManager = WallpaperManager
                        .getInstance(PhotoDetailsActivity.this);

                Glide
                        .with(PhotoDetailsActivity.this)
                        .asBitmap()
                        .load(uri)
                        .into(new SimpleTarget<Bitmap>() {
                            @Override
                            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                                try {
                                    wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_SYSTEM);
                                } catch (IOException e) {
                                }
                            }
                        });
            }
        });
        return null;
    }

onPostExecute ()

    protected void onPostExecute(String result) {

        if (dialog.isShowing()) {
            dialog.dismiss();
        }

        // Show a Toast message on successful wallpaper change
        showToastWallpaperApplied();
    }
}

Спасибо за любую помощь, которую вы можете оказать мне!

РЕДАКТИРОВАТЬ: Я изменил свой метод doInBackground(), чтобы он выглядел как показано ниже, что по сути делает то же самое, но теперь, по крайней мере, он пытается асинхронно вызвать весь код, потому что он дает мне ошибку: java.lang.IllegalArgumentException: You must call this method on the main thread

final WallpaperManager wallpaperManager = WallpaperManager
            .getInstance(this);

    Intent intent = getIntent();
    int position = intent.getExtras().getInt("Image int");

    final StorageReference fullSizeImagesStoragePath = mStorageRef.child("images_full_size/" + position + ".jpg");
    GlideApp.with(PhotoDetailsActivity.this)
            .asBitmap()
            .load(fullSizeImagesStoragePath)
            .into(new SimpleTarget<Bitmap>() {
                @Override
                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                    try {
                        wallpaperManager.setBitmap(resource, null, true, WallpaperManager.FLAG_SYSTEM);
                    } catch (IOException e) {
                    }
                }
            });

Указывает на .into(new SimpleTarget<Bitmap>() как метод, который хочет запускаться только в основном потоке.Помощь

1 Ответ

0 голосов
/ 25 августа 2018

Полагаю, что внутреннее скольжение вызовет onSuccess в потоке пользовательского интерфейса, затем ваша задача установки обоев будет по-прежнему выполняться в потоке пользовательского интерфейса, даже если вы включите его в асинхронную задачу.Я предлагаю вам проверить реализацию связанных методов глиссады.

Редактировать: Если это так, то вам придется свернуть заданную задачу обоев в асинхронную задачу, что будет очень утомительно для реализации,Мое предложение состоит в том, чтобы использовать Rxjava для объединения этих задач, что, по моему мнению, будет лучшим подходом.

Редактировать: взглянул на документы, https://github.com/bumptech/glide/wiki/Loading-and-Caching-on-Background-Threads там сказано

Если вы действительно хотите взаимодействовать с декодированным изображением в фоновом потоке, вместо использованияdownloadOnly вы можете использовать версию into (), которая возвращает FutureTarget

Так что вы можете попытаться загрузить изображение синхронно в фоновом потоке (с помощью асинхронной задачи), чтобы избежать блокировки пользовательского интерфейса, но обязательно вызовитеэто с контекстом приложения, чтобы избежать утечек памяти.

Bitmap myBitmap = Glide.with(applicationContext)
    .load(yourUrl)
    .asBitmap()
    .centerCrop()
    .into(500, 500)
    .get()
...