简书原文链接:RxJava实例-线程切换
效果图
简单说明
UI包括两个按钮,一个进度条,一个RecyclerView,其中RecyclerView用来显示log信息,后面的例子都是这个形式。
写一个通用的Adapter
既然打算写一些RxJava的Demo,那么最简单直观的方式就是将log显示处理,让处理过程直接明了。
public class LogAdapter extends RecyclerView.Adapter<LogAdapter.ViewHolder>{
private Context mContext;
private List<String> mLogs;
public LogAdapter(Context context, @NonNull List<String> logs){
this.mContext = context;
this.mLogs = logs;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_log,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (mLogs.size() > 0){
holder.tvLog.setText(mLogs.get(position));
}
}
@Override
public int getItemCount() {
return mLogs.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView tvLog;
public ViewHolder(View itemView) {
super(itemView);
tvLog = (TextView) itemView.findViewById(R.id.tv_item_log);
}
}
}
其中UI就只有一个TextView,用来显示log信息
封装一下log的输出方法:
private void log(String logMsg){
if (isMainThread()){
mLogs.add(logMsg + "(主线程)");
mAdapter.notifyDataSetChanged();
}else {
mLogs.add(logMsg + "(非主线程)");
//此处必须在UI线程更新(因为此时RecycelrView可能还在计算布局或者滚动)
new Handler(Looper.getMainLooper())
.post(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
Log.d(TAG, "log: itemCount ->" + mAdapter.getItemCount());
}
private boolean isMainThread(){
return Looper.getMainLooper() == Looper.myLooper();
}
主要代码
点击开始按钮,开始执行下面的代码:
subscription = Observable.just(true)
.map(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean aBoolean) {
log("Observable -> map -> call");
doSomethingBlocked();
return aBoolean;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
mProgressBgWork.setVisibility(View.INVISIBLE);
log("subscriber -> onCompleted");
}
@Override
public void onError(Throwable e) {
mProgressBgWork.setVisibility(View.INVISIBLE);
log("subscriber -> onError :" + e.getMessage());
}
@Override
public void onNext(Boolean aBoolean) {
log("subscriber -> onNext :" + aBoolean);
}
});
其中用doSomethingBlocked()模拟耗时操作,耗时操作在io线程执行,然后切换到主线程展示log。
下面是doSomethingBlocked()的代码:
private void doSomethingBlocked() {
log("进行耗时操作");
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
源代码
总参考:https://github.com/kaushikgopal/RxJava-Android-Samples.git
Demo地址:https://github.com/jiangkang/KLearnAndroid.git