Android实战——RxJava2+Retrofit+RxBinding解锁各种新姿势

RxJava2+Retrofit+RxBinding解锁各种新姿势


本篇文章内容包含以下内容

  • 前言
  • RxJava2的基本介绍
  • RxJava2观察者模式的介绍
  • RxJava2观察者模式的使用
  • RxJava2的基本使用
    • 模拟发送验证码
  • RxJava2与Retrofit的使用
    • 模拟用户登陆获取用户数据
    • 合并本地与服务器购物车列表
  • RxJava2与RxBinding的使用
    • 优化搜索请求
    • 优化点击请求
  • 源码下载
  • 结语

前言

作为主流的第三方框架Rx系列,不学习也不行啊,对于初学者来说,可能RxJava看起来很难,用起来更难,但是你要知道,越复杂的东西往往能解决越复杂的问题,有可能你应用在项目中,也许你在面试的时候,就会和初级工程师拉开一大段距离。这门课程需要大家有Retrofit的基础,如果想学习Retrofit的同学可以查看我的博客,废话不多说,Hensen老师开车了。

RxJava2的介绍

用原话就是:RxJava2是一个在Java虚拟机上,使用可观察的序列构成基于事件的,异步的程序库。不理解没关系,可以类比成我们的AsyncTask,这样就好理解多了

RxJava传送门:https://github.com/ReactiveX/RxJava

RxJava2观察者模式的介绍

观察者模式就是RxJava使用的核心点,掌握这个模式,可以理解RxJava更简单,观察者模式简单的说就是”订阅-发布”的模式,举一例子说,当你订阅某家牛奶店的早餐奶(订阅过程),只要牛奶店生产牛奶,便会给你送过去(发布过程)。这里的牛奶店只有一家,但是订阅的人可以很多,这是一种一对多的关系,只要牛奶店发布牛奶,那么订阅的人就会收到牛奶。换做RxJava里面的话,牛奶店就是被观察者(Observable),订阅的人就是观察者(Observer)

RxJava2观察者模式的使用

这里我们举一例子学校点名的例子,首先创建我们所说的观察者和被观察者

public interface Observable {
    //订阅
    public void attach(Observer observer);
    //取消订阅
    public void detach(Observer observer);
    //发布
    public void notifyObservers(String message);
}
public interface Observer {
    //给个名字来分辨不同的观察者
    void setName(String name);
    //观察者的方法
    void say(String message);
}

各位可以思考一下,根据上面的介绍,学生和老师,谁是观察者,谁是被观察者,下面就看代码给你分析

public class Teather implements Observable {

    private List<Observer> observers = new ArrayList<>();

    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.say(message);
        }
    }
}
public class Student implements Observer {

    private String name;

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void say(String message) {
        System.out.println(message + ":" + this.name + "到");
    }
}

通过代码可以看到,注意分别实现的不同接口

1、老师是被观察者,他需要实现接口的方法

  • 订阅/取消订阅:往集合中存放/移除观察者
  • 发布:循环遍历观察者,调用观察者方法

2、学生是观察者,那么我们只需要给他个名字,实现观察者的方法即可

最后,我们就把观察者和被观察者关联起来,LessonStart (上课啦)

public class LessonStart {

    public static void main(String[] args){

        Observable teather = new Teather();

        Observer xiaoming = new Student();
        xiaoming.setName("小明");
        Observer xiaohong = new Student();
        xiaohong.setName("小红");

        teather.attach(xiaoming);
        teather.attach(xiaohong);

        teather.notifyObservers("点名啦");
    }
}

代码很简单,我们模拟了一个老师和小明同学和小红同学,老师已经知道看到两个人来了,那么可以开始点名了,下面通过Log打印出信息

点名啦:小明到
点名啦:小红到

RxJava2的基本使用

首先我先贴出我们后面所用到的第三方依赖库,以免后面忘记说了,大家对号入座

//retrofit
compile ‘com.squareup.retrofit2:retrofit:2.2.0‘
compile ‘com.squareup.retrofit2:converter-gson:2.2.0‘
//rx+retrofit
compile ‘com.squareup.retrofit2:adapter-rxjava2:2.2.0‘
//rxjava
compile "io.reactivex.rxjava2:rxjava:2.0.8"
compile ‘io.reactivex.rxjava2:rxandroid:2.0.1‘
//rxbinding
compile ‘com.jakewharton.rxbinding2:rxbinding:2.0.0‘
compile ‘com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0‘
compile ‘com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0‘
compile ‘com.jakewharton.rxbinding2:rxbinding-design:2.0.0‘
compile ‘com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0‘

其次还需要添加联网权限

<uses-permission android:name="android.permission.INTERNET" />

最后我们回到正题,看完上面的例子,我们可以知道RxJava就是这种订阅和发布的模式,换成我们的RxJava代码应该是怎么样的?当然也是通过被观察者订阅观察者啦

//拿到被观察者
Observable<String> observable = getObservable();
//拿到观察者
Observer<String> observer = getObserver();
//订阅
observable.subscribe(observer);

我们具体被观察者和观察者的实现,当然是创建出来啦

public Observable<String> getObservable() {
       return Observable.create(new ObservableOnSubscribe<String>() {
           @Override
           public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
               e.onNext("俊俊俊很帅");
               e.onNext("你值得拥有");
               e.onNext("取消关注");
               e.onNext("但还是要保持微笑");
               e.onComplete();
           }
       });
}

onNext方法就是我们的发布过程,我们看其观察者的创建就知道怎么回事了

public Observer<String> getObserver() {
    return new Observer<String>() {

        Disposable disposable = null;

        @Override
        public void onSubscribe(Disposable d) {
            disposable = d;
        }

        @Override
        public void onNext(String s) {
            Log.e("onNext", s);
            if (s.equals("取消关注")) {
                //断开订阅
                disposable.dispose();
            }
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {
            Log.e("onComplete", "onComplete");
        }
    };
}

我们可以发现,观察者的创建实现的方法,在被观察者中是对应起来的,也就是说,我们发布了什么,就可以在观察者中收到订阅信息,那么我们就可以在代码中编写我们的逻辑了,这样基本上已经使用好了RxJava了,通过Log打印出信息

1、人类就喜欢酷炫,炫耀,当然RxJava也少不了人类这种心理,就是链式编程,下面这段代码可以完美替代上面的所有代码

//创建被观察者
Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    //默认在主线程里执行该方法
    public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
        e.onNext("俊俊俊很帅");
        e.onNext("你值得拥有");
        e.onNext("取消关注");
        e.onNext("但还是要保持微笑");
        e.onComplete();
    }
})
//将被观察者切换到子线程
.subscribeOn(Schedulers.io())
//将观察者切换到主线程
.observeOn(AndroidSchedulers.mainThread())
//创建观察者并订阅
.subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(String s) {
        Log.e("onNext", s);
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onComplete() {

    }
});

这里我多写了两个方法,也就是.subscribeOn(Schedulers.io())和.observeOn(AndroidSchedulers.mainThread()),这里就是RxJava的好处之一,他可以手动切换线程,这两个方法在这里表示被观察者创建实现的方法都放在io线程也就是子线程,因为在被观察者中通常会调用网络数据请求,那么网络请求必须在子线程运行,当网络请求收到后,则发布出去,在观察者中通过TextView等控件展示在界面上,那么UI的更新必须在主线程进行,也就是我们上面的代码mainThread。如果你不深造RxJava,基本上这两个方法已经成了固定的写法,这也是很多初学者忘记添加上去的方法

2、久而久之,人类喜欢简洁,喜欢定制服务,巧了,RxJava也给你满足了,下面这段代码中,实现的方法跟上面的实现方法是对应起来的,大家看参数就知道哪个对应哪个了,你可以通过new Consumer,不需要实现的方法你可以不写,看上去更简洁,这里我为了方便大家看,都new出来了,Consumer就是消费者的意思,可以理解为消费了onNext等等等事件

Observable<String> observable = getObservable();
observable.subscribe(new Consumer<String>() {
    @Override
    public void accept(@NonNull String s) throws Exception {
        Log.e("accept", s);
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(@NonNull Throwable throwable) throws Exception {

    }
}, new Action() {
    @Override
    public void run() throws Exception {

    }
}, new Consumer<Disposable>() {
    @Override
    public void accept(@NonNull Disposable disposable) throws Exception {

    }
});

哦,对了,我们还忘记打印Log信息,不能否认了我很帅这个事实

04-03 01:32:48.445 13512-13512/com.handsome.boke2 E/onNext: 俊俊俊很帅
04-03 01:32:48.446 13512-13512/com.handsome.boke2 E/onNext: 你值得拥有
04-03 01:32:48.446 13512-13512/com.handsome.boke2 E/onNext: 取消关注

当然你觉得只要夸奖我一个帅就行了,那么你也可以通过下面这几种方法发送给观察者

public Observable<String> getObservable() {
    //1、可发送对应的方法
    return Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {
            e.onNext("俊俊俊很帅");
            e.onNext("你值得拥有");
            e.onNext("取消关注");
            e.onNext("但还是要保持微笑");
            e.onComplete();
        }
    });
    //2、发送多个数据
    return Observable.just("俊俊俊很帅","你值得拥有","取消关注","但还是要保持微笑");
    //3、发送数组
    return Observable.fromArray("俊俊俊很帅","你值得拥有","取消关注","但还是要保持微笑");
    //4、发送一个数据
    return Observable.fromCallable(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return "俊俊俊很帅";
        }
    });
}

模拟发送验证码

这里的案例使用我们平时最简单的需求,看效果图就知道(图片会卡,效果大家脑补)

这里是整个代码的实现思路,我会在代码下面注释一下需要注意的点,代码我就直接贴出来,有句话说得好,成为大神,就必须先学会阅读别人的代码,哈哈哈,我的代码阅读起来应该没问题的吧

public class ButtonEnableActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button_enable);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        final long count = 3;
        Observable.interval(0, 1, TimeUnit.SECONDS)
                .take(count + 1)
                .map(new Function<Long, Long>() {
                    @Override
                    public Long apply(@NonNull Long aLong) throws Exception {
                        return count - aLong;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {
                        button.setEnabled(false);
                        button.setTextColor(Color.BLACK);
                    }
                })
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {}
                    @Override
                    public void onNext(Long aLong) {
                        button.setText("剩余" + aLong + "秒");
                    }
                    @Override
                    public void onError(Throwable e) {}
                    @Override
                    public void onComplete() {
                        button.setEnabled(true);
                        button.setTextColor(Color.RED);
                        button.setText("发送验证码");
                    }
                });
    }
}

1、操作符

  • 像这种interval、take、map、observeOn、doOnSubscribe、subscribe都是属于RxJava的操作符,简单的说就是实现某个方法,里面的功能都被包装起来了
  • RxJava支持的操作符很多,很多操作符用起来都简单,但是组合起来就很复杂,功能很强大,具体分类如图所示

2、操作符介绍

  • interval:延时几秒,每隔几秒开始执行
  • take:超过多少秒停止执行
  • map:类型转换,由于是倒计时,案例需要将倒计时的数字反过来
  • observeOn:在主线程运行
  • doOnSubscribe:在执行的过程中
  • subscribe:订阅

RxJava2与Retrofit的使用

RxJava与Retrofit的使用,更像我们的AsyncTask,通过网络获取数据然后通过Handler更新UI

模拟用户登陆获取用户数据

人类总是喜欢看图说话,巧了,我给你提供了,我只能拿出我过硬的美工技术给你们画图了

① Bean对象

public class UserParam {
    private String param1;
    private String param2;
    public UserParam(String param1, String param2) {
        this.param1 = param1;
        this.param2 = param2;
    }
    public String getParam1() {
        return param1;
    }
    public void setParam1(String param1) {
        this.param1 = param1;
    }
    public String getParam2() {
        return param2;
    }
    public void setParam2(String param2) {
        this.param2 = param2;
    }
    @Override
    public String toString() {
        return new Gson().toJson(this);
    }
}
  • 这里我们采用的是httpbin的一个post接口,各位可以在它的网站试一下,这里的NetBean是通过请求返回的数据,进行GsonFormat生成的
public class NetBean {
    private FormBean form;
    public FormBean getForm() {
        return form;
    }
    public void setForm(FormBean form) {
        this.form = form;
    }
    public static class FormBean {
        private String username;
        private String password;
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
    }
}
public class UserBean {
    private String username;
    private String passwrod;
    public UserBean(String passwrod, String username) {
        this.passwrod = passwrod;
        this.username = username;
    }
    public String getPasswrod() {
        return passwrod;
    }
    public void setPasswrod(String passwrod) {
        this.passwrod = passwrod;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    @Override
    public String toString() {
        return new Gson().toJson(this);
    }
}

② ApiService

  • 这里返回Observable对象,也就是我们RxJava的被观察者
public interface ApiService {
    @FormUrlEncoded
    @POST("/post")
    Observable<NetBean> getUserInfo(@Field("username")String username, @Field("password")String password);
}

③ RxJava+Retrofit的实现

public class RxLoginActivity extends AppCompatActivity {

    ApiService apiService;
    TextView tv_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rx_login);
        tv_text = (TextView) findViewById(R.id.tv_text);

        //构建Retrofit
        apiService = new Retrofit.Builder()
                .baseUrl("https://httpbin.org/")
                //rx与Gson混用
                .addConverterFactory(GsonConverterFactory.create())
                //rx与retrofit混用
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
                .create(ApiService.class);

        //构建RxJava
        UserParam param = new UserParam("hensen", "123456");
        //发送param参数
        Observable.just(param)
                .flatMap(new Function<UserParam, ObservableSource<NetBean>>() {
                    @Override
                    public ObservableSource<NetBean> apply(@NonNull UserParam userParam) throws Exception {
                        //第一步:发送网络请求,获取NetBean
                        return apiService.getUserInfo(userParam.getParam1(), userParam.getParam2());
                    }
                })
                .flatMap(new Function<NetBean, ObservableSource<UserBean>>() {
                    @Override
                    public ObservableSource<UserBean> apply(@NonNull NetBean netBean) throws Exception {
                        UserBean user = new UserBean(netBean.getForm().getUsername(), netBean.getForm().getPassword());
                        //第二步:转换netBean数据为我们需要的UserBean类型
                        return Observable.just(user);
                    }
                })
                //将被观察者放在子线程,将观察者放在主线程
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<UserBean>() {
                    @Override
                    public void accept(@NonNull UserBean userBean) throws Exception {
                        //第三步:接收第二步发送过来的数据,进行UI更新
                        tv_text.setText("用户名:" + userBean.getUsername() + "--密码:" + userBean.getPasswrod());
                    }
                });
    }
}

1、Retrofit

  • RxJava与Retrofit一起使用必须在Retrofit上加上这句话addCallAdapterFactory(RxJava2CallAdapterFactory.create())

2、RxJava

  • 我们通过just方式发送数据
  • flatMap方法是用于数据格式转换的方法,其后面的参数UserParam与ObservableSource< NetBean>,参数一表示原数据,参数二表示转换的数据,那么就是通过发送网络参数,转换成网络返回的数据,调用Retrofit

合并本地与服务器购物车列表

这个案例其实就是用户添加购物车的时候,首先会在本地存储一份,然后发现如果没有网络,那么没办法提交到服务器上,只能等下一次有网络的时候采用本地数据库和服务器数据的合并来实现上传到服务器,这里我们就贴RxJava与Retrofit的代码,不贴其他代码了,废话不多说,上图

public class CartMegerActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button;
    private ApiService apiService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cart_meger);
        apiService = new Retrofit.Builder()
                .baseUrl("http://httpbin.org/")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(ApiService.class);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        Observable.merge(getDataForLocal(), getDataForNet()).subscribe(new Observer<List<String>>() {
            @Override
            public void onSubscribe(Disposable d) {}
            @Override
            public void onNext(List<String> strings) {
                for (String str : strings){
                    System.out.println(str);
                }
            }
            @Override
            public void onError(Throwable e) {}
            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }
        });
    }
    private Observable<List<String>> getDataForLocal() {
        List<String> list = new ArrayList<>();
        list.add("购物车物品一");
        list.add("购物车物品二");
        return Observable.just(list);
    }
    private Observable<List<String>> getDataForNet() {
        return Observable.just("购物车物品三").flatMap(new Function<String, ObservableSource<NetBean>>() {
            @Override
            public ObservableSource<NetBean> apply(@NonNull String s) throws Exception {
                return apiService.getCartList(s);
            }
        }).flatMap(new Function<NetBean, ObservableSource<List<String>>>() {
            @Override
            public ObservableSource<List<String>> apply(@NonNull NetBean netBean) throws Exception {
                String shop = netBean.get_$Args257().getShopName();
                List<String> list = new ArrayList<>();
                list.add(shop);
                return Observable.just(list);
            }
        }).subscribeOn(Schedulers.io());
    }
}

这里使用到merge的操作符,其表示意思就是将两个ObservableSource合并为一个ObservableSource,最后的打印结果是

04-03 02:37:28.840 5615-5615/com.handsome.boke2 I/System.out: 购物车物品一
04-03 02:37:28.840 5615-5615/com.handsome.boke2 I/System.out: 购物车物品二
04-03 02:37:39.501 5615-6337/com.handsome.boke2 I/System.out: 购物车物品三
04-03 02:37:39.501 5615-6337/com.handsome.boke2 I/System.out: onComplete

RxJava2与RxBinding的使用

RxBinding的使用也是为了让界面看起来更简洁,剩去了传统的findViewById和setOnClickListener的方法,不用任何声明,只要添加依赖就可以直接使用了

优化搜索请求

这里的案例是说当我们在EditText打字实时搜索的时候,可能用户会打字很会快,那么我们就没有必要一直发送网络请求,请求搜索结果,我们可以通过当用户打字停止后的延时500毫秒再发送搜索请求

public class TextChangeActivity extends AppCompatActivity {
   private  EditText edittext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_change);
        edittext = (EditText) findViewById(R.id.edittext);

        RxTextView.textChanges(edittext)
                //当你敲完字之后停下来的半秒就会执行下面语句
                .debounce(500, TimeUnit.MILLISECONDS)
                //下面这两个都是数据转换
                //flatMap:当同时多个网络请求访问的时候,前面的网络数据会覆盖后面的网络数据
                //switchMap:当同时多个网络请求访问的时候,会以最后一个发送请求为准,前面网路数据会被最后一个覆盖
                .switchMap(new Function<CharSequence, ObservableSource<List<String>>>() {
                    @Override
                    public ObservableSource<List<String>> apply(@NonNull CharSequence charSequence) throws Exception {
                        //网络操作,获取我们需要的数据
                        List<String> list = new ArrayList<String>();
                        list.add("2017年款最新帅哥俊俊俊");
                        list.add("找不到2017年比俊俊俊更帅的人");
                        return Observable.just(list);
                    }
                })
                //网络请求是在子线程的
                .subscribeOn(Schedulers.io())
                //界面更新在主线程
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<List<String>>() {
                    @Override
                    public void accept(@NonNull List<String> strings) throws Exception {
                        //界面更新,这里用打印替代
                        System.out.println(strings.toString());
                    }
                });
    }
}

操作符

  • RxTextView.textChanges(edittext):Rxbinding用法
  • debounce:表示延时多少秒后执行
  • switchMap:也是数据转换,与flatMap的区别在注释中解释很清楚了

演示效果图

优化点击请求

这个案例很简单,当用户一直点击一个按钮的时候,我们不应该一直调用访问网络请求,而是 1秒内,只执行一次网络请求

public class ButtonClickActivity extends AppCompatActivity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button_click);
        button = (Button) findViewById(R.id.button);
        RxView.clicks(button).throttleFirst(1, TimeUnit.SECONDS)
                .subscribe(new Observer<Object>() {
                    @Override
                    public void onSubscribe(Disposable d) {}
                    @Override
                    public void onNext(Object o) {
                        System.out.println("俊俊俊点击了按钮");
                    }
                    @Override
                    public void onError(Throwable e) {}
                    @Override
                    public void onComplete() {}
                });
    }
}

源码下载

源码下载

结语

听说认真看的同学都会学的很多哦,对于RxJava的操作符还是建议大家通过官网的wiki去深造,只有当RxJava用在项目中的时候,你才会体会它的好处,同时也让你与初级工程师有了一定的距离,像很多RxBus、RxPermission、RxAndroid,很多人会疑问要不要去学习它,毫无疑问是必须学习的,技术是不断更新,只有当你的技术跟上时代的时候,你才有可能和大神聊的津津有味,以上纯属瞎掰,当然有时间我也会去学习Rx系列,如果喜欢我的朋友可以关注我的博客,或者加群大家一起学习吧

时间: 2024-11-05 11:56:18

Android实战——RxJava2+Retrofit+RxBinding解锁各种新姿势的相关文章

Android实战——RxJava2解锁图片三级缓存框架

RxJava2解锁图片三级缓存框架 本篇文章包括以下内容 前言 图片三级缓存的介绍 框架结构目录的介绍 构建项目整体框架 实现图片三级缓存 演示效果 源码下载 结语 前言 RxJava2作为如今那么主流的技术,不学习学习都不行了,本篇文章需要你有RxJava2的基础,如果需要对RxJava2学习的同学,可以关注我的博客,查看Android实战--RxJava2+Retrofit+RxBinding解锁各种新姿势 .项目代码实现模仿Picasso,大伙们可以看下最后的代码效果,那么废话不多说,He

Android实现Rxjava2+Retrofit完美封装

去年的时候学习了Rxjava和Retrofit的基本用法,但一直没有在实际项目中运用.今年开做新项目,果断在新项目中引入了RxJava和Retrofit.本篇文章将介绍笔者在项目中对Retrofit的封装.先来看一下封装过后的Retrofit如何使用. RetrofitHelper.getApiService() .getMezi() .compose(this.<List<MeiZi>>bindToLifecycle()) .compose(ProgressUtils.<L

【Android实战】----从Retrofit源码分析到Java网络编程以及HTTP权威指南想到的

一.简介 接上一篇[Android实战]----基于Retrofit实现多图片/文件.图文上传中曾说非常想搞明白为什么Retrofit那么屌.最近也看了一些其源码分析的文章以及亲自查看了源码,发现其对Java网络编程及HTTP权威指南有了一个很好的诠释.一直以来,都信奉一个原则,在这个新技术日新月异的时代,如何在Java界立足,凭借的就两点: 1.基本功,包括:Java基本知识,(Java编程思想.Effective Java),Java进阶(Java虚拟机.Java设计模式).网络相关(这个时

Android实战技巧之四十三:终止一个线程引起的

这是一道老牌面试题.通常面试官会问你对Java线程的了解,然后再问此问题. 从理论到实践,这是一条好路子. 线程是操作系统实现多任务的一种方式,可以理解为线程是一个任务的执行单元.比如Android系统中每个App都会有自己的主线程,同时还可以创建worker thread"并行"为我们工作. Java中创建新线程的方法 Java对线程(Thread)提供了语言级的支持(依托虚拟机吧).java.lang包下有Thread类和Runnable接口,都可以替你完成创建新线程的工作. 1.

【Android实战】记录自学自己定义GifView过程,能同一时候支持gif和其它图片!【有用篇】

之前写了一篇博客.<[Android实战]记录自学自己定义GifView过程,具体解释属性那些事! [学习篇]> 关于自己定义GifView的,具体解说了学习过程及遇到的一些类的解释,然后完毕了一个项目,能通过在xml增加自己定义 view (MyGifView)中增加自己定义属性(my:gif_src = "@drawable/coffee").达到播放gif图片的效果. 可是.有几个问题 1.gif_src 属性仅仅支持 gif 图,并不支持其它类型的图片 2.仅仅支持

Android实战技巧:深入解析AsyncTask

AsyncTask的介绍及基本使用方法 关于AsyncTask的介绍和基本使用方法可以参考官方文档和Android实战技巧:多线程AsyncTask这里就不重复. AsyncTask引发的一个问题 上周遇到了一个极其诡异的问题,一个小功能从网络上下载一个图片,然后放到ImageView中,是用AsyncTask来实现的,本身逻辑也很简单,仅是在doInBackground中用HTTP请求把图片的输入流取出,然后用BitmapFactory去解析,然后再把得到的Bitmap放到ImageView中

Android实战简易教程-第三十九枪(第三方短信验证平台Mob和验证码自动填入功能结合实例)

用户注册或者找回密码时一般会用到短信验证功能,这里我们使用第三方的短信平台进行验证实例. 我们用到第三方短信验证平台是Mob,地址为:http://mob.com/ 一.注册用户.获取SDK 大家可以自行注册,得到APPKEY和APPSECRET,然后下载SDK,包的导入方式如截图: 二.主要代码 SMSSendForRegisterActivity.java:(获取验证码页) package com.qiandaobao.activity; import java.util.regex.Mat

Android实战简易教程-第五十四枪(通过实现OnScrollListener接口实现下拉刷新功能)

上一篇文章Android实战简易教程-第五十三枪(通过实现OnScrollListener接口实现上拉加载更多功能)讲述了如何实现上拉加载更多的功能,本篇,我们在上一篇的基础上实现下拉刷新功能.主要通过对滚动状态和手势监听实现这一功能,下面我们看一下代码: 1.header.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://sch

苹果电脑基本设置+Linux 命令+Android 实战集锦

本文微信公众号「AndroidTraveler」首发. 背景 大多数应届毕业生在大学期间使用的比较多的是 windows 电脑,因此初入职场如果拿到一台苹果电脑,可能一时间不能够很快的上手.基于此,这边出了系列视频,通过实际的演示让没使用过苹果电脑的小伙伴可以快速上手. 定位 适合以下小伙伴: 之前没有使用过苹果电脑 没在苹果电脑上用过 Terminal Android 开发中没用过命令来完成一些任务的 对视频感兴趣的任何好学小伙伴 讲解方式 这边会通过三种形式进行讲解.分别是思维导图.视频以及