从片段中的 MainActivity 中的 JSON API 获取数据
Get data from JSON API in my MainActivity from a fragment
我的项目使用 MVP 架构和 RxJava 从远程获取数据 JSON Api.
我有一个 MainActivity,它有 2 个角色。第一个是作为片段容器,第二个是从 JSON api 获取数据并将其传输到我的片段(我现在只有一个片段,但稍后会有另一个片段使用相同的数据)。
现在,我正在我的 MainActivity 中获取数据。我正在尝试通过调用 MainActivity 中的方法(使用解耦接口)从片段中获取数据。
问题是我的片段中的数据总是空的,我想这是因为我的 activity 使我的片段膨胀得如此之快,以至于当我的片段调用我的 activity 方法来获取数据时,这个数据仍然是空的,因为请求还没有收到答案,这个请求是使用 RxJava 异步调用的。
所以我想等待加载数据以打开我的片段,或者打开我的片段并等待数据加载到 activity 中,然后再获取它(向用户显示视觉进度)。问题不在于如何做,而在于何时何地。谢谢您的帮助。
我移动了我的 loadData() 方法和事务以在生命周期的不同位置多次打开我的片段,但没有任何效果。现在一切都在 MainActivity.onStart() :
@Override
protected void onStart() {
super.onStart();
presenter.setView(this);
// Load data from JSON API
presenter.loadData(city, authToken);
// Load fragments
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.ll_container);
if (fragment == null) {
fragment = new PollutionLevelsFragment();
fm.beginTransaction()
.add(R.id.ll_container, fragment)
.commit();
}
}
在我的演示者的 loadData() 方法中检索数据:
public class MainPresenter implements MainActivityMVP.Presenter {
final static String TAG = MainPresenter.class.getCanonicalName();
private MainActivityMVP.View view;
private MainActivityMVP.Model model;
private Subscription subscription = null;
public MainPresenter(MainActivityMVP.Model model) { this.model = model; }
@Override
public void loadData(String city, String authToken) {
subscription = model.result(city, authToken)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Aqicn>() {
@Override
public void onCompleted() {
Log.i(TAG,"completed");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(Aqicn aqicn) {
Data data = aqicn.getData();
Iaqi iaqi = data.getIaqi();
ViewModel viewModel = new ViewModel(data.getAqi(),
data.getDominentpol(),
iaqi.getCo().getV(),
iaqi.getH().getV(),
iaqi.getNo2().getV(),
iaqi.getO3().getV(),
iaqi.getP().getV(),
iaqi.getPm10().getV(),
iaqi.getPm25().getV(),
iaqi.getR().getV(),
iaqi.getSo2().getV(),
iaqi.getT().getV(),
iaqi.getW().getV());
Log.d(TAG,data.getCity().getName());
if (view != null) {
view.updateData(viewModel);
}
}
});
}
@Override
public void rxUnsubscribe() {
if (subscription != null) {
if (!subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
@Override
public void setView(MainActivityMVP.View view) {
this.view = view;
}
}
当收到对请求的响应时,演示者调用 MainActivity 中的 updateData() 方法(参见上面我的演示者代码)。这是我初始化 ArrayList pollutionLevels 的地方,它应该包含我试图从片段中获取的数据:
@Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
pollutionLevels = viewModel.getAllPolluants();
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
}
}
这是我的 MainActivity 中从我的片段中调用以获取数据的方法:
@Override
public ArrayList<PollutionLevel> getPollutionLevels() {
return pollutionLevels;
}
在我的片段中,我尝试在 onAttach() 中获取数据,但它始终为空:
public interface PollutionLevelsListener{
ArrayList<PollutionLevel> getPollutionLevels();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
pollutionLevelsListener = (PollutionLevelsListener) context;
ArrayList<PollutionLevel> levels = pollutionLevelsListener.getPollutionLevels();
for(PollutionLevel l:levels) {
Log.d(TAG,l.getName());
}
} catch (ClassCastException castException){
castException.printStackTrace();
}
}
编辑:添加 ViewModel.getAllPolluants() 方法
这是我的 ViewModel 中的方法 returns ArrayList :
public ArrayList<PollutionLevel> getAllPolluants() {
ArrayList<PollutionLevel> allLevels = new ArrayList();
allLevels.add(new PollutionLevel("Co",Double.toString(co)));
allLevels.add(new PollutionLevel("H",Double.toString(h)));
allLevels.add(new PollutionLevel("No2",Double.toString(no2)));
allLevels.add(new PollutionLevel("o3",Double.toString(o3)));
allLevels.add(new PollutionLevel("p",Double.toString(p)));
allLevels.add(new PollutionLevel("o3",Double.toString(o3)));
allLevels.add(new PollutionLevel("pm10",Integer.toString(pm10)));
allLevels.add(new PollutionLevel("pm25",Integer.toString(pm25)));
allLevels.add(new PollutionLevel("r",Double.toString(r)));
allLevels.add(new PollutionLevel("so2",Double.toString(so2)));
allLevels.add(new PollutionLevel("t",Double.toString(t)));
allLevels.add(new PollutionLevel("w",Double.toString(w)));
return allLevels;
}
编辑:添加新修改的 MainActivity class 和 PollutionLevelListener 接口,尝试应用@cricket_007 answer
public class MainActivity extends AppCompatActivity implements MainActivityMVP.View, PollutionLevelsListener {
final static String TAG = MainActivity.class.getCanonicalName();
@BindString(R.string.city)
String city;
@BindString(R.string.aqicn_token)
String authToken;
@Inject
MainActivityMVP.Presenter presenter;
ArrayList<PollutionLevel> pollutionLevels;
PollutionLevelsListener pollutionListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
((App) getApplication()).getComponent().injectPollutionLevels(this);
}
@Override
public void updateData(ViewModel viewModel) {
pollutionLevels = viewModel.getAllPolluants();
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
}
//===== NullPointerException
pollutionListener.onPollutionLevelsLoaded(pollutionLevels);
}
@Override
protected void onStart() {
super.onStart();
presenter.setView(this);
presenter.loadData(city, authToken);
}
@Override
public void onPollutionLevelsLoaded(List<PollutionLevel> levels) {
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
};
// Load fragments
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.ll_container);
if (fragment == null) {
fragment = new PollutionLevelsFragment();
fm.beginTransaction()
.add(R.id.ll_container, fragment)
.commit();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.rxUnsubscribe();
}
}
界面
public interface PollutionLevelsListener {
void onPollutionLevelsLoaded(List<PollutionLevel> levels);
}
####################编辑################### #####
在对采用什么解决方案有很多疑问之后,我遵循了@yosriz 的回答和建议。这是我结束的代码。请注意,我仍然需要实现缓存管理功能,因为现在 JSON 对两个片段都进行了请求。
因此,我的两个片段都使用了一个公共存储库。 MainActivity 变成了一个片段容器,它不获取任何数据。它甚至没有 MVP 结构,因为我认为它现在没用了。
我的两个片段(所以我的两个特征)从 PollutionLevelRepository
获取数据:
public interface Repository {
Observable<Aqicn> getPollutionLevelsFromNetwork(String city, String authToken);
Observable<Aqicn> getPollutionLevels(String city, String authToken);
}
public class PollutionLevelsRepository implements Repository {
private PollutionApiService pollutionApiService;
private static Observable<Aqicn> pollutionData = null;
public PollutionLevelsRepository(PollutionApiService pollutionApiService) {
this.pollutionApiService = pollutionApiService;
}
@Override
public Observable<Aqicn> getPollutionLevelsFromNetwork(String city, String authToken) {
pollutionData = pollutionApiService.getPollutionObservable(city, authToken);
return pollutionData;
}
@Override
public Observable<Aqicn> getPollutionLevels(String city, String authToken) {
return getPollutionLevelsFromNetwork(city, authToken);
}
}
我的第一个片段的模型(甜甜圈特征):
public class DonutModel implements DonutFragmentMVP.Model {
final static String TAG = DonutModel.class.getSimpleName();
private Repository repository;
public DonutModel(Repository repository) {
this.repository = repository;
}
@Override
public Observable<Aqicn> getPollutionLevels(String city, String authToken) {
Observable<Aqicn> aqicnObservable = repository.getPollutionLevels(city, authToken);
return aqicnObservable;
}
}
我的第二个片段的模型(污染等级特征):
public class PollutionLevelsModel implements PollutionLevelsFragmentMVP.Model {
private Repository repository;
public PollutionLevelsModel(Repository repository) {
this.repository = repository;
}
@Override
public Observable<Aqicn> result(String city, String authToken) {
Observable<Aqicn> aqicnObservable = repository.getPollutionLevels(city, authToken);
return aqicnObservable;
}
}
I'm trying to get the data from my fragment by calling a method in my MainActivity
您的界面似乎只返回字段,这很可能是在请求完成之前。你似乎明白了...
didn't receive the answer yet and this request is called asynchronously using RxJava
我不建议您等待,而是
open my fragment and wait the data being loaded in the activity before get it (showing a visual progress to the user).
无论您想如何实现,您都可以尝试 new ProgressDialog()
并显示/隐藏它。
您的问题是 onAttach
立即被调用并且请求仍在无限期地进行。
您需要 "subscribe" 从片段中获取该数据。
A "listener" 通常不是为了实现 "getter" 而编写的,所以让我们重写一下
public interface PollutionLevelsListener {
void onPollutionLevelsLoaded(List<PollutionLevel> levels);
}
然后,您可以使用它来启动您的 Fragment 而不是在 Activity 启动时立即启动
// The Activity
class ... implements PollutionLevelsListener {
@Override
public void onPollutionLevelsLoaded(List<PollutionLevel> levels) {
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
};
// Moved this section here
// Load fragments
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = fm.findFragmentById(R.id.ll_container);
if (fragment == null) {
fragment = new PollutionLevelsFragment();
// If your object is Parcelable
/*
* Bundle args = new Bundle();
* args.putParcelableArrayList(levels);
* fragment.setArguments(args);
*/
ft.add(R.id.ll_container, fragment).commit();
}
}
现在你有了那个方法,
the presenter call the updateData() method in MainActivity
好吧,这是列表的来源,所以只需将它传递给然后加载片段的新方法
@Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
if (pollutionLevels == null) {
pollutionsLevels = new ArrayList<>();
}
pollutionLevels.clear();
pollutionLevels.addAll(viewModel.getAllPolluants());
this.onPollutionLevelsLoaded(pollutionsLevels);
}
好吧,你可能有时间问题,model.result
是异步 IO 操作,它将在完成时以异步方式更新 activity 上的数据,而你获取数据的片段调用是一旦片段附加了 activity(当你调用片段 commit()
而不是 commitNow()
时它仍然是异步的)但是如果你将它与 [=10= 的可能网络调用进行比较] 它可能总是更快。
实际上我认为你的方法是错误的,当你在 Rx 中使用反应式方式时,你应该推送数据,最后,你将它从 Activity
的片段端拉出来,虽然您不知道此数据是否已经可用。
从演示者加载的数据应立即更新片段,这意味着您的 Activity.updateData()
将更新片段,或者我认为更正确的方法是演示者将绑定到片段本身,因为这是实际的View
正在更新,因此演示者的 view.UpdateData()
将直接通知片段。
您是否尝试在片段中创建一个方法,一旦调用 updateData(ViewModel viewModel) 就可以点击它?
例如(尝试在您的片段中添加此方法):
public class YourFragmentName extends Fragment {
public YourFragmentName(StepsHandler stepsHandler){
this.stepsHandler = stepsHandler;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_supplier_registrtion_first, container, false);
return rootView;
}
public void dataLoaded() {
// Do what you need after data finish loading..
}
}
来自你的Activity:
public class MainActivity extends Activity implements StepsHandler {
YourFragmentName fragmentName;
//onCreate ()
fragmentName = new YourFragmentName(this);
@Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
pollutionLevels = viewModel.getAllPolluants();
fragmentName.dataLoaded();
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
}
}
}
我的项目使用 MVP 架构和 RxJava 从远程获取数据 JSON Api.
我有一个 MainActivity,它有 2 个角色。第一个是作为片段容器,第二个是从 JSON api 获取数据并将其传输到我的片段(我现在只有一个片段,但稍后会有另一个片段使用相同的数据)。
现在,我正在我的 MainActivity 中获取数据。我正在尝试通过调用 MainActivity 中的方法(使用解耦接口)从片段中获取数据。
问题是我的片段中的数据总是空的,我想这是因为我的 activity 使我的片段膨胀得如此之快,以至于当我的片段调用我的 activity 方法来获取数据时,这个数据仍然是空的,因为请求还没有收到答案,这个请求是使用 RxJava 异步调用的。
所以我想等待加载数据以打开我的片段,或者打开我的片段并等待数据加载到 activity 中,然后再获取它(向用户显示视觉进度)。问题不在于如何做,而在于何时何地。谢谢您的帮助。
我移动了我的 loadData() 方法和事务以在生命周期的不同位置多次打开我的片段,但没有任何效果。现在一切都在 MainActivity.onStart() :
@Override
protected void onStart() {
super.onStart();
presenter.setView(this);
// Load data from JSON API
presenter.loadData(city, authToken);
// Load fragments
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.ll_container);
if (fragment == null) {
fragment = new PollutionLevelsFragment();
fm.beginTransaction()
.add(R.id.ll_container, fragment)
.commit();
}
}
在我的演示者的 loadData() 方法中检索数据:
public class MainPresenter implements MainActivityMVP.Presenter {
final static String TAG = MainPresenter.class.getCanonicalName();
private MainActivityMVP.View view;
private MainActivityMVP.Model model;
private Subscription subscription = null;
public MainPresenter(MainActivityMVP.Model model) { this.model = model; }
@Override
public void loadData(String city, String authToken) {
subscription = model.result(city, authToken)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Aqicn>() {
@Override
public void onCompleted() {
Log.i(TAG,"completed");
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(Aqicn aqicn) {
Data data = aqicn.getData();
Iaqi iaqi = data.getIaqi();
ViewModel viewModel = new ViewModel(data.getAqi(),
data.getDominentpol(),
iaqi.getCo().getV(),
iaqi.getH().getV(),
iaqi.getNo2().getV(),
iaqi.getO3().getV(),
iaqi.getP().getV(),
iaqi.getPm10().getV(),
iaqi.getPm25().getV(),
iaqi.getR().getV(),
iaqi.getSo2().getV(),
iaqi.getT().getV(),
iaqi.getW().getV());
Log.d(TAG,data.getCity().getName());
if (view != null) {
view.updateData(viewModel);
}
}
});
}
@Override
public void rxUnsubscribe() {
if (subscription != null) {
if (!subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
@Override
public void setView(MainActivityMVP.View view) {
this.view = view;
}
}
当收到对请求的响应时,演示者调用 MainActivity 中的 updateData() 方法(参见上面我的演示者代码)。这是我初始化 ArrayList pollutionLevels 的地方,它应该包含我试图从片段中获取的数据:
@Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
pollutionLevels = viewModel.getAllPolluants();
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
}
}
这是我的 MainActivity 中从我的片段中调用以获取数据的方法:
@Override
public ArrayList<PollutionLevel> getPollutionLevels() {
return pollutionLevels;
}
在我的片段中,我尝试在 onAttach() 中获取数据,但它始终为空:
public interface PollutionLevelsListener{
ArrayList<PollutionLevel> getPollutionLevels();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
pollutionLevelsListener = (PollutionLevelsListener) context;
ArrayList<PollutionLevel> levels = pollutionLevelsListener.getPollutionLevels();
for(PollutionLevel l:levels) {
Log.d(TAG,l.getName());
}
} catch (ClassCastException castException){
castException.printStackTrace();
}
}
编辑:添加 ViewModel.getAllPolluants() 方法
这是我的 ViewModel 中的方法 returns ArrayList :
public ArrayList<PollutionLevel> getAllPolluants() {
ArrayList<PollutionLevel> allLevels = new ArrayList();
allLevels.add(new PollutionLevel("Co",Double.toString(co)));
allLevels.add(new PollutionLevel("H",Double.toString(h)));
allLevels.add(new PollutionLevel("No2",Double.toString(no2)));
allLevels.add(new PollutionLevel("o3",Double.toString(o3)));
allLevels.add(new PollutionLevel("p",Double.toString(p)));
allLevels.add(new PollutionLevel("o3",Double.toString(o3)));
allLevels.add(new PollutionLevel("pm10",Integer.toString(pm10)));
allLevels.add(new PollutionLevel("pm25",Integer.toString(pm25)));
allLevels.add(new PollutionLevel("r",Double.toString(r)));
allLevels.add(new PollutionLevel("so2",Double.toString(so2)));
allLevels.add(new PollutionLevel("t",Double.toString(t)));
allLevels.add(new PollutionLevel("w",Double.toString(w)));
return allLevels;
}
编辑:添加新修改的 MainActivity class 和 PollutionLevelListener 接口,尝试应用@cricket_007 answer
public class MainActivity extends AppCompatActivity implements MainActivityMVP.View, PollutionLevelsListener {
final static String TAG = MainActivity.class.getCanonicalName();
@BindString(R.string.city)
String city;
@BindString(R.string.aqicn_token)
String authToken;
@Inject
MainActivityMVP.Presenter presenter;
ArrayList<PollutionLevel> pollutionLevels;
PollutionLevelsListener pollutionListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
((App) getApplication()).getComponent().injectPollutionLevels(this);
}
@Override
public void updateData(ViewModel viewModel) {
pollutionLevels = viewModel.getAllPolluants();
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
}
//===== NullPointerException
pollutionListener.onPollutionLevelsLoaded(pollutionLevels);
}
@Override
protected void onStart() {
super.onStart();
presenter.setView(this);
presenter.loadData(city, authToken);
}
@Override
public void onPollutionLevelsLoaded(List<PollutionLevel> levels) {
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
};
// Load fragments
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.ll_container);
if (fragment == null) {
fragment = new PollutionLevelsFragment();
fm.beginTransaction()
.add(R.id.ll_container, fragment)
.commit();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.rxUnsubscribe();
}
}
界面
public interface PollutionLevelsListener {
void onPollutionLevelsLoaded(List<PollutionLevel> levels);
}
####################编辑################### #####
在对采用什么解决方案有很多疑问之后,我遵循了@yosriz 的回答和建议。这是我结束的代码。请注意,我仍然需要实现缓存管理功能,因为现在 JSON 对两个片段都进行了请求。
因此,我的两个片段都使用了一个公共存储库。 MainActivity 变成了一个片段容器,它不获取任何数据。它甚至没有 MVP 结构,因为我认为它现在没用了。
我的两个片段(所以我的两个特征)从 PollutionLevelRepository
获取数据:
public interface Repository {
Observable<Aqicn> getPollutionLevelsFromNetwork(String city, String authToken);
Observable<Aqicn> getPollutionLevels(String city, String authToken);
}
public class PollutionLevelsRepository implements Repository {
private PollutionApiService pollutionApiService;
private static Observable<Aqicn> pollutionData = null;
public PollutionLevelsRepository(PollutionApiService pollutionApiService) {
this.pollutionApiService = pollutionApiService;
}
@Override
public Observable<Aqicn> getPollutionLevelsFromNetwork(String city, String authToken) {
pollutionData = pollutionApiService.getPollutionObservable(city, authToken);
return pollutionData;
}
@Override
public Observable<Aqicn> getPollutionLevels(String city, String authToken) {
return getPollutionLevelsFromNetwork(city, authToken);
}
}
我的第一个片段的模型(甜甜圈特征):
public class DonutModel implements DonutFragmentMVP.Model {
final static String TAG = DonutModel.class.getSimpleName();
private Repository repository;
public DonutModel(Repository repository) {
this.repository = repository;
}
@Override
public Observable<Aqicn> getPollutionLevels(String city, String authToken) {
Observable<Aqicn> aqicnObservable = repository.getPollutionLevels(city, authToken);
return aqicnObservable;
}
}
我的第二个片段的模型(污染等级特征):
public class PollutionLevelsModel implements PollutionLevelsFragmentMVP.Model {
private Repository repository;
public PollutionLevelsModel(Repository repository) {
this.repository = repository;
}
@Override
public Observable<Aqicn> result(String city, String authToken) {
Observable<Aqicn> aqicnObservable = repository.getPollutionLevels(city, authToken);
return aqicnObservable;
}
}
I'm trying to get the data from my fragment by calling a method in my MainActivity
您的界面似乎只返回字段,这很可能是在请求完成之前。你似乎明白了...
didn't receive the answer yet and this request is called asynchronously using RxJava
我不建议您等待,而是
open my fragment and wait the data being loaded in the activity before get it (showing a visual progress to the user).
无论您想如何实现,您都可以尝试 new ProgressDialog()
并显示/隐藏它。
您的问题是 onAttach
立即被调用并且请求仍在无限期地进行。
您需要 "subscribe" 从片段中获取该数据。
A "listener" 通常不是为了实现 "getter" 而编写的,所以让我们重写一下
public interface PollutionLevelsListener {
void onPollutionLevelsLoaded(List<PollutionLevel> levels);
}
然后,您可以使用它来启动您的 Fragment 而不是在 Activity 启动时立即启动
// The Activity
class ... implements PollutionLevelsListener {
@Override
public void onPollutionLevelsLoaded(List<PollutionLevel> levels) {
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
};
// Moved this section here
// Load fragments
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = fm.findFragmentById(R.id.ll_container);
if (fragment == null) {
fragment = new PollutionLevelsFragment();
// If your object is Parcelable
/*
* Bundle args = new Bundle();
* args.putParcelableArrayList(levels);
* fragment.setArguments(args);
*/
ft.add(R.id.ll_container, fragment).commit();
}
}
现在你有了那个方法,
the presenter call the updateData() method in MainActivity
好吧,这是列表的来源,所以只需将它传递给然后加载片段的新方法
@Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
if (pollutionLevels == null) {
pollutionsLevels = new ArrayList<>();
}
pollutionLevels.clear();
pollutionLevels.addAll(viewModel.getAllPolluants());
this.onPollutionLevelsLoaded(pollutionsLevels);
}
好吧,你可能有时间问题,model.result
是异步 IO 操作,它将在完成时以异步方式更新 activity 上的数据,而你获取数据的片段调用是一旦片段附加了 activity(当你调用片段 commit()
而不是 commitNow()
时它仍然是异步的)但是如果你将它与 [=10= 的可能网络调用进行比较] 它可能总是更快。
实际上我认为你的方法是错误的,当你在 Rx 中使用反应式方式时,你应该推送数据,最后,你将它从 Activity
的片段端拉出来,虽然您不知道此数据是否已经可用。
从演示者加载的数据应立即更新片段,这意味着您的 Activity.updateData()
将更新片段,或者我认为更正确的方法是演示者将绑定到片段本身,因为这是实际的View
正在更新,因此演示者的 view.UpdateData()
将直接通知片段。
您是否尝试在片段中创建一个方法,一旦调用 updateData(ViewModel viewModel) 就可以点击它?
例如(尝试在您的片段中添加此方法):
public class YourFragmentName extends Fragment {
public YourFragmentName(StepsHandler stepsHandler){
this.stepsHandler = stepsHandler;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_supplier_registrtion_first, container, false);
return rootView;
}
public void dataLoaded() {
// Do what you need after data finish loading..
}
}
来自你的Activity:
public class MainActivity extends Activity implements StepsHandler {
YourFragmentName fragmentName;
//onCreate ()
fragmentName = new YourFragmentName(this);
@Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
pollutionLevels = viewModel.getAllPolluants();
fragmentName.dataLoaded();
for(PollutionLevel p : pollutionLevels) {
Log.d(TAG,p.getName());
}
}
}