如何使用 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 == nullgetUserList 响应时。

关于如何构造它的任何想法?

我也开始学习类似的东西。在这里,我宁愿使用回调。

在您的演示者中,

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());
        }
    });
}