1. 添加依賴
1. 在Project的 build.gradle文件添加
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'me.tatarka:gradle-retrolambda:3.2.4'
2. 在App下的build.gradle添加
頭部添加
apply plugin: 'com.neenbedankt.android-apt'
apply plugin: 'me.tatarka.retrolambda'
3. android{}中添加
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
4. dependencies {}中添加
dagger相關
apt 'com.google.dagger:dagger-compiler:2.2'
compile 'com.google.dagger:dagger:2.2'
provided 'org.glassfish:javax.annotation:10.0-b28'
rxjava retrofit相關
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
2. 配置單例對象
1. 創建ActivityScope 該類用於區分與@Sigleton或其他@Scope的作用域。
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}
2. 創建Module
2.1 創建AppModule 提供SharedPreferences和Context對象
@Module
public class AppModule {
private Context context;
public AppModule(MyApplication application){
this.context = application;
}
@Singleton
@Provides
public Context getApplication() {
return context;
}
@Singleton
@Provides
@Named("default")
public SharedPreferences getSharedPreferences(){
return PreferenceManager.getDefaultSharedPreferences(context);
}
@Singleton
@Provides
@Named("config")
public SharedPreferences getConfigGetSharedPreferences(){
return context.getSharedPreferences("config",Context.MODE_PRIVATE);
}
}
2.2 因爲網絡框架是Rxjava+Retrofit 所以要提供OkHttpModule,RetrofitModule兩個類
1. 創建OkHttpModule
@Module
public class OkHttpModule {
/**
* 緩存文件大小
*/
private static long maxSize = 8 * 1024 * 1024;
/**
* 超時時間
*/
private final static long TIMEOUT = 500;
private Cache mCache;
private static File cacheFile;
private OkHttpClient okHttpClient;
@Singleton
@Provides
@Named("cache")
public OkHttpClient provideOkHttpClient(){
if(mCache == null) {
cacheFile = new File(MyApplication.getApplication().getCacheDir().getAbsolutePath(), "cache_mvp");
mCache = new Cache(cacheFile, maxSize);
}
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(message -> Log.e("OkHttpModule",message));
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
if(okHttpClient == null) {
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
.readTimeout(TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.cache(mCache)
.build();
}
return okHttpClient;
}
}
2. 創建RetrofitModule
@Module
public class RetrofitModule {
@Singleton
@Provides
public Retrofit provideRetrofit(@Named("cache") OkHttpClient okHttpClient){
return RetrofitHelper.getInstance(okHttpClient).getRetrofit();
}
@Singleton
@Provides
public RetrofitService provideRetrofitService(Retrofit retrofit){
return retrofit.create(RetrofitService.class);
}
}
3. 提供一個獲取Retrofit單例對象的幫助類
public class RetrofitHelper {
private static final String BASE_URL = "http://ip.taobao.com/";
private Retrofit mRetrofit;
private static RetrofitHelper helper;
private RetrofitHelper(OkHttpClient okHttpClient){
mRetrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
}
/**
*單例 保證對象唯一
*/
public static RetrofitHelper getInstance(OkHttpClient okHttpClient){
if(helper == null) {
synchronized (RetrofitHelper.class){
if(helper == null){
helper = new RetrofitHelper(okHttpClient);
}
}
}
return helper;
}
/**
* 獲取Retrofit對象
* @return
*/
public Retrofit getRetrofit(){
return mRetrofit;
}
}
3. 創建AppConponent
/**
* 通過modules把需要的Module全部添加進來
*/
@Singleton
@Component(modules = {AppModule.class,OkHttpModule.class,RetrofitModule.class})
public interface AppComponent {
/**
* 添加MainComponent
* @param mainModule
* @return
*/
MainComponent addSub(MainModule mainModule);
}
4. 自定義Application
public class MyApplication extends Application {
private static MyApplication mContext;
private static AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
public static MyApplication getApplication() {
return mContext;
}
public static AppComponent getAppComponent() {
return appComponent;
}
}
5.網絡工具類封裝
1. 封裝Observer
public abstract class BaseObserver<T extends BaseInfo> implements Observer<T>{
protected IBaseView mView;
private final String TAG;
private Disposable mDisposable;
public BaseObserver(IBaseView view){
this.mView = view;
TAG = getClass().getSimpleName();
}
@Override
public void onSubscribe(Disposable d) {
this.mDisposable = d;
if(mView!=null) {
mView.addRxDisposable(d);
}
}
@Override
public void onNext(T t) {
this.onSuccess(t);
}
@Override
public void onError(Throwable e) {
this.onError(e,e.getMessage());
if(mDisposable !=null) {
mDisposable.dispose();
}
if(mView != null) {
mView.onError(e.getMessage());
}
}
@Override
public void onComplete() {
Log.e(TAG +" : onComplete","請求成功");
if(mView != null){
mView.closeLoading();
}else if(mDisposable!=null){
mDisposable.dispose();
}
}
/**
* 請求成功
* @param t
*/
public abstract void onSuccess(T t);
/**
* 請求錯誤
* @param e
* @param msg
*/
public abstract void onError(Throwable e,String msg);
}
2. 網絡工具類封裝
public class HttpUtil {
/**
*Post方式請求網絡 mvp方式 傳view
*/
public static <T extends BaseInfo> void post(Observable observable, IBaseView view, final OnResultListener onResultListener){
setSubscribe(observable, new BaseObserver<T>(view) {
@Override
public void onSuccess(T info) {
if(onResultListener!=null){
onResultListener.onSuccess(info);
}
}
@Override
public void onError(Throwable e, String msg) {
Log.e("onError",e.getMessage());
errorDispose(e,msg,onResultListener);
}
});
}
/**
*Post方式請求網絡 view傳null 不是mvp方式
*/
public static void post(Observable observable,OnResultListener onResultListener){
post(observable,null,onResultListener);
}
/**
* 訂閱事件
*/
public static<T> void setSubscribe(Observable<T> observable, Observer<T> observer){
observable
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}
/**
* 接口回調
* @param <T>
*/
public interface OnResultListener<T>{
void onSuccess(T t);
void onError(Throwable error, String msg);
}
/**
* 錯誤處理
* @param error
* @param msg
* @param resultListener
*/
private static void errorDispose(Throwable error,String msg,OnResultListener resultListener) {
if(error!=null && resultListener!=null){
resultListener.onError(error,error.getMessage());
}else if(resultListener!=null){
resultListener.onError(new Exception("網絡不給力"),"");
Toast.makeText(MyApplication.getApplication(),"網絡不給力",Toast.LENGTH_LONG).show();
return;
}
String e = error.getMessage();
int code =0;
if(!TextUtils.isEmpty(e)){
try {
e = e.substring(e.length()-3,e.length());
code = Integer.valueOf(e);
}catch (Exception e1){
Toast.makeText(MyApplication.getApplication(),"網絡不給力",Toast.LENGTH_LONG).show();
}
}
Log.e("錯誤code",code+"");
if(code >= 300 && code < 500){
Toast.makeText(MyApplication.getApplication(),"您的請求迷路了,請稍後再試",Toast.LENGTH_LONG).show();
}else if(code >= 500){
Toast.makeText(MyApplication.getApplication(),"服務器異常,請稍後再試",Toast.LENGTH_LONG).show();
}else{
Toast.makeText(MyApplication.getApplication(),"網絡不給力",Toast.LENGTH_LONG).show();
}
}
}
6.MVP封裝
1. View層基類封裝
public interface IBaseView {
/**
* 數據請求失敗 View層處理
* @param msg
*/
void onError(String msg);
/**
*請求成功關閉loading
*/
void closeLoading();
/**
*添加Disposable
* @param disposable
*/
void addRxDisposable(Disposable disposable);
/**
*移除Disposable
* @param disposable
*/
void removeRxDisposable(Disposable disposable);
}
2. presenter層基類封裝
public abstract class BasePresenter <T extends IBaseView>{
protected T mView;
protected Context mContext;
public BasePresenter(T view,Context context){
this.mView = view;
this.mContext = context;
}
/**
*請求網絡 加載數據方法
*/
public abstract void initData();
/**
*用於將View對象清空
*/
public void onDestoryView() {
if(mView !=null) {
mView = null;
}
}
}
3. module層封裝 接口通用屬性都可以放在這裏面
public class BaseInfo {
}
4. 創建基於Activity的Module
@Module
public class MainModule {
private IMainView mView;
private CompositeDisposable disposables2Destroy;
public MainModule(IMainView view){
this.mView = view;
}
@ActivityScope
@Provides
public IMainView provideMainView(){
return mView;
}
@ActivityScope
@Provides
public CompositeDisposable provideDisposable(){
return disposables2Destroy ==null ? new CompositeDisposable() : disposables2Destroy;
}
}
5. 創建Activity的Component
@ActivityScope
@Subcomponent(modules = MainModule.class)
public interface MainComponent {
/**
* 方法參數中,只能傳遞被注入對象!要在哪個類中注入,寫哪個類,注入到父類沒用!
* @param activity
*/
void inject(MainActivity activity);
}
6. 改造AppComponent(重要)
MainComponent addSub(MainModule mainModule);
7. 創建基於MainActivity的View接口
public interface IMainView extends IBaseView{
/**
* 顯示位置信息
* @param info
*/
void showLocationInfo(IPLocationInfo info);
}
8. 創建基於MainActivity的Presenter類
public class MainPresenter extends BasePresenter<IMainView>{
private final RetrofitService service;
@Inject
public MainPresenter(IMainView view, Context context,RetrofitService service) {
super(view, context);
this.service = service;
}
@Override
public void initData() {
getInfo();
}
public void getInfo(){
HttpUtil.post(service.getIPInfo("61.135.169.121"), mView, new HttpUtil.OnResultListener<IPLocationInfo>() {
@Override
public void onSuccess(IPLocationInfo info) {
mView.showLocationInfo(info);
}
@Override
public void onError(Throwable error, String msg) {
mView.onError(msg);
}
});
}
}
7.MainActivity實現
public class MainActivity extends BaseActivity implements IMainView{
@Inject
MainPresenter presenter;
private TextView city;
private TextView cityCode;
private TextView ip;
private TextView isp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initView() {
city = (TextView) findViewById(R.id.city);
cityCode = (TextView) findViewById(R.id.cityCode);
ip = (TextView) findViewById(R.id.ip);
isp = (TextView) findViewById(R.id.isp);
}
private void initData() {
MyApplication.getAppComponent()
.addSub(new MainModule(this))
.inject(this);
presenter.initData();
}
@Override
public void showLocationInfo(IPLocationInfo info) {
city.setText(String.format("定位城市:%s", info.getData().getCity()));
cityCode.setText(String.format("定位城市代碼:%s", info.getData().getCity_id()));
ip.setText(String.format("地位地區IP:%s", info.getData().getIp()));
isp.setText(String.format("isp服務提供商:%s", info.getData().getIsp()));
}
@Override
public void onError(String msg) {
Toast.makeText(this,msg,Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
if(presenter!=null){
presenter.onDestoryView();
}
}
}
8.聯繫方式
QQ:1509815887
email:zlc921022@163.com
9.下載地址
點擊去下載