请求天气的小应用,练习如何使用Dagger2+Retrofit+RxJava
效果预览
Paste_Image.png
gradle配置
project/build.gradle
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'me.tatarka:gradle-retrolambda:3.2.4'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
project/app/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'com.neenbedankt.android-apt'
android {
......
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
......
}
dependencies {
......
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'
compile 'com.google.dagger:dagger:2.1'
apt 'com.google.dagger:dagger-compiler:2.1'
provided 'org.glassfish:javax.annotation:10.0-b28'
}
项目结构
Paste_Image.png
mvp流程
MainPresenter作为MainActivity和MainModel之间的桥梁,当MainActivity需要请求数据时,通知MainPresenter;MainPresenter通知MainModel需要数据,MainModel通过Retrofit从网络中获取数据,若是请求成功,则把数据传给MainPresenter,若是请求失败,则把失败信息传给MainPresenter。
MainPresenter从MainModel中获取数据信息后通知MainActivity更新数据。
MainActivity中的MainPresenter实例是由Dagger2注入的单例。
public class MainActivity extends AppCompatActivity implements MainView {
@Bind(R.id.tv_displayWeather) TextView tv;
@Bind(R.id.progressBar) ProgressBar progressBar;
@Inject @Singleton public MainPresenter myPresenter; //Dagger不能注入私有变量
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
setContentView(R.layout.activity_main);
ButterKnife.bind(this);//ButterKnife注入
initView();
}
public void displayWeather(View view) {
myPresenter.getData();
}
@Override
public void initView() {
MainComponent component=DaggerMainComponent.builder().mainPresenterModule(new MainPresenterModule(this)).build();
component.inject(this);
}
@Override
public void showData(MainModelBean mybean) {
if(mybean==null){
tv.setText("请求失败");
}
else{
MainModelBean.WeatherinfoEntity bean = mybean.getWeatherinfo();
String city=bean.getCity();
String wd=bean.getWD();
String ws=bean.getWS();
String time=bean.getTime();
String data="城市:"+city+"\n风向:"+wd+"\n风级:"+ws+"\n发布时间:"+time;
tv.setText(data);
}
hideProgressBar();
}
public void showProgressBar(){
progressBar.setVisibility(View.VISIBLE);
}
public void hideProgressBar(){
progressBar.setVisibility(View.GONE);
}
}
MainModel的代码如下:
public class MainModel {
String baseUrl="http://www.weather.com.cn/adat/sk/";
private List list = new ArrayList<>();
private MainPresenter mainPresenter;
public MainModel(MainPresenter mainPresenter){
this.mainPresenter=mainPresenter;
}
public void getData(){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
WeatherService service=retrofit.create(WeatherService.class);
service.getModelBean("101010100")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new MySubscriber());
}
interface WeatherService{
@GET("{cityId}"+".html")
Observable getModelBean(@Path("cityId") String cityId);
}
class MySubscriber extends Subscriber{
@Override
public void onCompleted() {
mainPresenter.loadDataSuccess(list);
}
@Override
public void onError(Throwable e) {
mainPresenter.loadDataFailure();
}
@Override
public void onNext(MainModelBean mainModelBean) {
list.add(mainModelBean);
}
}
}
MainPresenter源码如下:
public class MainPresenter {
private MainView mainView;
public MainModel mainModel=new MainModel(this);
@Inject @Singleton
public MainPresenter(MainView mainView) {
this.mainView=mainView;
}
public void getData(){
mainView.showProgressBar();
mainModel.getData();
}
public void loadDataSuccess(List list) {
mainView.showData(list.get(0));
}
public void loadDataFailure(){
mainView.showData(null);
}
}
源码地址:
参考文章:Android MVP 实例(吴小龙同學)