代码之家  ›  专栏  ›  技术社区  ›  Cheok Yan Cheng

我是否应该将LiveData或Repository类的AsyncTask成员作为加载程序的替换

  •  2
  • Cheok Yan Cheng  · 技术社区  · 7 年前

    LiveData / ViewModel 是一个很好的替代品 Loader .

    基于 https://medium.com/google-developers/lifecycle-aware-data-loading-with-android-architecture-components-f95484159de4 ,

    AsyncTask 是的成员 实时数据 .

    public class JsonLiveData extends LiveData<List<String>> {
    
      public JsonLiveData(Context context) {
    
        loadData();
      }
    
    
      private void loadData() {
        new AsyncTask<Void,Void,List<String>>() {
    
        }.execute();
      }
    }
    

    但是,基于 presentation from Lyla Fujiwara :

    enter image description here

    我应该 异步任务 成员 Repository 上课?

    1 回复  |  直到 7 年前
        1
  •  6
  •   Knossos    7 年前

    你应该避免跑你的 AsyncTask 在里面 LiveData . 实时数据 应该只关注数据的观察。不是改变数据的行为。

    处理这种情况的最好方法是使用 ViewModel /存储库模式。

    Activity / Fragment 视图模型 , 视图模型 观察 实时数据 从存储库。在存储库中进行更改,并将其推送到 实时数据 . 这些更改将传递给 活动/片段 (通过 视图模型 ).

    在这种情况下,我会避免使用AsyncTask。AsyncTask的好处是,您可以在完成工作后在UI线程上获得结果。不过,在这种情况下,这是不必要的。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();
        }
    
    }