下载okhttp,并导入自己工程

下载okhttp,并导入自己工程
okhttp 简介

OkHttp 是一套处理 HTTP 网络请求的依赖库,由 Square 公司设计研发并开源,目前可以在 Java 和 Kotlin 中使用。对于 Android App 来说,OkHttp 现在几乎已经占据了所有的网络请求操作,RetroFit + OkHttp 实现网络请求似乎成了一种标配。因此它也是每一个 Android 开发工程师的必备技能,了解其内部实现原理可以更好地进行功能扩展、封装以及优化。

okhttp 导入自己的工程

平常我们使用okhttp 是直接使用grable 依赖的方式倒入工程

implementation("com.squareup.okhttp3:okhttp:4.10.0")

之前查看源码,也是直接通过工程点击查看,发现有些不方便,比如,我想在源码中添加些代码 发现,代码都是只读的如:
在这里插入图片描述
那么我们怎么能添加我们自己的代码呢?这就需要以工程依赖的方式倒入okhttp的源码

step1: 下载okhttp 源码

源码地址:https://github.com/square/okhttp
可以直接下载zip包,或者通过git clone 方式

step2: 通过android studio 打开工程

1、android studio 版本尽量使用最新的
2、注意自己使用的jdk 版本,需要和源码中的是一样的,否则会报错
导入后效果:
在这里插入图片描述

step4: 创建android Application 工程

在这里插入图片描述

在这里插入图片描述
创建工程的过程后,编译,可能会报错:

The 'java' plugin has been applied, but it is not compatible with the Android plugins.

需要在:
okhttp/build.gradle.kts 下添加 :

if (project.name == "myokhttpapplication") return@subprojects
//myokhttpapplication  为你的功能

在这里插入图片描述
完成代码:

import com.vanniktech.maven.publish.MavenPublishBaseExtension
import com.vanniktech.maven.publish.SonatypeHost
import groovy.util.Node
import groovy.util.NodeList
import java.net.URL
import kotlinx.validation.ApiValidationExtension
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSnifferExtension

buildscript {
  dependencies {
    classpath(libs.gradlePlugin.dokka)
    classpath(libs.gradlePlugin.kotlin)
    classpath(libs.gradlePlugin.androidJunit5)
    classpath(libs.gradlePlugin.android)
    classpath(libs.gradlePlugin.graal)
    classpath(libs.gradlePlugin.bnd)
    classpath(libs.gradlePlugin.shadow)
    classpath(libs.gradlePlugin.animalsniffer)
    classpath(libs.gradlePlugin.errorprone)
    classpath(libs.gradlePlugin.spotless)
    classpath(libs.gradlePlugin.mavenPublish)
    classpath(libs.gradlePlugin.binaryCompatibilityValidator)
  }

  repositories {
    mavenCentral()
    gradlePluginPortal()
    google()
  }
}

allprojects {
  group = "com.squareup.okhttp3"
  version = "5.0.0-SNAPSHOT"

  repositories {
    mavenCentral()
    google()
  }

  tasks.create("downloadDependencies") {
    description = "Download all dependencies to the Gradle cache"
    doLast {
      for (configuration in configurations) {
        if (configuration.isCanBeResolved) {
          configuration.files
        }
      }
    }
  }

  normalization {
    runtimeClasspath {
      metaInf {
        ignoreAttribute("Bnd-LastModified")
      }
    }
  }
}

/** Configure building for Java+Kotlin projects. */
subprojects {
  val project = this@subprojects
  if (project.name == "okhttp-bom") return@subprojects
  if (project.name == "okhttp-android") return@subprojects
//  添加工程 
  if (project.name == "myokhttpapplication") return@subprojects
  if (project.name == "android-test") return@subprojects
  if (project.name == "regression-test") return@subprojects

  apply(plugin = "checkstyle")
  apply(plugin = "ru.vyarus.animalsniffer")
  apply(plugin = "biz.aQute.bnd.builder")

  tasks.withType<JavaCompile> {
    options.encoding = Charsets.UTF_8.toString()
  }

  configure<JavaPluginExtension> {
    toolchain {
      languageVersion.set(JavaLanguageVersion.of(11))
    }
  }

  tasks.withType<Checkstyle>().configureEach {
    exclude("**/CipherSuite.java")
  }

  val checkstyleConfig: Configuration by configurations.creating
  dependencies {
    checkstyleConfig(rootProject.libs.checkStyle) {
      isTransitive = false
    }
  }

  configure<CheckstyleExtension> {
    config = resources.text.fromArchiveEntry(checkstyleConfig, "google_checks.xml")
    toolVersion = rootProject.libs.versions.checkStyle.get()
    sourceSets = listOf(project.sourceSets["main"])
  }

  // Animal Sniffer confirms we generally don't use APIs not on Java 8.
  configure<AnimalSnifferExtension> {
    annotation = "okhttp3.internal.SuppressSignatureCheck"
    sourceSets = listOf(project.sourceSets["main"])
  }

  val signature: Configuration by configurations.getting
  dependencies {
    signature(rootProject.libs.signature.android.apilevel21)
    signature(rootProject.libs.codehaus.signature.java18)
  }

  tasks.withType<KotlinCompile> {
    kotlinOptions {
      jvmTarget = JavaVersion.VERSION_1_8.toString()
      freeCompilerArgs = listOf(
        "-Xjvm-default=all",
      )
    }
  }

  val platform = System.getProperty("okhttp.platform", "jdk9")
  val testJavaVersion = System.getProperty("test.java.version", "11").toInt()

  val testRuntimeOnly: Configuration by configurations.getting
  dependencies {
    testRuntimeOnly(rootProject.libs.junit.jupiter.engine)
    testRuntimeOnly(rootProject.libs.junit.vintage.engine)
  }

  tasks.withType<Test> {
    useJUnitPlatform()
    jvmArgs = jvmArgs!! + listOf(
      "-Dokhttp.platform=$platform",
      "-XX:+HeapDumpOnOutOfMemoryError"
    )

    val javaToolchains = project.extensions.getByType<JavaToolchainService>()
    javaLauncher.set(javaToolchains.launcherFor {
      languageVersion.set(JavaLanguageVersion.of(testJavaVersion))
    })

    maxParallelForks = Runtime.getRuntime().availableProcessors() * 2
    testLogging {
      exceptionFormat = TestExceptionFormat.FULL
    }

    systemProperty("okhttp.platform", platform)
    systemProperty("junit.jupiter.extensions.autodetection.enabled", "true")
  }

  if (platform == "jdk8alpn") {
    // Add alpn-boot on Java 8 so we can use HTTP/2 without a stable API.
    val alpnBootVersion = alpnBootVersion()
    if (alpnBootVersion != null) {
      val alpnBootJar = configurations.detachedConfiguration(
        dependencies.create("org.mortbay.jetty.alpn:alpn-boot:$alpnBootVersion")
      ).singleFile
      tasks.withType<Test> {
        jvmArgs = jvmArgs!! + listOf("-Xbootclasspath/p:${alpnBootJar}")
      }
    }
  } else if (platform == "conscrypt") {
    dependencies {
      testRuntimeOnly(rootProject.libs.conscrypt.openjdk)
    }
  } else if (platform == "openjsse") {
    dependencies {
      testRuntimeOnly(rootProject.libs.openjsse)
    }
  }

  tasks.withType<JavaCompile> {
    sourceCompatibility = JavaVersion.VERSION_1_8.toString()
    targetCompatibility = JavaVersion.VERSION_1_8.toString()
  }
}

/** Configure publishing and signing for published Java and JavaPlatform subprojects. */
subprojects {
  tasks.withType<DokkaTask>().configureEach {
    dokkaSourceSets.configureEach {
      reportUndocumented.set(false)
      skipDeprecated.set(true)
      jdkVersion.set(8)
      perPackageOption {
        matchingRegex.set("okhttp3\\.internal.*")
        suppress.set(true)
      }
      perPackageOption {
        matchingRegex.set("mockwebserver3\\.internal.*")
        suppress.set(true)
      }
      if (project.file("Module.md").exists()) {
        includes.from(project.file("Module.md"))
      }
      externalDocumentationLink {
        url.set(URL("https://square.github.io/okio/2.x/okio/"))
        packageListUrl.set(URL("https://square.github.io/okio/2.x/okio/package-list"))
      }
    }
    if (name == "dokkaGfm") {
      outputDirectory.set(file("${rootDir}/docs/4.x"))
    }
  }

  plugins.withId("com.vanniktech.maven.publish.base") {
    val publishingExtension = extensions.getByType(PublishingExtension::class.java)
    configure<MavenPublishBaseExtension> {
      publishToMavenCentral(SonatypeHost.S01)
      signAllPublications()
      pom {
        name.set(project.name)
        description.set("Square’s meticulous HTTP client for Java and Kotlin.")
        url.set("https://square.github.io/okhttp/")
        licenses {
          license {
            name.set("The Apache Software License, Version 2.0")
            url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
            distribution.set("repo")
          }
        }
        scm {
          connection.set("scm:git:https://github.com/square/okhttp.git")
          developerConnection.set("scm:git:ssh://git@github.com/square/okhttp.git")
          url.set("https://github.com/square/okhttp")
        }
        developers {
          developer {
            name.set("Square, Inc.")
          }
        }
      }

      // Configure the kotlinMultiplatform artifact to depend on the JVM artifact in pom.xml only.
      // This hack allows Maven users to continue using our original OkHttp artifact names (like
      // com.squareup.okhttp3:okhttp:5.x.y) even though we changed that artifact from JVM-only
      // to Kotlin Multiplatform. Note that module.json doesn't need this hack.
      val mavenPublications = publishingExtension.publications.withType<MavenPublication>()
      mavenPublications.configureEach {
        if (name != "jvm") return@configureEach
        val jvmPublication = this
        val kmpPublication = mavenPublications.getByName("kotlinMultiplatform")
        kmpPublication.pom.withXml {
          val root = asNode()
          val dependencies = (root["dependencies"] as NodeList).firstOrNull() as Node?
            ?: root.appendNode("dependencies")
          for (child in dependencies.children().toList()) {
            dependencies.remove(child as Node)
          }
          dependencies.appendNode("dependency").apply {
            appendNode("groupId", jvmPublication.groupId)
            appendNode("artifactId", jvmPublication.artifactId)
            appendNode("version", jvmPublication.version)
            appendNode("scope", "compile")
          }
        }
      }
    }
  }

  plugins.withId("binary-compatibility-validator") {
    configure<ApiValidationExtension> {
      ignoredPackages += "okhttp3.logging.internal"
      ignoredPackages += "mockwebserver3.internal"
      ignoredPackages += "okhttp3.internal"
      ignoredPackages += "mockwebserver3.junit5.internal"
      ignoredPackages += "okhttp3.brotli.internal"
      ignoredPackages += "okhttp3.sse.internal"
      ignoredPackages += "okhttp3.tls.internal"
    }
  }
}

tasks.wrapper {
  distributionType = Wrapper.DistributionType.ALL
}

step5: 以工程依赖的方式引入okhttp

在这里插入图片描述
完整代码:

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.example.myokhttpapplication"
    compileSdk = 32

    defaultConfig {
        applicationId = "com.example.myokhttpapplication"
        minSdk = 21
        targetSdk = 32
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.7.0")
    implementation("androidx.appcompat:appcompat:1.4.1")
    implementation("com.google.android.material:material:1.5.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.3")
    //   添加工程依赖
    implementation(project(mapOf("path" to ":okhttp-android")))
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.3")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
}

step6: 添加测试代码
package com.example.myokhttpapplication

import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import java.nio.charset.Charset
import java.nio.charset.UnsupportedCharsetException
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okio.Buffer
import okio.BufferedSource

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<View>(R.id.send_request).setOnClickListener{
          Thread(Runnable {
            var client = OkHttpClient()
            val request: Request = Request.Builder()
              .url("https://api.github.com/gists/c2a7c39532239ff261be")
              .build()
            val response: Response = client.newCall(request).execute()
            if (!response.isSuccessful) {
                Log.i("zhao","请求失败")
            }
            var bodyStrRespon = ""
            val source: BufferedSource =  response.body.source()
            source.request(Long.MAX_VALUE)
            val buffer: Buffer = source.buffer
            var charset: Charset =  Charset.forName("UTF-8")
            val contentType: MediaType? = response.body.contentType()
            if (contentType != null) {
              try {
                charset = contentType.charset(Charset.forName("UTF-8"))!!
              } catch (e: UnsupportedCharsetException) {
                e.printStackTrace()
              }
            }
            bodyStrRespon = buffer.clone().readString(charset)
            bodyStrRespon = if (bodyStrRespon === "") "无响应Body" else bodyStrRespon
            Log.i("zhao","请求结果"+bodyStrRespon)
          }).start()
        }
    }
}

哈哈哈,到这里就完结了

参考资料:

https://github.com/square/okhttp

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值