如何使用 MVP 和 rxjava 构建我的应用程序并进行改造以从 Observables 中获取数据?
How to structure my app using MVP with rxjava and retrofit to get data out of Observables?
因此,我会尽量让这个问题切题,但它会涉及遍历整个代码路径的代码片段。
就上下文而言,我是 Android 开发人员的新手,完全是自学成才,因此请在整个过程中通知我任何明确的 misunderstandings/poor 组织。问题的主要焦点是我现在遇到的错误,即在网络请求之后,应该作为该网络请求的结果设置的变量为空,因为代码在网络请求完成之前向前移动.
这是我的 activity 方法。它应该用 mUserPresenter.getUserList()
的结果填充 mFriends
变量,这是(不幸的是)null
:
/**
* Grabs a list of friends, populates list with UserAdapter
*/
@Override
public void onResume(){
super.onResume();
mUserPresenter = new UserPresenter();
mFriends = mUserPresenter.getUserList();
if (mGridView.getAdapter() == null) {
UserAdapter adapter = new UserAdapter(getActivity(), mFriends);
mGridView.setAdapter(adapter);
}
else{
((UserAdapter)mGridView.getAdapter()).refill(mFriends);
}
}
下面是我构建 UserPresenter
方法的方式 getUserList
:
public List<User> getUserList()
{
ApiService.get_friends(this);
return mUserList;
}
真正的魔法发生在 ApiService
class:
public static void get_friends(final UserPresenter userPresenter){
ApiEndpointInterface apiService = prepareService();
apiService.get_friends().
observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Action1<List<User>>()
{
@Override
public void call(List<User> users) {
userPresenter.setList(users);
}
}
);
}
我的想法是,通过在 ApiService
中调用 userPresenter.setList(users)
,这会将 mUserList
设置为来自 api 请求的响应。但是,相反,mUserList == null
在 getUserList
响应时。
关于如何构造它的任何想法?
我也开始学习类似的东西。在这里,我宁愿使用回调。
在您的演示者中,
public void setList(List<User> users) {
yourView.setUserList(users);
}
你的 activity 实现了一个视图 (MVP)
@Override
public void setUserList(List<User> users) {
((UserAdapter)mGridView.getAdapter()).refill(mFriends);
}
此外,检查改造是否未返回空列表。
在了解这一切的过程中,我做了一个小应用程序。它从 GitHub 获取用户数据并显示在列表中。我也在使用 ORMLite 和 Picasso,所以那里有一些数据库的东西。也使用了 Dagger Dependency(但你可以忽略它)。这是 link.
这是我的 Presenter 的行为方式:
private DataRetrieverImpl dataRetriever;
@Override
public void getUserList(String name) {
dataRetriever.getUserList(name);
}
@Override
public void onEvent(DataRetrieverEvent event) {
UserList userList = (UserList)event.getData();
mainView.setItems(userList);
}
DataRetrieverImpl
作为一个模块(某种程度上)工作。
private DataRetriever dataRetriever;
restAdapter = new RestAdapter.Builder().setEndpoint(SERVER_END_POINT).build();
dataRetriever = restAdapter.create(DataRetriever.class);
public void getUserList(final String name) {
Log.i(TAG, "getting user list for: " + name);
Observable<UserList> observable = dataRetriever.getUserList(name);
Log.i(TAG, "subscribe to get userlist");
observable.subscribe(new Action1<UserList>() {
@Override
public void call(UserList userList) {
eventBus.post(new DataRetrieverEvent("UserList", userList));
// save to database
for (User user : userList.getItems()) {
Log.i(TAG, user.getLogin());
try {
dbHelper.create(user);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});
}
而DataRetriever
是retrofit的接口。对于命名混乱,我深表歉意。
public interface DataRetriever {
@GET("/search/users")
public Observable<UserList> getUserList(@Query("q") String name);
}
任何我的 Activity,
@Override
public void setItems(final UserList userList) {
runOnUiThread(new Runnable() {
@Override
public void run() {
UserAdapter userAdapter = (UserAdapter)recyclerView.getAdapter();
userAdapter.setUserList(userList);
userAdapter.notifyItemRangeInserted(0, userAdapter.getItemCount());
}
});
}
因此,我会尽量让这个问题切题,但它会涉及遍历整个代码路径的代码片段。
就上下文而言,我是 Android 开发人员的新手,完全是自学成才,因此请在整个过程中通知我任何明确的 misunderstandings/poor 组织。问题的主要焦点是我现在遇到的错误,即在网络请求之后,应该作为该网络请求的结果设置的变量为空,因为代码在网络请求完成之前向前移动.
这是我的 activity 方法。它应该用 mUserPresenter.getUserList()
的结果填充 mFriends
变量,这是(不幸的是)null
:
/**
* Grabs a list of friends, populates list with UserAdapter
*/
@Override
public void onResume(){
super.onResume();
mUserPresenter = new UserPresenter();
mFriends = mUserPresenter.getUserList();
if (mGridView.getAdapter() == null) {
UserAdapter adapter = new UserAdapter(getActivity(), mFriends);
mGridView.setAdapter(adapter);
}
else{
((UserAdapter)mGridView.getAdapter()).refill(mFriends);
}
}
下面是我构建 UserPresenter
方法的方式 getUserList
:
public List<User> getUserList()
{
ApiService.get_friends(this);
return mUserList;
}
真正的魔法发生在 ApiService
class:
public static void get_friends(final UserPresenter userPresenter){
ApiEndpointInterface apiService = prepareService();
apiService.get_friends().
observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Action1<List<User>>()
{
@Override
public void call(List<User> users) {
userPresenter.setList(users);
}
}
);
}
我的想法是,通过在 ApiService
中调用 userPresenter.setList(users)
,这会将 mUserList
设置为来自 api 请求的响应。但是,相反,mUserList == null
在 getUserList
响应时。
关于如何构造它的任何想法?
我也开始学习类似的东西。在这里,我宁愿使用回调。
在您的演示者中,
public void setList(List<User> users) {
yourView.setUserList(users);
}
你的 activity 实现了一个视图 (MVP)
@Override
public void setUserList(List<User> users) {
((UserAdapter)mGridView.getAdapter()).refill(mFriends);
}
此外,检查改造是否未返回空列表。
在了解这一切的过程中,我做了一个小应用程序。它从 GitHub 获取用户数据并显示在列表中。我也在使用 ORMLite 和 Picasso,所以那里有一些数据库的东西。也使用了 Dagger Dependency(但你可以忽略它)。这是 link.
这是我的 Presenter 的行为方式:
private DataRetrieverImpl dataRetriever;
@Override
public void getUserList(String name) {
dataRetriever.getUserList(name);
}
@Override
public void onEvent(DataRetrieverEvent event) {
UserList userList = (UserList)event.getData();
mainView.setItems(userList);
}
DataRetrieverImpl
作为一个模块(某种程度上)工作。
private DataRetriever dataRetriever;
restAdapter = new RestAdapter.Builder().setEndpoint(SERVER_END_POINT).build();
dataRetriever = restAdapter.create(DataRetriever.class);
public void getUserList(final String name) {
Log.i(TAG, "getting user list for: " + name);
Observable<UserList> observable = dataRetriever.getUserList(name);
Log.i(TAG, "subscribe to get userlist");
observable.subscribe(new Action1<UserList>() {
@Override
public void call(UserList userList) {
eventBus.post(new DataRetrieverEvent("UserList", userList));
// save to database
for (User user : userList.getItems()) {
Log.i(TAG, user.getLogin());
try {
dbHelper.create(user);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});
}
而DataRetriever
是retrofit的接口。对于命名混乱,我深表歉意。
public interface DataRetriever {
@GET("/search/users")
public Observable<UserList> getUserList(@Query("q") String name);
}
任何我的 Activity,
@Override
public void setItems(final UserList userList) {
runOnUiThread(new Runnable() {
@Override
public void run() {
UserAdapter userAdapter = (UserAdapter)recyclerView.getAdapter();
userAdapter.setUserList(userList);
userAdapter.notifyItemRangeInserted(0, userAdapter.getItemCount());
}
});
}