Build a different Android Network Architecture Based on javasfit2.0 + RxJava + Dragger2, rxjavadragger2
As we all know, the core of a mobile APP is to call the background interface to display relevant information so that we can interact with the outside world on the mobile phone. Therefore, the establishment of network frameworks in apps has always been a concern of our developers. In Android, there are two types of network frameworks: one is to use third-party open-source network frameworks instead of repeatedly building wheels, and the other is to encapsulate their own network frameworks.
It is good to encapsulate and implement the network framework by ourselves, but this requires our own high capabilities. In many cases, we do not have the ability to encapsulate it well. At this time, it is not a good thing to use open-source network frameworks. The well-known network frameworks on github have been verified by many apps, in a certain sense, it is very consistent with what we need in actual project development.
Several well-known open-source network frameworks in Android development include android-async-http, Volley, and OkHttp. The xUtils quick development framework developed by Chinese people is also popular. Android-async-http is a classic network framework. Officially recommended by Volley. OkHttp can be said to be a rising star and is now very popular. The underlying APIs of the Android system are useful, so it is very niubility.
Many of our developers are in small companies and do not know how large companies build Android Network frameworks. They also want to know what technologies are used by apps with over 10 million users, there are two images below. Let's take a look at the technologies used by Meituan and Uber for Android.
US Mission Uber
After reading this, you will find that many open-source frameworks are also used for these apps with over million users. Most of these open-source frameworks are actually commonly used in development and are no stranger. Most people may not be familiar with Retrofit and Rxjava. Let's talk about how to build the Android Network Architecture with javasfit2.0 + RxJava + Dragger2 today, we provide you with an idea for your reference.
It is a dependency injection framework that can greatly save the amount of code and facilitate maintenance.
Here I will not spend too much time introducing three things. Today's topic is to provide a way of building a different network framework. If you are not familiar with these three frameworks, you can make up your own Google brain.
First, introduce these frameworks into our projects as dependent libraries and add them to the app/build. gradle file.
Apply plugin: 'com. android. application 'apply plugin: 'com. neenbedankt. android-apt 'android {compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig {applicationId "com. finddreams. invalid fit "minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName" 1.0 "} buildTypes {release {minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt '), 'proguard-rules. pro' }}} dependencies {compile fileTree (include :['*. jar '], dir: 'libs') testCompile 'junit: junit: 4.12 'compile' com. android. support: appcompat-v7: 23.1.1 '// your fit compile 'com. squareup. invalid fit2: Invalid fit: 2.0.0-beta4 '// gson parses compile 'com. squareup. required fit2: converter-gson: 2.0.0-beta4 '// rxjava compile' io. reactivex: rxandroid: 1.1.0 'compute' com. squareup. required fit2: adapter-rxjava: 2.0.0-beta4 '// dragger2 provided 'org. glassfish: javax. annotation: 10.0-b28 'apt 'com. google. dagger: dagger-compiler: 2.0.2 'compile 'com. google. dagger: 2.0.2 '}
Because Dragger2 is annotation-based, it will generate some class files in advance, so you need to add the apt tool to the/build. gradle file of the entire project:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.0.0-beta6' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' // NOTE: Do not place your application dependencies here; they belong // in the inpidual module build.gradle files }}allprojects { repositories { jcenter() }}task clean(type: Delete) { delete rootProject.buildDir}
Then, write a singleton class that provides Retrofit:
/*** Entity class of fit */public class RestApiAdapter {private static dynamic fit = null; public static dynamic fit getInstance () {if (Dynamic Fit = null) {GsonConverterFactory gsonConverterFactory = GsonConverterFactory. create (); OkHttpClient okHttpClient = new OkHttpClient (); OkHttpClient. builder builder = okHttpClient. newBuilder (); builder. retryOnConnectionFailure (true); duplicate fit = new duplicate fit. builder (). client (okHttpClient ). baseUrl (ConstantApi. baiduUrl ). addConverterFactory (gsonConverterFactory ). addCallAdapterFactory (RxJavaCallAdapterFactory. create ()). build () ;}return pull fit ;}}
AddCallAdapterFactory (RxJavaCallAdapterFactory. create () is the key to combining RxJava with Retrofit.
Next, we provide a service interface for movie fit to declare the api address and required parameters. Here we use the weather interface provided by Baidu API to query the weather by city name,
/***** Weather interface Api */public interface WeatherApiService {/***** query weather conditions */@ GET ("apistore/weatherservice/cityname") Observable
QueryWeather (@ Header ("apikey") String apikey, @ Query ("cityname") String cityname );}
Returning an Observable observer/event source means to be handled by RxJava.
Then, we write a BaseSubsribe observer to manage the network request and start to end. successes and failures:
/* Observer ** @ author finddreams * @ address https://blog.csdn.net/finddreams */public abstract class BaseSubsribe
Extends Subscriber
{Private static final String TAG = "BaseSubsribe"; @ Override public void onStart () {super. onStart (); Log. I (TAG, "onStart") ;}@ Override public void onNext (T t) {Log. I (TAG, "response" + t. toString (); onSuccess (t) ;}@ Override public void onCompleted () {Log. I (TAG, "onCompleted");} public abstract void onSuccess (T result); @ Override public void onError (Throwable e) {e. printStackTrace (); Log. I (TAG, "onError" + e. getMessage ());}}
Next we will write a WeatherInteractor interface to connect to the service class:
/*** Interface for obtaining weather information ** @ author finddreams * @ address https://blog.csdn.net/finddreams */public interface WeatherInteractor {subcategory queryWeather (String apikey, String cityname, BaseSubsribe
Subsribe );}
Then there is the implementation class of this interface:
/*** Implementation class for obtaining weather information */public class WeatherInteractorImpl implements WeatherInteractor {private final WeatherApiService api; @ Inject public WeatherInteractorImpl (WeatherApiService myApi) {this. api = myApi;} @ Override public subscribe queryWeather (String apikey, String cityname, BaseSubsribe
Subsribe) {Observable
Observable = api. queryWeather (apikey, cityname); subscribe = observable. subscribeOn (Schedulers. io ()). observeOn (AndroidSchedulers. mainThread ()). subscribe (subsribe); return subscribe ;}}
The next step is how to use Dragger2. Anyone who knows Dragger2 knows that there are several concepts. One is Module: It mainly provides dependent objects such as context, rest api ...; One is @ inject: annotation, Which is used where dependent objects are needed; the other is Componet: used to connect Module and @ inject
First, define a Module class to provide the objects to be injected with dependencies:
/*** Module class ** Provides the class to be injected ** @ author finddreams * @ address https://blog.csdn.net/finddreams */@ Modulepublic class InteractorModule {@ Provides public extends fit provideRestAdapter () {return RestApiAdapter. getInstance () ;}@ Provides public WeatherApiService provideHomeApi (descrifit restAdapter) {return restAdapter. create (WeatherApiService. class) ;}@ Provides public WeatherInteractor provideHomeInteractor (WeatherApiService myApi) {return new WeatherInteractorImpl (myApi );}}
Next, write a Componet class:
/*** Declare the AppComponent Component ** @ author finddreams * @ address https://blog.csdn.net/finddreams */@ Singleton @ Component (modules = {InteractorModule. class,}) public interface AppComponent {void inject (App app); WeatherInteractor getWeatherInteractor ();}
Then we initialize the AppComponent in the Application:
/*** Application class ** @ author finddreams * @ address https://blog.csdn.net/finddreams */public class App extends Application {private AppComponent component; @ Override public void onCreate () {super. onCreate (); setDraggerConfig ();} public AppComponent component () {return component;} public static App get (Context context) {return (App) context. getApplicationContext ();}/*** initialize Dragger. DaggerAppComponent is automatically generated and requires Rebuild */private void setDraggerConfig () {component = DaggerAppComponent. builder (). interactorModule (new InteractorModule ()). build (); component. inject (this );}}
Note that Dagger2 is a pre-compiled class, so we need to Rebuild the project to generate the DaggerAppComponent class. If
Import com. finddreams. Invalid fit. api. config. DaggerAppComponent; the error of this class cannot be found.
In this case, you need to re-build the project
This is the class file generated after the Rebuild project,
Finally, we can start using it in Activity:
/*** Homepage ** @ author finddreams * @ address https://blog.csdn.net/finddreams */Public class MainActivity extends AppCompatActivity {private AppComponent component; private WeatherInteractor weatherInteractor; private EditText city; private TextView queryresult; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); city = (EditText) findViewById (R. id. city); queryresult = (TextView) findViewById (R. id. queryresult); // obtain the AppComponent component = App. get (this ). component (); // obtain WeatherInteractor weatherInteractor = component through AppComponent. getWeatherInteractor (); findViewById (R. id. query ). setOnClickListener (new View. onClickListener () {@ Override public void onClick (View v) {queryWeatherData () ;}}) ;}public void queryWeatherData () {String content = city. getText (). toString (); // call the weather query method subscribe = weatherInteractor. queryWeather (ConstantApi. baiduKey, content, new BaseSubsribe
() {@ Override public void onSuccess (WeatherResultBean result) {WeatherResultBean. retDataEntity retData = result. getRetData (); queryresult. setText (retData. getCity () + ":" + retData. getWeather () + ":" + retData. getDate () ;}@ Override public void onError (Throwable e) {super. onError (e); queryresult. setText ("query failed") ;}}); // cancel the request // subpipeline. unsubscribe ();}}
Let's take a look at the project running result diagram: