调用 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-java
和 Retrofit
的初学者。
编辑-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);
}
其中 mAdapter
是 private 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();
}
}
我在 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-java
和 Retrofit
的初学者。
编辑-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);
}
其中 mAdapter
是 private 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();
}
}