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

??前言:由于最近的工作環(huán)境是處于內(nèi)網(wǎng)環(huán)境下,所以沒法使用公開的網(wǎng)絡(luò),導(dǎo)致了無法正常使用android studio和下載三方庫,為此折騰了很久,踩了許多坑,網(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ì)引用第三方庫,我們這里試一下,添加一個(gè)依賴,如下
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'
??然后點(diǎn)擊sync now,嗯,沒有問題,然后點(diǎn)擊run app,提示錯(cuò)誤了


gradle配置3

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

二 下載官方庫和普通三方庫

??倉庫里面的庫分為倆種類,一種是類似Glide,Rxjava,BaseRecyclerViewAdapterHelper這種第三方庫,另一種是官方庫,比如RecyclerView,F(xiàn)ragment這種,倆種庫放在一起,但是獲取方式卻不一樣,下面分別介紹:

??獲取官方庫

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

offline-gmaven-stable

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

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

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

??獲取普通三方庫

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

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

SnakeBar示意圖

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

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è)文件,有的庫最多會(huì)有四個(gè)文件,分別是.aar,.pom,-javadoc.jar,sources.jar結(jié)尾的文件,至此獲取到一個(gè)庫的源文件。
??方法二:公網(wǎng)設(shè)備內(nèi)復(fù)制粘貼
??除了從倉庫下載,我們還可以從公網(wǎng)安裝了android studio的機(jī)器里面復(fù)制已經(jīng)添加依賴并且已經(jīng)下載文件的項(xiàng)目里面復(fù)制我們需要的庫,步驟如下,我們在三方庫的位置找到我們需要用的庫:
??Mac電腦:找到路徑/Users/mac/.gradle/caches/modules-2/files-2.1
??window電腦:同理,在用戶盤(一般是C盤),下面找到用戶,然后進(jìn)去,再看到用戶名稱,再進(jìn)去即可找到.gradle,后面路徑和mac一致,然后可以看到很多已經(jīng)下載好的庫在里面,如下圖
三方庫集合列表

??找到我們需要庫,打開可以看到


三方庫詳情

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

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

三 配置本地倉庫

??到這里需要說一下倉庫的概念了,正常我們在添加依賴后,點(diǎn)擊sync now后,android studio就會(huì)從倉庫下載我們添加引用的倉庫,常用的倉庫有倆個(gè)google和jcenter,但是內(nèi)網(wǎng)沒法通過網(wǎng)絡(luò)直接下載,所以我們就需要配置一個(gè)本地倉庫。

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

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

??普通三方庫
??用com.nispok.slidingtabs.1.0.0這個(gè)庫舉例,把已經(jīng)下載好的這個(gè)庫的幾個(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,和我們上面的官方庫文件夾嵌套模式保持一摸一樣,如果官方庫已經(jīng)建立了某些文件夾,普通三方庫就不用建,此時(shí)本地庫里面也就有普通三方庫。
??有的同學(xué)覺得這種一層層的建立文件夾太復(fù)雜了,后面會(huì)提供一個(gè)工具,參考第四模塊,學(xué)到了什么里面的公網(wǎng)設(shè)備三方庫代碼轉(zhuǎn)換。
??總而言之,我們獲得了需要用到的官方庫和第三方庫,通過合理的文件夾嵌套放在了指定的位置,這里就是F:android/repo文件夾下

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

??誰知道我踩了多少坑?。??

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

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

四 學(xué)到了什么?

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

??上面我們搭建了一個(gè)本地倉庫repo,但實(shí)際上我們還有默認(rèn)的,也就是google和jcenter倉庫,我們可以打開Android studio,打開Settings,找到Build,Execution,Deployment目錄下的Remote Jar Repositories,如下圖


Remote Jar Repositories

??這里展示了我們使用庫全部會(huì)被索引的倉庫,如果所有的倉庫都沒有找到我們需要用到的類或組件,就會(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群: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)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,582評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,540評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,801評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,223評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評(píng)論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,442評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,976評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,800評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,996評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評(píng)論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,233評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評(píng)論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,702評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,991評(píng)論 2 374

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