內(nèi)網(wǎng)搭建Android環(huán)境

??前言:由于最近的工作環(huán)境是處于內(nèi)網(wǎng)環(huán)境下,所以沒法使用公開的網(wǎng)絡(luò)鸭巴,導(dǎo)致了無法正常使用android studio和下載三方庫(kù)馅巷,為此折騰了很久,踩了許多坑淹仑,網(wǎng)上找的很多資料不僅少丙挽,而且不全,很難解決匀借,最后得出的經(jīng)驗(yàn)希望能夠幫助遇到同樣問題的同學(xué)颜阐。

??關(guān)鍵字:Android Studio,Android SDK,offline-gmaven-stable,gradle,maven
??內(nèi)網(wǎng):可以理解成斷網(wǎng)吓肋,即不能連接公網(wǎng)凳怨,但是用網(wǎng)線連接的設(shè)備之間可以通信。

??由于搭建的流程比較復(fù)雜,我這里用一幅圖展示肤舞,給大家梳理一下紫新。


內(nèi)網(wǎng)配置Android環(huán)境

一 安裝Android Studio配置SDK

??安裝后提示需要配置sdk路徑,如圖

提示沒有sdk.png

??我們的sdk可以從我們公網(wǎng)中的設(shè)備里面復(fù)制過來李剖,然后我們點(diǎn)擊右下角芒率,找到配置sdk路徑的位置,如圖

配置sdk1

??點(diǎn)擊edit篙顺,選擇我們之前獲取到的sdk的位置
??正常情況下sdk是可以直接下載偶芍,因?yàn)檫@是內(nèi)網(wǎng)環(huán)境,所以我們只能直接從在公網(wǎng)環(huán)境的電腦中把sdk復(fù)制過來進(jìn)行使用德玫,公網(wǎng)中的sdk放置的位置同樣參考圖-配置sdk1即可找到匪蟀。
??如下圖
配置sdk2

??點(diǎn)擊確認(rèn)之后,成功之后如下圖
配置sdk3

??配置好sdk后宰僧,點(diǎn)擊運(yùn)行材彪,依然會(huì)提示錯(cuò)誤,告訴我們沒有當(dāng)前gradle版本琴儿,如圖
gradle配置1

??當(dāng)前使用的gradle版本是6.5段化,會(huì)提示錯(cuò)誤
gradle配置1

??需要注意的是android studio中的gradle涉及倆個(gè)概念,一個(gè)gradle造成,一個(gè)是gradle插件穗泵,分別都有不同的版本。
??gradle的版本配置在gradle-wrapper.properties文件中谜疤,形如

??gradle插件的版本配置在build.gradle文件中,形如

??gradle版本和gradle插件之間的對(duì)應(yīng)關(guān)系现诀,一個(gè)項(xiàng)目中的gradle和gradle插件需要相互對(duì)應(yīng)

??更多的可以參考:Android Gradle 插件版本說明
??小插曲結(jié)束夷磕,我們gradle依然可以用我們公網(wǎng)中的設(shè)備,找到gradle仔沿,然后復(fù)制到內(nèi)網(wǎng)機(jī)器坐桩,從android studio的設(shè)置中可以查看gradle的路徑配置,如圖
gradle路徑配置

??如圖封锉,默認(rèn)在用戶盤的根目錄下绵跷,我們把.gradle文件中的內(nèi)容全部復(fù)制出來,里面文件形如

.gradle文件夾目錄

??caches文件里面存儲(chǔ)了就是gradle解壓后的版本成福,我這里的gradle的版本寫的是

distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip

??我們查看caches里面有什么

caches文件夾目錄

??沒錯(cuò)碾局,有文件夾6.1.1,里面存儲(chǔ)正是我們使用的gradle版本奴艾,還有其余的版本净当,都是其他的項(xiàng)目創(chuàng)建的時(shí)候緩存下來的,所以隨著項(xiàng)目的越來越多,gradle版本的變化像啼,caches文件也會(huì)越來越大俘闯。
如果不想用這個(gè)gradle版本的同學(xué),可以下載其他版本忽冻,前往Gradle下載地址
??示意圖
Gradle版本

??接下來我們用內(nèi)網(wǎng)機(jī)器配置下復(fù)制過來的gradle路徑真朗,然后觀察下caches里面有哪些可用的版本,然后更改一下gradle-wrapper.properties文件內(nèi)的gradle版本僧诚,順便把build.gradle文件里面的gradle插件版本更改成對(duì)應(yīng)的版本遮婶,
??我這里gradle插件版本寫的是

classpath "com.android.tools.build:gradle:3.1.0"

??然后點(diǎn)擊sync now
??不出意外,到這里項(xiàng)目就是可運(yùn)行狀態(tài)了
??點(diǎn)擊run app振诬,可以正常安裝運(yùn)行

??但是正常情況我們都會(huì)引用第三方庫(kù)蹭睡,我們這里試一下,添加一個(gè)依賴,如下
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'
??然后點(diǎn)擊sync now赶么,嗯肩豁,沒有問題,然后點(diǎn)擊run app辫呻,提示錯(cuò)誤了


gradle配置3

??大致意思就是找不到這個(gè)庫(kù)清钥,當(dāng)然了,在內(nèi)網(wǎng)環(huán)境下放闺,根本沒法下載祟昭,自然沒有這個(gè)庫(kù),我們看看怎么把這個(gè)庫(kù)放進(jìn)來怖侦。

二 下載官方庫(kù)和普通三方庫(kù)

??倉(cāng)庫(kù)里面的庫(kù)分為倆種類篡悟,一種是類似Glide,Rxjava匾寝,BaseRecyclerViewAdapterHelper這種第三方庫(kù)搬葬,另一種是官方庫(kù),比如RecyclerView艳悔,F(xiàn)ragment這種急凰,倆種庫(kù)放在一起,但是獲取方式卻不一樣猜年,下面分別介紹:

??獲取官方庫(kù)

??我們來到官網(wǎng)offline-gmaven-stable
??還是官方聰明抡锈,都提供了一個(gè)現(xiàn)成的庫(kù)讓我們直接下載使用,我們找到

offline-gmaven-stable

??然后點(diǎn)擊下載
offline-gmaven-stable下載頁

??文件大概有3個(gè)G左右乔外,下載好之后解壓床三,里面有倆個(gè)壓縮包,??暫時(shí)只用到gmaven-stable杨幼,里面就是我們需要的官方庫(kù)勿璃,我們可以隨便點(diǎn)一個(gè)進(jìn)去看看,如圖
官方庫(kù)實(shí)例

??最多就四個(gè)文件類型,好了补疑,到這里我們獲取到了官方庫(kù)歧沪。

??獲取普通三方庫(kù)

??有倆種方法,方法二也可以用來獲取官方庫(kù)

??方法一:從中心倉(cāng)庫(kù)下載
??中心倉(cāng)庫(kù)有很多莲组,maven其中一個(gè)網(wǎng)址地址:maven倉(cāng)庫(kù)
??直接在上面搜需要使用的庫(kù)的名稱诊胞,我用上面的BaseRecyclerViewAdapterHelper去搜,沒有搜到锹杈,可能是這個(gè)庫(kù)不在這個(gè)倉(cāng)庫(kù)撵孤,因?yàn)檫€有很多其他倉(cāng)庫(kù),我為了演示隨便搜另一個(gè)庫(kù)Snackbar竭望,點(diǎn)擊搜索如下:

SnakeBar示意圖

??有很多匹配的邪码,正常情況下我們應(yīng)該怎么選呢,我們用BaseRecyclerViewAdapterHelper 這個(gè)庫(kù)作示范咬清,全名為

com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50

??實(shí)際上可以拆成三部分闭专,

group ID:com.github.CymChad
Artifact Id : BaseRecyclerViewAdapterHelper:
Version : 2.9.50

??這樣我們就知道從下面的列表中選擇哪一個(gè)了,這里我們就隨便選一個(gè)
??點(diǎn)擊進(jìn)去旧烧,如下圖

SnakeBar下載頁

??我們點(diǎn)擊右邊的download按鈕影钉,可能會(huì)提示如下
SnakeBar下載類型

??我們?nèi)肯螺d下來,就是三個(gè)文件掘剪,有的庫(kù)最多會(huì)有四個(gè)文件平委,分別是.aar,.pom,-javadoc.jar,sources.jar結(jié)尾的文件夺谁,至此獲取到一個(gè)庫(kù)的源文件廉赔。
??方法二:公網(wǎng)設(shè)備內(nèi)復(fù)制粘貼
??除了從倉(cāng)庫(kù)下載,我們還可以從公網(wǎng)安裝了android studio的機(jī)器里面復(fù)制已經(jīng)添加依賴并且已經(jīng)下載文件的項(xiàng)目里面復(fù)制我們需要的庫(kù)匾鸥,步驟如下昂勉,我們?cè)谌綆?kù)的位置找到我們需要用的庫(kù):
??Mac電腦:找到路徑/Users/mac/.gradle/caches/modules-2/files-2.1
??window電腦:同理,在用戶盤(一般是C盤)扫腺,下面找到用戶,然后進(jìn)去村象,再看到用戶名稱笆环,再進(jìn)去即可找到.gradle,后面路徑和mac一致,然后可以看到很多已經(jīng)下載好的庫(kù)在里面厚者,如下圖
三方庫(kù)集合列表

??找到我們需要庫(kù)躁劣,打開可以看到


三方庫(kù)詳情

??可以看到里面也有四個(gè)不同后綴的文件,但是和我們方法1下載后不一樣的是库菲,這些文件分別在一些命名長(zhǎng)長(zhǎng)的文件夾里面账忘,這些文件夾的名稱是通過里面文件計(jì)算SHA1得到的,但是這里不影響,我們把里面的四個(gè)文件復(fù)制出來即可鳖擒。

??通過方法一溉浙,二獲取普通三方庫(kù)文件的方法到此結(jié)束。

三 配置本地倉(cāng)庫(kù)

??到這里需要說一下倉(cāng)庫(kù)的概念了蒋荚,正常我們?cè)谔砑右蕾嚭蟠粱c(diǎn)擊sync now后,android studio就會(huì)從倉(cāng)庫(kù)下載我們添加引用的倉(cāng)庫(kù)期升,常用的倉(cāng)庫(kù)有倆個(gè)google和jcenter惊奇,但是內(nèi)網(wǎng)沒法通過網(wǎng)絡(luò)直接下載,所以我們就需要配置一個(gè)本地倉(cāng)庫(kù)播赁。

步驟一 把庫(kù)放在指定位置
??具體操作:我們可以在本地磁盤建一個(gè)文件夾颂郎,里面用來存儲(chǔ)我們需要添加依賴,我這里建在了F盤下的android文件下容为,起名repo乓序。

??官方庫(kù)
??我們直接將之前下載的gmaven-stable文件里面的內(nèi)容全部復(fù)制進(jìn)repo里面即可,即本地庫(kù)有了官方庫(kù)舟奠。

??普通三方庫(kù)
??用com.nispok.slidingtabs.1.0.0這個(gè)庫(kù)舉例竭缝,把已經(jīng)下載好的這個(gè)庫(kù)的幾個(gè)文件放進(jìn)去,不過不是直接放到repo里面進(jìn)去沼瘫,需要按照次序抬纸,建立三個(gè)文件吕粹,先建com文件夾樟澜,然后進(jìn)去,再建nispok文件夾稽莉,再建slidingtabs文件夾膜蛔,再進(jìn)去坛猪,再建立文件夾1.0.0,再進(jìn)去皂股,最后再把三個(gè)文件放進(jìn)去墅茉,細(xì)心的同學(xué)注意到了,最后的文件夾嵌套就是com/nispok/slidingtabs/1.0.0呜呐,如果是像我們用的BaseRecyclerViewAdapterHelper就斤,那文件夾嵌套就是com/github/CymChad/BaseRecyclerViewAdapterHelper/2.9.50,和我們上面的官方庫(kù)文件夾嵌套模式保持一摸一樣蘑辑,如果官方庫(kù)已經(jīng)建立了某些文件夾洋机,普通三方庫(kù)就不用建,此時(shí)本地庫(kù)里面也就有普通三方庫(kù)洋魂。
??有的同學(xué)覺得這種一層層的建立文件夾太復(fù)雜了绷旗,后面會(huì)提供一個(gè)工具喜鼓,參考第四模塊,學(xué)到了什么里面的公網(wǎng)設(shè)備三方庫(kù)代碼轉(zhuǎn)換衔肢。
??總而言之庄岖,我們獲得了需要用到的官方庫(kù)和第三方庫(kù),通過合理的文件夾嵌套放在了指定的位置膀懈,這里就是F:android/repo文件夾下

步驟二 android studio添加本地庫(kù)
??具體操作:需要更改我們項(xiàng)目的配置顿锰,找到整個(gè)項(xiàng)目的build.gralde,正常情況下启搂,allprojects里面只有g(shù)oogle()和jcenter()硼控,但是這里我們獲取到了庫(kù)并按指定方式放了進(jìn)去,得到了本地庫(kù)胳赌,我們的gradle里面就需要添加我們這個(gè)本地庫(kù)牢撼,在google()或jcenter()后面添加 maven{ url 'file:/F:/android/repo'},即可,點(diǎn)擊sync now疑苫,本地庫(kù)就添加成功了熏版,我們新建一個(gè)MyAdapter,發(fā)現(xiàn)就可以繼承BaseQuickAdapter這個(gè)第三方庫(kù)了捍掺,終于成功了撼短?

??誰知道我踩了多少坑!Mξ稹曲横?

??點(diǎn)擊run app,嘿嘿不瓶,又報(bào)錯(cuò)了禾嫉,如下圖


adapter報(bào)錯(cuò)

??錯(cuò)誤還是亂碼,氣人蚊丐,看下解決辦法
??第一步:Help—>Edit Custom VM Options


Edit Custom VM Options

??第二步:在打開的文件里(如果沒有熙参,就新建),增加 -Dfile.encoding=UTF-8


-Dfile.encoding=UTF-8

??第三步:重啟Android studio 就行麦备,對(duì)比下修復(fù)前和修復(fù)后

??好了孽椰,不亂碼了,看錯(cuò)誤提示是缺少v7包下的RecyclerView凛篙,那么問題來了黍匾,這android studio都什么版本了,還用什么v7鞋诗,解決辦法倆個(gè)

??方法1:提升引用的BaseRecyclerViewAdapterHelper的版本,使其引用的不再是v7下的包迈嘹,而是androidx下的包即可削彬,我用的就是這個(gè)方法全庸。
??方法2:下載v7包,按照上面的方法融痛,依次放到文件夾下壶笼,這個(gè)方法我沒試
然后接著運(yùn)行,可能會(huì)提示類似

program type already present:xxx.xxx.xx

??這樣的錯(cuò)誤雁刷,意思就是android和各種support的沖突覆劈,我們把項(xiàng)目完全轉(zhuǎn)成androidx即可,刪除build.gradle里面的各種的support包即可沛励,如果沒法刪除责语,勇士你可以不用androidx,把項(xiàng)目里面的androidx東西全部刪除目派,網(wǎng)上資料很多坤候,這里不做闡述。

??解決androidx和support的沖突后企蹭,可能依然會(huì)提示缺少其他庫(kù)白筹,這是因?yàn)槲覀円玫钠胀ǖ谌綆?kù)還引用了別的庫(kù),那怎么辦呢谅摄?
??還記得我們上面說的下載普通三方庫(kù)的方法么徒河,沒錯(cuò),自此開始缺少什么庫(kù)送漠,都重新拿過來顽照,再放進(jìn)repo這個(gè)本地倉(cāng)庫(kù)里面即可。
??還記得我們之前看見的下載的依賴包的幾個(gè)文件么螺男,分別是.aar棒厘,.pom,-javadoc.jar,sources.jar結(jié)尾的文件,我們打開.opm后綴的文件下隧,里面有該庫(kù)依賴的其他庫(kù)奢人,我們可以從這里查到并進(jìn)行下載或者如果本地已經(jīng)存在相關(guān)庫(kù),但是版本不對(duì)應(yīng)淆院,直接更改成本地庫(kù)的版本即可何乎。
??然后運(yùn)行可能依然會(huì)報(bào)一些關(guān)于主題找不到的錯(cuò),我這里是找不到的主題直接就不用了土辩,更多解決方法也沒做研究支救,到這里的,后續(xù)出現(xiàn)的問題已經(jīng)和本文要解決的中心問題無關(guān)拷淘,所以這里不作更多闡述各墨,等到全部庫(kù)都放進(jìn)去完畢之后,最終我們即使把build.gradle里面的allprojects下面的google和jcenter刪除發(fā)現(xiàn)也能正常運(yùn)行了(天啦~終于結(jié)束了~)启涯。

??慢著贬堵,你到這里解決了問題恃轩,但是你真的理解了么,下面幾個(gè)問題你能回答出來么黎做?

四 學(xué)到了什么叉跛?

??問題一 公網(wǎng)設(shè)備三方庫(kù)代碼如何轉(zhuǎn)換成可使用的
??上面說了配置本地倉(cāng)庫(kù)中的獲取普通三方庫(kù),除了從官網(wǎng)下載庫(kù)蒸殿,然后通過手動(dòng)建立文件夾的方式筷厘,還可以從公網(wǎng)的設(shè)備中復(fù)制過來,具體路徑在上面的獲取普通三方庫(kù)中已經(jīng)作了介紹宏所,但是我們發(fā)現(xiàn)看到的文件夾形式總是com.github.xxxx類似這種酥艳,但是我們自定義的倉(cāng)庫(kù)里面的文件是不可以這樣直接使用的,需要文件夾一層層嵌套才可以正常使用楣铁,這里提供一個(gè)工具玖雁,代碼如下:

/**
 * 將Android中使用的gradle緩存目錄中的jar包重新處理路徑,用于內(nèi)網(wǎng)離線構(gòu)建
 **/

public class CopyTool {

    static String path = "C:/Users/Administrator/.gradle/caches/modules-2/files-2.1";

    static String stopName = "files-2.1";


    public static void main(String[] args) {
        System.out.println("Begin to copy");
        processDotForld();
        copyToLastForld();
        System.out.println("Copy finished");
    }

    /**
     * 處理文件夾中帶點(diǎn)好的盖腕。赫冬;例如:D:/test/com.ifind.android/
     */
    public static void processDotForld() {
        File file = new File(path);
        if (file.exists()) {
            LinkedList<File> list = new LinkedList<>();
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                File file2 = files[I];
                if (file2.isDirectory()) {
                    //文件夾
                    File desFile = creatforld(file2);
                    copyFileToDes(file2, desFile);
                } else {
                    //文件//目前不存在
                }
            }
        }
    }

    /**
     * 文件夾拷貝
     *
     * @param source
     * @param des
     */
    public static void copyFileToDes(File source, File des) {
        try {
            copyDir(source.getPath(), des.getPath());
        } catch (Exception e) {
        }
    }

    /**
     * 文件夾拷貝
     *
     * @param sourcePath
     * @param newPath
     * @throws IOException
     */
    public static void copyDir(String sourcePath, String newPath) throws IOException {
        File file = new File(sourcePath);
        String[] filePath = file.list();

        if (!(new File(newPath)).exists()) {
            (new File(newPath)).mkdir();
        }

        for (int i = 0; i < filePath.length; i++) {
            if ((new File(sourcePath + file.separator + filePath[i])).isDirectory()) {
                copyDir(sourcePath + file.separator + filePath[i], newPath
                        + file.separator + filePath[I]);
            }

            if (new File(sourcePath + file.separator + filePath[i]).isFile()) {
                copyFile(sourcePath + file.separator + filePath[i], newPath + file.separator + filePath[I]);
            }

        }
    }


    public static void copyFile(String oldPath, String newPath) throws IOException {
        File oldFile = new File(oldPath);
        File file = new File(newPath);
        FileInputStream in = new FileInputStream(oldFile);
        FileOutputStream out = new FileOutputStream(file);

        byte[] buffer = new byte[2097152];

        DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(out));

        int length;
        while ((length = dis.read(buffer)) != -1) {
            dos.write(buffer, 0, length);
        }
        dos.flush();
        dos.close();
        dis.close();
    }


    /**
     * 創(chuàng)建文件夾
     *
     * @param file
     */
    public static File creatforld(File file) {
        String path = file.getAbsolutePath();
        if (path != null) {
            String temp = "files-2.1";
            temp = stopName;
            String temS[] = path.split(temp);

            if (temS != null && temS.length == 2) {
                String firstName = temS[0];
                String dotName = temS[1];
                if (dotName != null) {
                    String[] lasts = dotName.split("\\.");
                    int count = lasts.length;
                    if (count < 2) {
                        return null;
                    }
                    String pathNew = firstName + temp;
                    for (int i = 0; i < count; i++) {
                        if (i == 0) {
                            pathNew = pathNew + lasts[I];
                        } else {
                            pathNew = pathNew + "\\" + lasts[I];
                        }
                    }
                    if (pathNew != null && !pathNew.equals("")) {
                        File fileForld = new File(pathNew);
                        if (!fileForld.exists()) {
                            fileForld.mkdirs();
                        }
                        return fileForld;
                    }
                }
            }
        }
        return null;
    }


    public static ArrayList<File> getFile(File file) {
        ArrayList<File> list = new ArrayList<>();
        if (file.isDirectory()) {
            File[] filesTemp = file.listFiles();
            for (int i = 0; i < filesTemp.length; i++) {
                ArrayList<File> result = getFile(filesTemp[I]);
                list.addAll(result);
            }

        } else {
            list.add(file);
        }
        return list;
    }


    // 創(chuàng)建目錄
    public static boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            // 判斷目錄是否存在
            System.out.println("創(chuàng)建目錄失敗,目標(biāo)目錄已存在溃列!");
            return false;
        }
        if (!destDirName.endsWith(File.separator)) {
            // 結(jié)尾是否以"/"結(jié)束
            destDirName = destDirName + File.separator;
        }
        if (dir.mkdirs()) {
            // 創(chuàng)建目標(biāo)目錄
            System.out.println("創(chuàng)建目錄成功劲厌!" + destDirName);
            return true;
        } else {
            System.out.println("創(chuàng)建目錄失敗听隐!");
            return false;
        }
    }


    public static void copyToLastForld() {
        File file = new File(path);
        if (file.exists()) {
            LinkedList<File> list = new LinkedList<>();
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                File file2 = files[I];
                if (file2.isDirectory()) {
                    //文件夾
                    proceessForld(file2);
                } else {
                    //文件//目前不存在
                }
            }
        }
    }


    private static void proceessForld(File file) {
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            File file2 = files[I];
            if (file2.isDirectory()) {
                //文件夾
                proceessForld(file2);
            } else {
                //文件//目前不存在//判斷是否進(jìn)行拷貝
                try {
                    proceessFile(file2);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private static void proceessFile(File file) throws FileNotFoundException {
        if (file != null) {
            String path = file.getAbsolutePath();
            if (path != null) {
                String[] lasts = splitString(path);
                if (lasts != null && lasts.length > 0) {
                    int count = lasts.length;
                    String last = lasts[count - 1];
                    String last2 = lasts[count - 2];


                    if (last2 != null && last2.length() > 20) {
                        //拷貝到上一級(jí)目錄
                        String des = null;
                        if (count < 2) {
                            return;
                        }
                        for (int i = 0; i < count - 2; i++) {
                            if (i == 0) {
                                des = lasts[I];
                            } else {
                                des = des + "\\\\" + lasts[I];
                            }
                        }
                        String strParentDirectory = file.getParent();
                        File parentFile = new File(strParentDirectory);
                        strParentDirectory = parentFile.getParent() + "\\" + last;
                        copy(file, path, strParentDirectory);
                    } else {
                    }
                }
            }
        }
    }


    private static String[] splitString(String path) {
        String[] lasts = null;
        lasts = path.split("\\\\");
        int count = lasts.length;
        boolean isFirst = true;
        for (int i = 0; i < count; i++) {
            String str = lasts[I];
            if (str != null && str.contains(".")) {
                if (isFirst) {
                    isFirst = false;
                    System.out.println("\n\n\n\n");
                    System.out.println("path=" + path + "");
                }
                System.out.println("str=" + str + "");
            }
        }
        return lasts;
    }


    /**
     * copy動(dòng)作
     *
     * @param file
     * @param source
     * @param des
     * @throws FileNotFoundException
     */
    private static void copy(File file, String source, String des) throws FileNotFoundException {
        if (file != null) {
            FileInputStream fis = null;
            FileOutputStream fot = null;
            byte[] bytes = new byte[1024];
            int temp = 0;
            File desFile = new File(des);
            if (desFile.exists()) {
                return;
            }
            try {
                fis = new FileInputStream(file);
                fot = new FileOutputStream(desFile);
                while ((temp = fis.read(bytes)) != -1) {
                    fot.write(bytes, 0, temp);
                    fot.flush();


                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fot != null) {
                    try {
                        fot.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }


        }
    }


    private static String getContent(String content) {
        String str = content;
        if (content != null && content.length() > 4) {
            str = content.substring(0, 4);
        }
        return str;
    }

}

??我們可以上面的path改成我們的公網(wǎng)設(shè)備里面的三方庫(kù)路徑补鼻,然后點(diǎn)擊運(yùn)行,會(huì)把這些帶點(diǎn)號(hào)命名的文件夾拆分成嵌套形雅任,這樣我們就不用手動(dòng)就建立文件夾了风范。

問題二 Gradle安裝配置在什么位置,解壓后去哪了沪么?

??首先我們?nèi)ス倬W(wǎng)下載我們需要的版本硼婿,Gradle下載地址
??下載好之后我們可以放在本地路徑,還記得我們的gradle-wrapper.properties里面是什么樣子么禽车,如下

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

??最后一行就是配置我們Gradle版本的地方寇漫,實(shí)際上我們可以更改成我們本地路徑,例如我們下載了gradle-4.2.1-all.zip版本殉摔,放在了F盤的android文件夾下的gradle文件夾里面州胳,那這里我們就可以更改成

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=file:///F:/android/gradle/gradle-4.2.1-all.zip

??然后點(diǎn)擊sycn now,發(fā)現(xiàn)可以正常使用逸月,當(dāng)然還要注意和Gradle 插件的對(duì)應(yīng)栓撞,實(shí)際上點(diǎn)擊sync now就是解壓這個(gè)壓縮包,我么可以前往用戶C盤用戶名文件夾下的.gradle里面碗硬,看到caches文件夾瓤湘,里面就有我們剛剛解壓的Gradle捌归,所以這也是為什么我們內(nèi)網(wǎng)的設(shè)備直接從外網(wǎng)的設(shè)備把.Gradle下的文件全部復(fù)制過來就能使用的原因。

問題三 如何知道當(dāng)前項(xiàng)目使用庫(kù)是從什么地方來的

??上面我們搭建了一個(gè)本地倉(cāng)庫(kù)repo岭粤,但實(shí)際上我們還有默認(rèn)的,也就是google和jcenter倉(cāng)庫(kù)特笋,我們可以打開Android studio剃浇,打開Settings,找到Build猎物,Execution虎囚,Deployment目錄下的Remote Jar Repositories,如下圖


Remote Jar Repositories

??這里展示了我們使用庫(kù)全部會(huì)被索引的倉(cāng)庫(kù)蔫磨,如果所有的倉(cāng)庫(kù)都沒有找到我們需要用到的類或組件淘讥,就會(huì)報(bào)錯(cuò),就如我們上面說的RecyclerView找不到錯(cuò)誤一致
??在Remote Jar Repositories上面還有一個(gè)Gradle目錄堤如,如下圖


Gradle

??里面可以設(shè)置Gradle解壓后的目錄蒲列,這個(gè)一般不更改,還有Gradle版本的設(shè)置搀罢,可以指定是否使用gradle-wrapper.properties文件里面的配置或者手動(dòng)指定目錄和問題二效果一致蝗岖。

??前人種樹后人乘涼,這里提供參考的相關(guān)資料榔至,希望也能給大家一些幫助抵赢,如果依然不能解決,請(qǐng)私聊或移步Q群:561176094.

公司內(nèi)網(wǎng)離線環(huán)境搭建Android Studio
AndroidStudio中的內(nèi)網(wǎng)開發(fā)離線配置
Android 手動(dòng)下載Gradle的cache依賴包

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唧取,一起剝皮案震驚了整個(gè)濱河市铅鲤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌枫弟,老刑警劉巖邢享,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異媒区,居然都是意外死亡驼仪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門袜漩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绪爸,“玉大人,你說我怎么就攤上這事宙攻〉旎酰” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵座掘,是天一觀的道長(zhǎng)递惋。 經(jīng)常有香客問我柔滔,道長(zhǎng),這世上最難降的妖魔是什么萍虽? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任睛廊,我火速辦了婚禮,結(jié)果婚禮上杉编,老公的妹妹穿的比我還像新娘超全。我一直安慰自己,他們只是感情好邓馒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布嘶朱。 她就那樣靜靜地躺著,像睡著了一般光酣。 火紅的嫁衣襯著肌膚如雪疏遏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天救军,我揣著相機(jī)與錄音财异,去河邊找鬼。 笑死唱遭,一個(gè)胖子當(dāng)著我的面吹牛宝当,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胆萧,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼庆揩,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了跌穗?” 一聲冷哼從身側(cè)響起订晌,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚌吸,沒想到半個(gè)月后锈拨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡羹唠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年奕枢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佩微。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缝彬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哺眯,到底是詐尸還是另有隱情谷浅,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站一疯,受9級(jí)特大地震影響撼玄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜墩邀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一掌猛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧眉睹,春花似錦留潦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殖卑。三九已至站削,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孵稽,已是汗流浹背许起。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菩鲜,地道東北人园细。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像接校,于是被迫代替她去往敵國(guó)和親猛频。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容