Android-Rxjava&retrofit&dagger网络技术干货

「2020 新手必备 」极速入门 Retrofit + OkHt

2019-12-28  本文已影响0人  圆号本昊

老生常谈

A type-safe HTTP client for Android and Java

本文流程

依赖注入

// OkHttp3
api 'com.squareup.okhttp3:okhttp:3.10.0'
api 'com.squareup.okio:okio:1.8.0'
// Retrofit
api 'com.squareup.retrofit2:retrofit:2.7.0'
// Gson 服务器数据交互
api 'com.google.code.gson:gson:2.8.6'

依赖注入很简单, Retrofit 一直是结合 OkHttp 和 Gson(无所谓什么 JSON 解析器都行,这里就用 Gson 了)
我这里专门找了最新的版本库,so~ 大家直接用即可

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

全面进击

Retrofit 开始之前

    public void login2() {
        OkHttpClient okHttpClient = new OkHttpClient();
        //Form表单格式的参数传递
        FormBody formBody = new FormBody
            .Builder()
            //设置参数名称和参数值
            .add("username",mAccountEdit.getText().toString())
            .add("password",mPasswordEdit.getText().toString())
            .build();
        Request request = new Request
            .Builder()
            //Post请求的参数传递
            .post(formBody)
            .url("http://hyh.hljdx.net:8080/SitUpWebServer/login")
            .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {
                Log.d("my_Test", e.getMessage());
            }

            @Override
            public void onResponse(okhttp3.Call call, Response response) throws IOException {
                String result = response.body().toString();
                UserBean userBean = JSON.parseObject(result, UserBean.class);
                Log.d("my_Test",userBean.getUser_head_img());
                response.body().close();
            }
        });
    }

Retrofit 实现

    // baseUrl() 设置路由地址
    Retrofit retrofit = new Retrofit
        .Builder()
        .baseUrl(ApiUtils.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();
        
    // 设置参数
    Call<UserBean> call = retrofit.create(UserMgrService.class)
        .login( mAccountEdit.getText().toString(),
            mPasswordEdit.getText().toString());
            
    // 回调
    call.enqueue(new Callback<UserBean>() {
        @Override
        public void onResponse(Call<UserBean> call, Response<UserBean> response) {
            Log.d("123123", "msg--" + response.body().getUser_head_img());
        }

        @Override
        public void onFailure(Call<UserBean> call, Throwable t) {
            // 失败时做处理
        }
    });

实现流程

创建接口

/**
 * @author fishinwater-1999
 * @version 2019-12-21
 */
public interface UserMgrService {

    /**
     * GET 用 Query
     */
    @GET("login")
    Call<UserBean> login(@Query("username") String username, @Query("password") String password);

}

看到这里想必大家都明白了,如果大家还不明白什么是 Get 请求,以及 @Query("...") 里的 username 和 password 是怎么的话,我这里简单说下
比如说我们现在随便打开一个网页,就拿百度图片里搜索 Github 页面为例:

POST

public interface UserMgrService {

    /**
     * POST 用 Field
     */
    @POST("login")
    @FormUrlEncoded
    Call<UserBean> login(@Field("username") String username, @Field("password") String password);

}

生成 Retrofit 对象

// baseUrl() 设置路由地址
Retrofit retrofit = new Retrofit
    .Builder()
    .baseUrl(ApiUtils.BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .build();
http://hyh.hljdx.net:8080/SitUpWebServer/login
// Gson 服务器数据交互
api 'com.google.code.gson:gson:2.8.6'

具体这个对象怎么获得,大家可以联系后端,或者百度搜下 JsonFormat 插件使用或者 JSON 对象生成器,门路很多这里都告诉你们啦

生成接口对象

UserMgrService service = retrofit.create(UserMgrService.class);

获得 Call 对象

Call<UserBean> call = service.login( mAccountEdit.getText().toString(), mPasswordEdit.getText().toString());

发送请求

Response<UserBean> response = call.execute();
Log.d("123123", "msg--" + response.body().getUser_head_img());
// 回调
call.enqueue(new Callback<UserBean>() {
    @Override
    public void onResponse(Call<UserBean> call, Response<UserBean> response) {
        Log.d("123123", "msg--" + response.body().getUser_head_img());
    }

    @Override
    public void onFailure(Call<UserBean> call, Throwable t) {
        // 失败时做处理
    }
});

登录功能实战

搭建 Model 层

/**
 * @author fishinwater-1999
 * @version 2019-11-12
 */
public interface IBaseLog<L> {

    /**
     * 登录 Api
     * @param userAccount
     * @param mPassword
     * @param loginCallback
     */
    void login(String userAccount, String mPassword, L loginCallback);

}
/**
 * @author fishinwater-1999
 * @version 2019-12-23
 */
public interface IBaseRetCallback<T> {

    void onSucceed(Response<T> response);

    void onFailed(Throwable t);

}
/**
 * @author fishinwater-1999
 * @version 2019-11-12
 */
public class LogViewModel implements IBaseLog<IBaseRetCallback<UserBean>> {

    private final String TAG = "LogViewModel";

    @Override
    public void login(String userAccount, String userPassword, final IBaseRetCallback<UserBean> retCallback) {
        // baseUrl() 设置路由地址
        Retrofit retrofit = new Retrofit
                .Builder()
                .baseUrl(ApiUtils.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        // 设置参数
        UserMgrService service = retrofit.create(UserMgrService.class);
        retrofit2.Call<UserBean> call = service.login( userAccount, userPassword);
        // 回调
        call.enqueue(new Callback<UserBean>() {
            @Override
            public void onResponse(retrofit2.Call<UserBean> call, Response<UserBean> response) {
                retCallback.onSucceed(response);
            }

            @Override
            public void onFailure(retrofit2.Call<UserBean> call, Throwable t) {
                // 失败时做处理
                retCallback.onFailed(t);
            }
        });
    }

}

搭建 Presenter 层

/**
 * @author fishinwater-1999
 * @version 2019-11-12
 */
public interface IBasePresenter<V> {

    /**
     * 绑定
     * @param mLogView
     */
    void attachView(V mLogView);

    /**
     * 解绑
     */
    void detachView();

    /**
     * 登录
     * @param userName
     * @param userPassword
     * @param resultListener
     */
    void login(String userName, String userPassword, V resultListener);

}
/**
 * @author fishinwater-1999
 * @version 2019-11-12
 */
public abstract class BasePresenter<V> implements IBasePresenter<V> {

    private V view;

    @Override
    public void attachView(V mLogView) {
        this.view = mLogView;
    }

    @Override
    public void detachView() {
        this.view = null;
    }

    @Override
    public V getLoginVew() {
        return this.view;
    }

}
/**
 * @author fishinwater-1999
 * @version 2019-11-12
 */
public class LogPresenter extends BasePresenter<ILoginView> {

    private IBaseLog logViewModel;

    public LogPresenter(IBaseLog logViewModel) {
        this.logViewModel = logViewModel;
    }

    @Override
    public void login(String userName, String userPassword, final ILoginView iLoginView) {
        logViewModel.login(userName, userPassword, new IBaseRetCallback<UserBean>() {
            @Override
            public void onSucceed(Response<UserBean> response) {
                UserBean userBean = response.body();
                if (userBean != null) {
                    String user_id = userBean.getUser_id();
                    iLoginView.showLoginSuccess(user_id);
                }
            }

            @Override
            public void onFailed(Throwable t) {
                iLoginView.showLoginFailed(ILoginView.ErrCode.WRONG_NET_WORK);
            }
        });

    }
}

View 层实现

/**
 * @author fishinwater-1999
 * @version 2019-11-12
 */
public abstract class BaseFragment<V , P extends IBasePresenter<V>> extends Fragment {

    /**
     * Presenter 层
     */
    private P mBaseResister;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 自动绑定
        if (mBaseResister == null) {
            mBaseResister = createProsenter();
        }
    }

    /**
     * 在这里确定要生成的 Presenter 对象类型
     * @return
     */
    public abstract P createProsenter();

    /**
     * 获得 Presenter 对象
     * @return
     */
    public P getPresenter() {
        if (mBaseResister == null) {
            createProsenter();
        }
        return mBaseResister;
    }

    /**
     * 碎片销毁时解绑
     */
    @Override
    public void onStop() {
        super.onStop();
        mBaseResister = null;
    }
}
/**
 * @author fishinwater-1999
 */
public class LoginFragment extends BaseFragment<ILoginView, LogPresenter> implements ILoginView {

    private static final String TAG = "LoginFragment";

    private LogViewModel mLogViewModel;

    private LoginFragmentBinding binding;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, R.layout.login_fragment, container, false);
        View view = binding.getRoot();
        binding.setLogCallback(getLogActivity());
        binding.setFragment(this);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (mLogViewModel == null) {
            mLogViewModel = new LogViewModel();
        }
    }

    public void login(View v) {
        getPresenter().login(
                getUserName(),
                getUserPwd(),
                this);
    }

    @Override
    public LogPresenter createPresenter() {
        if (mLogViewModel == null) {
            mLogViewModel = new LogViewModel();
        }
        return new LogPresenter(mLogViewModel);
    }

    @Override
    public String getUserName() {
        return binding.userAccount.getText().toString();
    }

    @Override
    public String getUserPwd() {
        return binding.userPassword.getText().toString();
    }

    @Override
    public void showLoginSuccess(String response) {
        Toast.makeText(getActivity(), "登录成功", Toast.LENGTH_LONG).show();
        SharedPreferencesUtil.putString(getActivity(), SharedPreferencesUtil.PRE_NAME_SITUP, SharedPreferencesUtil.USER_ID, response);
        ARouter.getInstance().build(RouteUtils.MainActivity).navigation();
        getActivity().finish();
    }

    @Override
    public void showLoginFailed(ErrCode errCode) {
        if (errCode == ErrCode.WRONG_USER_NAME) {
            Toast.makeText(getActivity(), "用户名错误", Toast.LENGTH_LONG).show();
        }else if (errCode == ErrCode.WRONG_USER_PWD){
            Toast.makeText(getActivity(), "密码错误", Toast.LENGTH_LONG).show();
        }else if (errCode == ErrCode.WRONG_NET_WORK) {
            Toast.makeText(getActivity(), "未知,请检查网络", Toast.LENGTH_LONG).show();
        }
    }
}

运行

更多模块实战 FIWKeepApp

总结

上一篇 下一篇

猜你喜欢

热点阅读