The university’s science and technology innovation project is coming to an end. Recently, I learned the connection between Android client and server, using the open source framework Okhttp.

1 Okhttp profile

Okhttp is the mainstream Open source framework for handling network requests on Android. It is used to replace HttpUrlConnection. Starting with Android4.4, Google has started replacing HttpURLConnection with OkHttp in the source code.

2 Installation of Okhttp

Add to dependencies in the build.gradle section of the Module in question:

implementation("Com. Squareup. Okhttp3: okhttp: 4.3.1." ")
Copy the code

Synchronize after adding.

3 Basic steps to use Okhttp

  • Get the OkHttpClient object (or the OkHttpClient.Builder object)

    OkHttpClient okHttpClient=new OkHttpClient();
    / * or * /
    OkHttpClient.Builder okHttpClientBuilder=new OkHttpClient.Builder();
    Copy the code
  • To construct the Request

    Request.Builder builder=new Request.Builder();
    /*****get request - Request header URL*****/
    Request request=builder.get().url(mBaseUrl+"Requested content").build();
    
    /***** Post request - Request body *****/
    RequestBody requestBody=RequestBody.create(MediaType.parse("text/plain; charset=utf-8"), "Json data content");
    / * or * /
    RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
    / * or * /
    FormBody requestBody = new FormBody  //FormBody extends RequestBody
                    .Builder()
                    .add("usename"."zqq_post")
                    .add("password"."123456").build(); Request Request = builder.url(mBaseUrl + server name).post(requestBody).build();Copy the code
  • Encapsulate Request as Call

    private void executeRequest(Request request) throws IOException {
        Call call=okHttpClientBuilder.build().newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                L.e("onFailure" +e.getMessage());
                e.printStackTrace();
            }
    
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                L.e("onResponse:");
                final String res=response.body().string();
                L.e(res);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run(a) {
                       /****** Operations on client elements ******/}}); }}); }Copy the code
  • Execute the call

    executeRequest(request);
    Copy the code

4 sessions and cookies

  • Function: Records a series of states

  • The differences are as follows: Session is recorded on the server and cookie is recorded on the client

  • Sessions solve the problem of associating different HTTP requests, making them related

  • Implementation of session tracking

    In the client, I need to assign the CookieJar for

    okHttpClientBuilder.cookieJar(new PersistenceCookieJar());
    Copy the code

The encapsulated interfaces are as follows:

public class PersistenceCookieJar implements CookieJar {
    List<Cookie> cache = new ArrayList<>();
    // The Http request ends with a Cookie in Response
    @Override
    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
        // Cache cookies in memory
        cache.addAll(cookies);
    }
    //Http sends a callback before sending a Request
    @Override
    public List<Cookie> loadForRequest(HttpUrl url) {
        // An expired Cookie
        List<Cookie> invalidCookies = new ArrayList<>();
        // A valid Cookie
        List<Cookie> validCookies = new ArrayList<>();

        for (Cookie cookie : cache) {

            if (cookie.expiresAt() < System.currentTimeMillis()) {
                // Determine whether it expires
                invalidCookies.add(cookie);
            } else if (cookie.matches(url)) {
                // Match Cookie to URLvalidCookies.add(cookie); }}// Remove expired cookies from the cache
        cache.removeAll(invalidCookies);
        // Return List
      
        for Request to set
      
        returnvalidCookies; }};Copy the code

Meanwhile, on the server side, I can get the corresponding sessionId:

request.getSession.getId();
Copy the code

5 Common Problems

  • Android 6.0+ dynamic permissions issues

In addition to declaring permissions in the AndroidManifest, you need to get them dynamically using the following code

public void accessPermission(a){
        if (Build.VERSION.SDK_INT >= 23) {
            int REQUEST_CODE_CONTACT = 101;
            String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
            // Verify whether permissions are granted
            for (String str : permissions) {
                if (this.checkSelfPermission(str) ! = PackageManager.PERMISSION_GRANTED) {// Request permission
                    this.requestPermissions(permissions, REQUEST_CODE_CONTACT);
                    return;
                }}}}
Copy the code