هل يجب أن أجعل AsyncTask عضوًا في فئة LiveData أو Repository - كبديل لـ Loader

0

LiveData / ViewModel هو بديل جيد للمعقدات Loader .

بناءً على https://medium.com/google-developers/lifecycle-aware-data-loading-with-android-arch architecture-components-f95484159de4 ،

AsyncTask عضو في LiveData .

public class JsonLiveData extends LiveData<List<String>> {

  public JsonLiveData(Context context) {

    loadData();
  }


  private void loadData() {
    new AsyncTask<Void,Void,List<String>>() {

    }.execute();
  }
}

ومع ذلك ، استنادًا إلى العرض التقديمي من Lyla Fujiwara :

Imagen 20

هل يجب أن أفعل AsyncTask عضو في Repository صف دراسي؟

1 إجابة

1
افضل جواب

يجب عليك تجنب تشغيل الخاص بك AsyncTask في LiveData . LiveData يجب أن تهتم فقط بمراقبة البيانات. ليس فعل تغيير البيانات.

أفضل طريقة للتعامل مع هذا الموقف هو استخدام ViewModel / نمط المستودع.

Activity / Fragment يلاحظ LiveData من ViewModel ، ViewModel يلاحظ LiveData من المستودع. يتم إجراء التغييرات في المستودع ، والتي يتم دفعها إلى LiveData . يتم تسليم هذه التغييرات إلى Activity / Fragment (عبر ال ViewModel ).

سوف أتجنب استخدام AsyncTask في هذه الحالة. مكافأة AsyncTask هي أنه يمكنك الحصول على نتائج في مؤشر ترابط واجهة المستخدم بعد القيام بالعمل. ولكن في هذه الحالة ، هذا ليس ضروريًا. سيقوم LiveData بذلك نيابة عنك.

فيما يلي مثال (لم يتم اختباره):

نشاط

public class MyActivity extends AppCompatActivity {

    private MyViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set up your view model
        viewModel = ViewModelProviders.of(this).get(MyViewModel.class);

        // Observe the view model
        viewModel.getMyLiveData().observe(this, s -> {
            // You work with the data provided through the view model here.
            // You should only really be delivering UI updates at this point. Updating
            // a RecyclerView for example.
            Log.v("LIVEDATA", "The livedata changed: "+s);
        });

        // This will start the off-the-UI-thread work that we want to perform.
        MyRepository.getInstance().doSomeStuff();
    }
}

نموذج العرض

public class MyViewModel extends AndroidViewModel {

    @NonNull
    private MyRepository repo = MyRepository.getInstance();

    @NonNull
    private LiveData<String> myLiveData;

    public MyViewModel(@NonNull Application application) {
        super(application);
        // The local live data needs to reference the repository live data
        myLiveData = repo.getMyLiveData();
    }

    @NonNull
    public LiveData<String> getMyLiveData() {
        return myLiveData;
    }
}

مخزن

public class MyRepository {

    private static MyRepository instance;

    // Note the use of MutableLiveData, this allows changes to be made
    @NonNull
    private MutableLiveData<String> myLiveData = new MutableLiveData<>();

    public static MyRepository getInstance() {
        if(instance == null) {
            synchronized (MyRepository.class) {
                if(instance == null) {
                    instance = new MyRepository();
                }
            }
        }
        return instance;
    }

    // The getter upcasts to LiveData, this ensures that only the repository can cause a change
    @NonNull
    public LiveData<String> getMyLiveData() {
        return myLiveData;
    }

    // This method runs some work for 3 seconds. It then posts a status update to the live data.
    // This would effectively be the "doInBackground" method from AsyncTask.
    public void doSomeStuff() {
        new Thread(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ignored) {
            }

            myLiveData.postValue("Updated time: "+System.currentTimeMillis());
        }).start();
    }

}
:مؤلف
فوق
قائمة طعام