调用 Rx-java Observable 方法的正确方法是什么?

What is the proper way to call Rx-java Observable methods?

我在 Wrapper class 中定义了以下方法来进行 Rest 调用。

public void getWarehouse(){

    //Generation of  RestAdapter
    RestAdapter adapter = new  RestAdapter.Builder ()
            .setEndpoint(URL)
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();

    //Making request to API
    adapter.create(WarehouseAPI.class).getWarehouse()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<List<Warehouse>>() {
                @Override
                public void onCompleted() {
                    Log.d(this.getClass().getName(), "OnCompleted()");
                }

                @Override
                public void onError(Throwable e) {
                    Log.d(this.getClass().getName(), "Error: "  + e.toString());
                }

                @Override
                public void onNext(List<Warehouse> response) {
                }
            });
}

以上代码运行良好,我得到了预期的响应。但我需要从 Adapter class 调用此方法。我怎样才能做到这一点?有什么方法可以使用 onNext 方法吗?

我是 Android rx-javaRetrofit 的初学者。

编辑-1

我正在使用 staggeredGridView 来显示数据。所以,在我的 MainActivity class 中,我调用以下代码:

 StaggeredGridAdapter adapter = new StaggeredGridAdapter(this);
 mRecyclerView.setAdapter(adapter);

要在 StaggeredGridView holder 中填充数据,我必须调用 getWarehouse 方法。

编辑-2

MainActivity 的 onCreate() 方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mToolbar = (Toolbar) findViewById(R.id.toolbar);
    getWarehouse();
    mRecyclerView = (RecyclerView) findViewById(R.id.staggering_grid);
    mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));

    StaggeredGridAdapter adapter = new StaggeredGridAdapter(this);
    mRecyclerView.setAdapter(adapter);
    GridItemSpaces decoration = new GridItemSpaces(10);
    mRecyclerView.addItemDecoration(decoration);

}

其中 StaggeredGridAdapter 是:

public class StaggeredGridAdapter extends RecyclerView.Adapter<StaggeredGridAdapter.StaggeredGridView>{}

编辑 3

根据建议,我在 MainActivity.onCreate 方法中调用 getWarehouse(); 并将 getWarehouse() 的定义复制到 MainActivity.class

还有我的MainActivity.getWarehouse.onNext方法:

@Override
public void onNext(List<Warehouse> response) {
  mAdapter.addItems(response);
}

其中 mAdapterprivate StaggeredGridAdapter mAdapter;,稍后在 MainActivity.onCreate 方法中初始化。

StaggeredGridAdapter class 中 addItems 方法的定义是什么?

Edit-4

StaggeredGridAdapter

的完整定义
public class StaggeredGridAdapter extends RecyclerView.Adapter<StaggeredGridAdapter.StaggeredGridView> {
private Context context;
private List<Warehouse> warehouses = new ArrayList<Warehouse>();
int size;

public StaggeredGridAdapter(Context context) {
    this.context = context;
}

public void addItems(List<Warehouse> response){
    size = response.size();
    warehouses = response;
}

@Override
public StaggeredGridView onCreateViewHolder(ViewGroup parent, int viewType) {
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
    StaggeredGridView staggeredGridView = new StaggeredGridView(layoutView);
    return staggeredGridView;
}

@Override
public void onBindViewHolder(StaggeredGridView holder, int position) {
    holder.textView.setText(warehouses.get(position).getFace());
}

@Override
public int getItemCount() {
    return size;
}

class StaggeredGridView extends RecyclerView.ViewHolder {
    TextView textView;

    public StaggeredGridView(View itemView) {
        super(itemView);

        textView = (TextView) itemView.findViewById(R.id.img_name);

    }
}

与其在 getWarehouse 方法中订阅,不如让 getWarehouse return observable 并在适配器中执行订阅部分。这样你就可以让 onNext 回调存在于适配器中而不是调用方法中。理想情况下,您也应该只在 getWarehouse 方法中实例化 restadapter 一次,而不是每次都实例化。

public Observable<Warehouse> getWarehouse(){

adapter.getWarehouse()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread());

}

从适配器执行此操作: someClass.getWarehouse().subscribe(new Subscriber()....)

我会将 getWarehouse() 留在 Activity 中。在同一个 Activity 中,您可以保留对 StaggeredGridAdapter 的引用,就像您对 mRecyclerView 所做的那样。在您的适配器中创建一个 public void addItems(List<Warehouse> response),当调用 onNext 时,您只需执行 mAdapter.addItems(response)

例如

 public void addItems(List<Warehouse> items) {
     int oldSize = mDataSet.size();
     synchronized(mDataSet) {
         mDataSet.addAll(items);
     }
     notifyItemRangeInserted(oldSize - 1, mDataSet.size() - 1);
 }

我假设 mDataSet 是您在适配器(您的数据集)中使用的 Collection 的名称。

我也会避免实例化

   RestAdapter adapter = new  RestAdapter.Builder ()
            .setEndpoint(URL)
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();

每次调用 getWarehouse();subscribe returns 一个 Subscription 对象。将其保留为成员变量并在 ondDestroy

中调用取消订阅
@Override
protected void onDestroy() {
    super.onDestroy();
    if (mSubscription != null) {
        mSubscription.unsubscribe();
    }
}