最好的安卓网络请求库

原文:The Best Android Networking Library for Fast and Easy Networking

最近我发布了一个library,我认为它是安卓上处理网络的最简方式。

以下是Fast Android Networking优于它库的几个方面:

每个请求都可以轻易的定制OkHttpClient-比如超时等。

因为它使用了OkHttpClientOkio,所以速度很快

支持RxJava点击这里

支持把JSON解析成java对象(同时支持Jackson解析)。

可以得到任何请求的详细数据分析。你可以知道发送了多少字节,接收了多少字节,以及请求所花的时间。这些数据是很重要的,这样你就可以识别出慢的请求。

你可以得到当前的带宽和网络质量以写出更合理的代码-网络质量高的时候下载高质量的图片,不好的时候下载低质量的图片。

Proper Response Caching— which leads toreduced bandwidth usage.

很好的响应请求-可以减少带宽的使用。

一个executor可以被传递给任何请求让响应在另一个线程中被获取。如果你在响应中做了很重的任务,你不可以在主线程中做。

一个库就能处理所有类型的网络问题-下载,上传,multipart。

可以通过设置prefetch(预取)让请求在需要的时候立即返回缓存。

任何类型的自定义都是可以的

立即请求真的是立即发生的。

很好的取消请求。

如果一个请求完成了指定的百分比,可以阻止其取消。

一个简单的接口就可以做任何类型的请求。

为什么你应该使用Fast Android Networking Library?

最近Android Marshmallow(Android M)上对HttpClient的移除让其它的网络库都过时了。

没有哪个单一的库做完了所有的事情,比如发送请求,下载任意类型的文件,上传文件,在ImageView中加载网络图片,等等。有一些库可以但是都过时了。

因为使用了sOkHttp,所以支持HTTP/2。

没有哪个库为网络中所有类型的事情提供了简单的接口,比如设置优先级,取消请求等。

如何使用Fast Android Networking

build.gradle

compile 'com.amitshekhar.android:android-networking:0.2.0'

发起GET请求

AndroidNetworking.get("http://api.localhost.com/{pageNumber}/test")
                 .addPathParameter("pageNumber", "0")    //参数
                 .addQueryParameter("limit", "3")    //参数
                 .addHeaders("token", "1234")    //请求头
                 .setTag("test")    //相当于名字
                 .setPriority(Priority.LOW)
                 .build()
                 .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                    // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error
                    }
                });

 

发起POST请求

AndroidNetworking.post("http://api.localhost.com/createAnUser")
                 .addBodyParameter("firstname", "Amit")    //参数
                 .addBodyParameter("lastname", "Shekhar")    //参数
                 .setTag("test")    //名字
                 .setPriority(Priority.MEDIUM)  //类型
                 .build()
                 .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                    // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error
                    }
                });

和JAVA对象一起使用 - JSON Parser

/*--------------Example One -> Getting the userList----------------*/
AndroidNetworking.get("http://api.localhost.com/getAllUsers/{pageNumber}")
                .addPathParameter("pageNumber", "0")
                .addQueryParameter("limit", "3")
                .setTag(this)
                .setPriority(Priority.LOW)
                .build()
                    //与实体类结合 注意Gosn转换的类型
                .getAsParsed(new TypeToken<List<User>>() {}, new ParsedRequestListener<List<User>>() {
                    @Override
                    public void onResponse(List<User> users) {
                    // do anything with response
                    Log.d(TAG, "userList size : " + users.size());
                    for (User user : users) {
                        Log.d(TAG, "id : " + user.id);
                        Log.d(TAG, "firstname : " + user.firstname);
                        Log.d(TAG, "lastname : " + user.lastname);
                    }
                    }
                    @Override
                    public void onError(ANError anError) {
                     // handle error
                    }
                });
/*--------------Example Two -> Getting an user----------------*/
AndroidNetworking.get("http://api.localhost.com/getAnUser/{userId}")
                .addPathParameter("userId", "1")
                .setTag(this)
                .setPriority(Priority.LOW)
                .build()
                .getAsParsed(new TypeToken<User>() {}, new ParsedRequestListener<User>() {
                     @Override
                     public void onResponse(User user) {
                     // do anything with response
                         Log.d(TAG, "id : " + user.id);
                         Log.d(TAG, "firstname : " + user.firstname);
                         Log.d(TAG, "lastname : " + user.lastname);
                     }
                     @Override
                     public void onError(ANError anError) {
                      // handle error
                     }
                 }); 
/*-- Note : TypeToken and getAsParsed is important here --*/

从服务器下载一个文件

AndroidNetworking.download(url,dirPath,fileName)
                 .setTag("downloadTest")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .setDownloadProgressListener(new DownloadProgressListener() {
                    @Override
                    public void onProgress(long bytesDownloaded, long totalBytes) {
                    // do anything with progress  
                    }
                 })
                 .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                    // do anything after completion
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error    
                    }
                });

上传一个文件

AndroidNetworking.upload(url)
                 .addMultipartFile("image",file)    
                 .setTag("uploadTest")
                 .setPriority(Priority.IMMEDIATE)
                 .build()
                 .setUploadProgressListener(new UploadProgressListener() {
                    @Override
                    public void onProgress(long bytesUploaded, long totalBytes) {
                    // do anything with progress 
                    }
                 })
                 .getAsJSONObject(new JSONObjectRequestListener() {
                    @Override
                    public void onResponse(JSONObject response) {
                    // do anything with response                
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error 
                    }
                 });

得到一个响应并在另一个线程executor中完成

(注 : 错误和进度总是在主线程中返回)

AndroidNetworking.upload(url)
                 .addMultipartFile("image",file)    
                 .setTag("uploadTest")
                 .setPriority(Priority.IMMEDIATE)
                 .build()
                 .setExecutor(Executors.newSingleThreadExecutor()) // setting an executor to get response or completion on that executor thread
                 .setUploadProgressListener(new UploadProgressListener() {
                    @Override
                    public void onProgress(long bytesUploaded, long totalBytes) {
                    // do anything with progress 
                    }
                 })
                 .getAsJSONObject(new JSONObjectRequestListener() {
                    @Override
                    public void onResponse(JSONObject response) {
                    // below code will be executed in the executor provided
                    // do anything with response                
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error 
                    }
                 });

取消一个请求

任何一个指定了tag的请求都可以被取消。

AndroidNetworking.cancel("tag");//这个就是那个名字

把从网络加载的图片放到ImageView

   <com.androidnetworking.widget.ANImageView
          android:id="@+id/imageView"
          android:layout_width="100dp"
          android:layout_height="100dp"
          android:layout_gravity="center" />
 
      imageView.setDefaultImageResId(R.drawable.default);
      imageView.setErrorImageResId(R.drawable.error);
      imageView.setImageUrl(imageUrl);

从url获取指定了一些参数的Bitmap

AndroidNetworking.get(imageUrl)
                 .setTag("imageRequestTag")
                 .setPriority(Priority.MEDIUM)
                 .setBitmapMaxHeight(100)
                 .setBitmapMaxWidth(100)
                 .setBitmapConfig(Bitmap.Config.ARGB_8888)
                 .build()
                 .getAsBitmap(new BitmapRequestListener() {
                    @Override
                    public void onResponse(Bitmap bitmap) {
                    // do anything with bitmap
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error
                    }
                });

预取请求(以便它可以在需要时立即从缓存中返回)

 

AndroidNetworking.get(ApiEndPoint.BASE_URL + ApiEndPoint.GET_JSON_ARRAY)
                .addPathParameter("pageNumber", "0")
                .addQueryParameter("limit", "30")
                .setTag(this)
                .setPriority(Priority.LOW)
                .build()
                .prefetch();

为某个请求自定义OkHttpClient

OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .addInterceptor(new GzipRequestInterceptor())
                .build();
 
AndroidNetworking.get("http://api.localhost.com/{pageNumber}/test")
                 .addPathParameter("pageNumber", "0")
                 .addQueryParameter("limit", "3")
                 .addHeaders("token", "1234")
                 .setTag("test")
                 .setPriority(Priority.LOW)
                 .setOkHttpClient(okHttpClient) // passing a custom okHttpClient 
                 .build()
                 .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                    // do anything with response
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error
                    }
                });

用ConnectionClass Listener得到当前网络质量和带宽

// Adding Listener
AndroidNetworking.setConnectionQualityChangeListener(new ConnectionQualityChangeListener() {
            @Override
            public void onChange(ConnectionQuality currentConnectionQuality, int currentBandwidth) {
                // do something on change in connectionQuality
            }
        });
 
// Removing Listener   
AndroidNetworking.removeConnectionQualityChangeListener();
 
// Getting current ConnectionQuality
ConnectionQuality connectionQuality = AndroidNetworking.getCurrentConnectionQuality();
if(connectionQuality == ConnectionQuality.EXCELLENT){
// do something
}else if (connectionQuality == ConnectionQuality.POOR){
// do something
}else if (connectionQuality == ConnectionQuality.UNKNOWN){
// do something
}
// Getting current bandwidth
int currentBandwidth = AndroidNetworking.getCurrentBandwidth(); // Note : if (currentBandwidth == 0)

 

通过在请求上设置分析器来获取对请求的

AndroidNetworking.download(url,dirPath,fileName)
                 .setTag("downloadTest")
                 .setPriority(Priority.MEDIUM)
                 .build()
                 .setAnalyticsListener(new AnalyticsListener() {
                      @Override
                      public void onReceived(long timeTakenInMillis, long bytesSent, long bytesReceived, boolean isFromCache) {
                          Log.d(TAG, " timeTakenInMillis : " + timeTakenInMillis);
                          Log.d(TAG, " bytesSent : " + bytesSent);
                          Log.d(TAG, " bytesReceived : " + bytesReceived);
                          Log.d(TAG, " isFromCache : " + isFromCache);
                      }
                  })
                 .setDownloadProgressListener(new DownloadProgressListener() {
                    @Override
                    public void onProgress(long bytesDownloaded, long totalBytes) {
                    // do anything with progress  
                    }
                 })
                 .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                    // do anything after completion
                    }
                    @Override
                    public void onError(ANError error) {
                    // handle error    
                    }
                });  
Note : If bytesSent or bytesReceived is -1 , it means it is unknown

 

和RxJava一起使用Fast Android Networking请看这里

package com.kunminx.samples.ui.networking;

import android.os.Bundle;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.kunminx.samples.R;
import com.kunminx.samples.databinding.FragmentNetworkingBinding;
import com.kunminx.samples.model.ApiUser;
import com.kunminx.samples.model.User;
import com.kunminx.samples.model.UserDetail;
import com.kunminx.samples.utils.Utils;
import com.rx2androidnetworking.Rx2AndroidNetworking;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;

/**
 * Created by amitshekhar on 04/02/17.
 */

public class NetworkingFragment extends Fragment {

    public static final String TAG = NetworkingFragment.class.getSimpleName();
    private FragmentNetworkingBinding mBinding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_networking, container, false);
        mBinding = FragmentNetworkingBinding.bind(view);
        mBinding.setClickProxy(new ClickProxy());
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

    }

    private Observable<List<User>> getCricketFansObservable() {
        return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllCricketFans")
                .build()
                .getObjectListObservable(User.class);
    }

    /*
     * This observable return the list of User who loves Football
     */
    private Observable<List<User>> getFootballFansObservable() {
        return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllFootballFans")
                .build()
                .getObjectListObservable(User.class);
    }

    /*
     * This do the complete magic, make both network call
     * and then returns the list of user who loves both
     * Using zip operator to get both response at a time
     */
    private void findUsersWhoLovesBoth() {
        // here we are using zip operator to combine both request
        Observable.zip(getCricketFansObservable(), getFootballFansObservable(),
                new BiFunction<List<User>, List<User>, List<User>>() {
                    @Override
                    public List<User> apply(List<User> cricketFans, List<User> footballFans) {
                        List<User> userWhoLovesBoth =
                                filterUserWhoLovesBoth(cricketFans, footballFans);
                        return userWhoLovesBoth;
                    }
                })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<User>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(List<User> users) {
                        // do anything with user who loves both
                        Log.d(TAG, "userList size : " + users.size());
                        for (User user : users) {
                            Log.d(TAG, "user : " + user.toString());
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Utils.logError(TAG, e);
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete");
                    }
                });
    }

    private List<User> filterUserWhoLovesBoth(List<User> cricketFans, List<User> footballFans) {
        List<User> userWhoLovesBoth = new ArrayList<>();

        for (User footballFan : footballFans) {
            if (cricketFans.contains(footballFan)) {
                userWhoLovesBoth.add(footballFan);
            }
        }

        return userWhoLovesBoth;
    }

    private Observable<List<User>> getAllMyFriendsObservable() {
        return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllFriends/{userId}")
                .addPathParameter("userId", "1")
                .build()
                .getObjectListObservable(User.class);
    }

    private Observable<List<User>> getUserListObservable() {
        return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAllUsers/{pageNumber}")
                .addPathParameter("pageNumber", "0")
                .addQueryParameter("limit", "10")
                .build()
                .getObjectListObservable(User.class);
    }

    private Observable<UserDetail> getUserDetailObservable(long id) {
        return Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAnUserDetail/{userId}")
                .addPathParameter("userId", String.valueOf(id))
                .build()
                .getObjectObservable(UserDetail.class);
    }


    public class ClickProxy {

        public void map() {
            Rx2AndroidNetworking.get("https://fierce-cove-29863.herokuapp.com/getAnUser/{userId}")
                    .addPathParameter("userId", "1")
                    .build()
                    .getObjectObservable(ApiUser.class)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(new Function<ApiUser, User>() {
                        @Override
                        public User apply(ApiUser apiUser) {
                            // here we get ApiUser from server
                            User user = new User(apiUser);
                            // then by converting, we are returning user
                            return user;
                        }
                    })
                    .subscribe(new Observer<User>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(User user) {
                            Log.d(TAG, "user : " + user.toString());
                        }

                        @Override
                        public void onError(Throwable e) {
                            Utils.logError(TAG, e);
                        }

                        @Override
                        public void onComplete() {
                            Log.d(TAG, "onComplete");
                        }
                    });
        }

        public void zip() {
            findUsersWhoLovesBoth();
        }

        public void flatMapAndFilter() {
            getAllMyFriendsObservable()
                    .flatMap(new Function<List<User>, ObservableSource<User>>() { // flatMap - to return users one by one
                        @Override
                        public ObservableSource<User> apply(List<User> usersList) {
                            return Observable.fromIterable(usersList); // returning user one by one from usersList.
                        }
                    })
                    .filter(new Predicate<User>() {
                        @Override
                        public boolean test(User user) {
                            // filtering user who follows me.
                            return user.isFollowing;
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<User>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(User user) {
                            // only the user who is following me comes here one by one
                            Log.d(TAG, "user : " + user.toString());
                        }

                        @Override
                        public void onError(Throwable e) {
                            Utils.logError(TAG, e);
                        }

                        @Override
                        public void onComplete() {
                            Log.d(TAG, "onComplete");
                        }
                    });
        }

        public void take() {
            getUserListObservable()
                    .flatMap(new Function<List<User>, ObservableSource<User>>() { // flatMap - to return users one by one
                        @Override
                        public ObservableSource<User> apply(List<User> usersList) {
                            return Observable.fromIterable(usersList); // returning user one by one from usersList.
                        }
                    })
                    .take(4) // it will only emit first 4 users out of all
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<User>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(User user) {
                            // // only four user comes here one by one
                            Log.d(TAG, "user : " + user.toString());
                        }

                        @Override
                        public void onError(Throwable e) {
                            Utils.logError(TAG, e);
                        }

                        @Override
                        public void onComplete() {
                            Log.d(TAG, "onComplete");
                        }
                    });
        }

        public void flatMap() {
            getUserListObservable()
                    .flatMap(new Function<List<User>, ObservableSource<User>>() { // flatMap - to return users one by one
                        @Override
                        public ObservableSource<User> apply(List<User> usersList) {
                            return Observable.fromIterable(usersList); // returning user one by one from usersList.
                        }
                    })
                    .flatMap(new Function<User, ObservableSource<UserDetail>>() {
                        @Override
                        public ObservableSource<UserDetail> apply(User user) {
                            // here we get the user one by one
                            // and returns corresponding getUserDetailObservable
                            // for that userId
                            return getUserDetailObservable(user.id);
                        }
                    })
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<UserDetail>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onError(Throwable e) {
                            Utils.logError(TAG, e);
                        }

                        @Override
                        public void onNext(UserDetail userDetail) {
                            // do anything with userDetail
                            Log.d(TAG, "userDetail : " + userDetail.toString());
                        }

                        @Override
                        public void onComplete() {
                            Log.d(TAG, "onComplete");
                        }
                    });
        }

        public void flatMapWithZip() {
            getUserListObservable()
                    .flatMap(new Function<List<User>, ObservableSource<User>>() { // flatMap - to return users one by one
                        @Override
                        public ObservableSource<User> apply(List<User> usersList) {
                            return Observable.fromIterable(usersList); // returning user one by one from usersList.
                        }
                    })
                    .flatMap(new Function<User, ObservableSource<Pair<UserDetail, User>>>() {
                        @Override
                        public ObservableSource<Pair<UserDetail, User>> apply(User user) {
                            // here we get the user one by one and then we are zipping
                            // two observable - one getUserDetailObservable (network call to get userDetail)
                            // and another Observable.just(user) - just to emit user
                            return Observable.zip(getUserDetailObservable(user.id),
                                    Observable.just(user),
                                    new BiFunction<UserDetail, User, Pair<UserDetail, User>>() {
                                        @Override
                                        public Pair<UserDetail, User> apply(UserDetail userDetail, User user) {
                                            // runs when network call completes
                                            // we get here userDetail for the corresponding user
                                            return new Pair<>(userDetail, user); // returning the pair(userDetail, user)
                                        }
                                    });
                        }
                    })
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Pair<UserDetail, User>>() {
                        @Override
                        public void onComplete() {
                            // do something onCompleted
                            Log.d(TAG, "onComplete");
                        }

                        @Override
                        public void onError(Throwable e) {
                            // handle error
                            Utils.logError(TAG, e);
                        }

                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onNext(Pair<UserDetail, User> pair) {
                            // here we are getting the userDetail for the corresponding user one by one
                            UserDetail userDetail = pair.first;
                            User user = pair.second;
                            Log.d(TAG, "user : " + user.toString());
                            Log.d(TAG, "userDetail : " + userDetail.toString());
                        }
                    });
        }
    }
}

只是用法 都有注释

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值