preface
This article mainly explains the common network framework encapsulation of Android, and the implementation of a code to switch the mainstream network framework at will. Readers can also follow the ideas in this chapter to achieve other effects, such as switching permission request frameworks at will.
The characteristics of
Written this way, refactoring is easy!
What is isolation layer design?
Let me draw a picture to illustrate
Let’s take real life for example.
-
Consider the buyer (customer) as the APP we wrote;
-
Think of people (owners) as the mainstream network framework we approach (XUtils, OkHttp, OkGo….) ;
-
Real estate companies (such as Lianjia) are regarded as the services (POST, GET network request, etc.) needed by customers (our APP);
-
The salesman (intermediary) as the customer’s recommender;
then
If the App wants to realize the network request, it needs to find the salesman of the real estate company first. The salesman will get the list of the network frame (owner list) that has been settled in the real estate company and provide the user with choice. If the user is not satisfied with the house (network frame), he can change to another one at any time. And real estate company and salesman is this chapter so-called isolation layer.
The train of thought is understood clearly, then began actual combat operation
The first step is to create a real estate company called IHttpProcessor
/** * Real estate company */
public interface IHttpProcessor {
// Have the ability to sell the house
// Network access capability
void post(String url, Map<String,Object> params, ICallback callback);
void get(String url, Map<String,Object> params,ICallback callback);
}
Copy the code
Whether the transaction is successful is the callback ICallback
/** * the top-level callback interface */
public interface ICallback {
void onSuccess(String result);
void onFailure(String e);
}
Copy the code
And the ICallback extension, HttpCallback
/** * an implementation of the callback interface */
public abstract class HttpCallback<Result> implements ICallback{
@Override
public void onSuccess(String result) {
// All the results back from the network are on result
//1. What javaBean does the caller use to receive dataClass<? > clz=analysisClassInfo(this);
//2. Turn String into A javaBean object and hand it to the user
Gson gson=new Gson();
Result objResult=(Result)gson.fromJson(result,clz);
//3. Give the result to the user
onSuccess(objResult);
}
public abstract void onSuccess(Result objResult);
/** * Get the actual type of the input parameter */
privateClass<? > analysisClassInfo(Object object){GetGenericSuperclass () returns an object of type
// This object can be obtained containing primitive types, parameterizations, arrays, type variables, and primitive data types
Type getType=object.getClass().getGenericSuperclass();
Type[] params=((ParameterizedType)getType).getActualTypeArguments();
return(Class<? >)params[0];
}
@Override
public void onFailure(String e) {}}Copy the code
Code analysis: Why was this class created? Imagine, when the user, when the buyer is successful, does the customer have to have a contract, and all kinds of vouchers. And this class is the network request after the success of the data to do a layer of data analysis, try to deal with the complex data, to the upper layer to submit a very simple data structure.
Step 2, we create the owner and merge into the real estate company (OkHttp example)
public class OkHttpProcessor implements IHttpProcessor {
private OkHttpClient mOkHttpClient;
private Handler myHandler;
public OkHttpProcessor(a){
mOkHttpClient=new OkHttpClient();
myHandler=new Handler(Looper.getMainLooper());
}
@Override
public void post(String url, Map<String, Object> params,final ICallback callback) {
final RequestBody requestBody=appendBody(params);
Request request=new Request.Builder()
.url(url)
.post(requestBody)
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result=response.body().string();
if(response.isSuccessful()){
myHandler.post(new Runnable() {
@Override
public void run(a) { callback.onSuccess(result); }}); }else{
myHandler.post(new Runnable() {
@Override
public void run(a) { callback.onFailure(result); }}); }}@Override
public void onFailure(Call call, IOException e) {
myHandler.post(new Runnable() {
@Override
public void run(a) {
callback.onFailure("onFailure"); }}); }}); }@Override
public void get(String url, Map<String, Object> params, ICallback callback) {}private RequestBody appendBody(Map<String, Object> params){
FormBody.Builder body=new FormBody.Builder();
if(params==null || params.isEmpty()){
return body.build();
}
for(Map.Entry<String, Object> entry:params.entrySet()){
body.add(entry.getKey(),entry.getValue().toString());
}
returnbody.build(); }}Copy the code
Code analysis: This class OkHttpProcessor realizes the interface of real estate company, and realizes the corresponding network request service in corresponding real estate company service (POST, GET), so that the real estate company has the ability to process OkHttpProcessor corresponding to POST and GET.
The third step is to create an owner again and merge into a real estate company (XUtils example).
public class XUtilsProcessor implements IHttpProcessor {
public XUtilsProcessor(MyApplication app){
x.Ext.init(app);
}
@Override
public void post(String url, Map<String, Object> params,final ICallback callback) {
RequestParams requestParams=new RequestParams(url);
x.http().post(requestParams, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
callback.onSuccess(result);
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {}@Override
public void onCancelled(CancelledException cex) {}@Override
public void onFinished(a) {}}); }@Override
public void get(String url, Map<String, Object> params, ICallback callback) {}}Copy the code
To this, the real estate company had, the owner also had many, and also entered the real estate company. So now comes the salesman
Step 4: HttpHelper
public class HttpHelper implements IHttpProcessor {
// Define an owner, the person who sells a house
private static IHttpProcessor mIHttpProcessor=null;
// Through an API to set which owner sells his house, (who completes the network access)
public static void init(IHttpProcessor httpProcessor){
mIHttpProcessor=httpProcessor;
}
/ / the singleton
private static HttpHelper instance;
public static HttpHelper obtain(a){
synchronized (HttpHelper.class){
if(instance==null){
instance=newHttpHelper(); }}return instance;
}
private HttpHelper(a){}
/** * can you sell the house by yourself */
@Override
public void post(String url, Map<String, Object> params, ICallback callback) {
//http://www.aaa.bbb/index?&user=jett&pwd=123
//http://www.aaa.bbb/index
//&user=jett&pwd=123
String finalUrl=appendParams(url,params);
mIHttpProcessor.post(url,params,callback);
}
@Override
public void get(String url, Map<String, Object> params, ICallback callback) {}public static String appendParams(String url, Map<String,Object> params) {
if(params==null || params.isEmpty()){
return url;
}
StringBuilder urlBuilder=new StringBuilder(url);
if(urlBuilder.indexOf("?") < =0){
urlBuilder.append("?");
}else{
if(! urlBuilder.toString().endsWith("?")){
urlBuilder.append("&"); }}for(Map.Entry<String,Object> entry:params.entrySet()){
urlBuilder.append("&"+entry.getKey())
.append("=")
.append(encode(entry.getValue().toString()));
}
return urlBuilder.toString();
}
private static String encode(String str){
try {
return URLEncoder.encode(str,"utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw newRuntimeException(); }}}Copy the code
HttpHelper: HttpHelper is a real estate broker that implements the ability of the real estate company to sell a house, and init method for the client (APP) which house to sell (which network frame). The static variable mIHttpProcessor is the owner of the house that is about to sell, which is the network framework that we are going to use.
At this point, all the preparations have been made and we can now start trading
Step 5: Start trading
- MyApplication
public class MyApplication extends Application {
@Override
public void onCreate(a) {
super.onCreate();
// HttpHelper.init(new VolleyProcessor(this));
// HttpHelper.init(new XUtilsProcessor(this)); Determine which network framework to use
HttpHelper.init(newOkHttpProcessor()); }}Copy the code
- MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void click(View view) {
String url="https://v.juhe.cn/historyWeather/citys";
HashMap<String,Object> params=new HashMap<>();
//https://v.juhe.cn/historyWeather/citys?&province_id=2&key=bb52107206585ab074f5e59a8c73875b
params.put("province_id"."2");
params.put("key"."bb52107206585ab074f5e59a8c73875b");
HttpHelper.obtain().post(url, params, new HttpCallback<ResponceData>() {
@Override
public void onSuccess(ResponceData objResult) {
Toast.makeText(MainActivity.this, objResult.getResultcode(), Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(String e) {
super.onFailure(e); }}); }}Copy the code
ResponceData is the ResponceData entity that responds to a successful web request
In the next article, how to quickly switch mainstream frameworks using Hilt