AsyncTask и фрагменты

Последнее обновление: 26.02.2017

При использовании AsyncTask следует учитывать следующий момент. Более оптимальным способом является работа AsyncTask с фрагментом, нежели непосредственно с activity. Например, если мы возьмем проект из прошлой темы, запустим приложение и изменим ориентацию мобильного устройства, то произойдет пересоздание activity. В случае изменения орентации устройства поток AsyncTask будет продолжать обращаться к старой activity, вместо новой. Поэтому в этом случае лучше использовать фрагменты.

Итак, возьмем проект из прошлой темы и добавим в него новый фрагмент, который назовем ProgressFragment.

ProgressBar во фрагменте в Android

Определим для него новый файл разметки интерфейса fragment_progress.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_progress"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="16dp"
    android:orientation="vertical">
    <Button
        android:id="@+id/progressBtn"
        android:text="Запуск"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/statusView"
        android:text="Статус"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <ProgressBar
        android:id="@+id/indicator"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="0" />
</LinearLayout>

Сам класс фрагмента ProgressFragment изменим следующим образом:

package com.example.eugene.asyncapp;

import android.widget.Button;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Fragment;
import android.os.SystemClock;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.view.View.OnClickListener;

public class ProgressFragment extends Fragment {

    int[] integers=null;
    ProgressBar indicatorBar;
    TextView statusView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_progress, container, false);
        integers = new int[100];
        for(int i=0;i<100;i++) {
            integers[i] = i + 1;
        }
        indicatorBar = (ProgressBar) view.findViewById(R.id.indicator);
        statusView = (TextView) view.findViewById(R.id.statusView);
        Button btnFetch = (Button)view.findViewById(R.id.progressBtn);
        btnFetch.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                new ProgressTask().execute();
            }
        });
        return view;
    }

    class ProgressTask extends AsyncTask<Void, Integer, Void> {
        @Override
        protected Void doInBackground(Void... unused) {
            for (int i = 0; i<integers.length;i++) {

                publishProgress(i);
                SystemClock.sleep(400);
            }
            return null;
        }
        @Override
        protected void onProgressUpdate(Integer... items) {
            indicatorBar.setProgress(items[0]+1);
            statusView.setText("Статус: " + String.valueOf(items[0]+1));
        }
        @Override
        protected void onPostExecute(Void unused) {
            Toast.makeText(getActivity(), "Задача завершена", Toast.LENGTH_SHORT)
                    .show();
        }
    }
}

Здесь определены все те действия, которые были рассмотрены в прошлой теме и которые ранее находились в классе MainActivity. Особо стоит отметить вызов setRetainInstance(true) в методе onCreate(), который позволяет сохранять состояние фрагмента вне зависимости от изменения ориентации.

Теперь свяжем фрагмент с activity. Для этого определим в файле activity_main.xml следующий код:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/progressFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.eugene.asyncapp.ProgressFragment"/>
</LinearLayout>

А сам класс MainActivity сократим:

package com.example.eugene.asyncapp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Теперь если мы запустим приложение, то вне зависимости от смены ориентации моильного устройства фоновая задача будет продолжать свою работу:

AsyncTask и альбомный режим в Android AsyncTask и фрагменты в Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850