Android控件之ImageView(二)

前言

在上一篇文章中森篷,我們講解了如何加載本地圖片徐钠,那么在實際項目中 ImageView 大多數(shù)使用場景是加載網(wǎng)絡(luò)圖片堂飞,網(wǎng)絡(luò)圖片其實就是存儲在服務(wù)器上的文件悔叽,我們需要從服務(wù)器獲取到文件的二進制輸入流 Inpustream 构韵,然后將其轉(zhuǎn)化為 ImageView 可以加載的 Bitmap 對象周蹭。實現(xiàn)網(wǎng)絡(luò)圖片的加載。

這篇文章我們通過使用原始的網(wǎng)絡(luò)連接和使用第三庫來簡單講解 ImageView 網(wǎng)絡(luò)圖片的加載疲恢。

  • 怎么使用原始方式加載網(wǎng)絡(luò)圖片凶朗?
  • 第三方網(wǎng)絡(luò)圖片加載庫與原始加載庫的對比?
  • 怎樣使用第三方網(wǎng)絡(luò)加載庫加載圖片显拳?

使用原始方式加載網(wǎng)絡(luò)圖片

先上代碼(主要分為三大步驟):

  • 1~6 : 從網(wǎng)絡(luò)獲取圖片棚愤。由于Android 系統(tǒng)規(guī)定網(wǎng)絡(luò)請求操作需要在子線程完成。主要是因為網(wǎng)絡(luò)請求屬于耗時操作杂数,如果在主線程發(fā)起網(wǎng)絡(luò)請求會導(dǎo)致主線程在網(wǎng)絡(luò)請求期間宛畦,無法及時響應(yīng)用戶的操作,
  • 7:利用在 Activity聲明的 Handler對象把在子線從網(wǎng)絡(luò)獲取到的 Bitmap 對象揍移,轉(zhuǎn)移到 UI 線程次和。
  • 8 : 更新UI
public class ImageNetActivity extends AppCompatActivity {

    /**
     * 7.要知道 這里現(xiàn)在是子線程 更新UI的操作需要在主線程(UI線程)完成那伐。
     * 在 Activity 中聲明 Handler 對象踏施,并復(fù)寫它的 handleMessage 方法
     */
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1010) {
                Bitmap bitmap = (Bitmap) msg.obj;
                setImageView(bitmap);
            }
        }
    };

    private ImageView mImageView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_net);

        mImageView = findViewById(R.id.image);


        loadImageUrl("https://cdn.pixabay.com/photo/2017/05/09/23/02/dog-2299482_960_720.jpg");
    }

   

    private void loadImageUrl(final String imageUrl) {
        // Android 系統(tǒng)強制網(wǎng)絡(luò)請求需要在子線程操作
        new Thread(new Runnable() {

            @Override
            public void run() {
                InputStream inputStream = null;
                try {
                    // 1. 把傳過來的路徑轉(zhuǎn)成URL
                    URL url = new URL(imageUrl);
                    // 2.通過URL 建立網(wǎng)絡(luò)連接
                    // --> url.openConnection() 返回 URLConnection
                    // ,它是一個抽象類,這里需要通過Http協(xié)議建立連接罕邀,需要它的實現(xiàn)類 HttpURLConnection
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    // 3. 使用GET方法訪問網(wǎng)絡(luò)
                    urlConnection.setRequestMethod("GET");
                    // 配置網(wǎng)絡(luò)超時時間為 10秒
                    urlConnection.setConnectTimeout(10000);

                    //4. 獲取Http協(xié)議 響應(yīng)碼
                    int responseCode = urlConnection.getResponseCode();
                    // Http 協(xié)議 規(guī)定 響應(yīng)碼為200時 請求成功
                    if (responseCode == 200) {
                        // 5. 得知 請求資源成功后畅形,獲取圖片文件輸入流
                        inputStream = urlConnection.getInputStream();

                        // 6. 把獲取到的 文件輸入流 通過 系統(tǒng)Api 轉(zhuǎn)換為 ImageView 可以識別的 Bitmap 對象

                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                        // 7.要知道 這里現(xiàn)在是子線程 更新UI的操作需要再主線程(UI線程)完成。
                        Message message = mHandler.obtainMessage();
                        message.obj = bitmap;
                        message.what = 1010;//
                        mHandler.sendMessage(message);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (inputStream != null) {
                        try {
                            //關(guān)閉流
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();


    }
}
/**
* 8.利用從 Mesage 從子線程中攜帶回來的 Bitmap 對象诉探,在UI線程設(shè)置圖片
*/
 private void setImageView(Bitmap bitmap) {
        mImageView.setImageBitmap(bitmap);
 }
}

上面是創(chuàng)建一個空的 Activity ,布局文件中只有一個 ImageView 控件日熬。
注意:在 Android中 主線程 也叫 UI線程。UI 線程是響應(yīng)用戶操作的線程阵具,一旦在 UI線程中存在好在操作碍遍,就會阻塞 UI 線程,導(dǎo)致無法及時響應(yīng)用戶操作事件阳液。所以在Android 系統(tǒng) 4.0 后怕敬,強制網(wǎng)絡(luò)請求操作必須在子線程。但問題是:所有更新 UI 的操作又必須在UI線程帘皿,這就是我們必須把網(wǎng)絡(luò)請求的結(jié)果东跪,轉(zhuǎn)移到主線程才能更新 UI。怎么轉(zhuǎn)移呢鹰溜? 那就是 Handler虽填。這個現(xiàn)在知道怎么用就行,后面我們會仔細講解曹动。

上面的代碼中斋日,利用系統(tǒng)自帶 ULRConnection請求網(wǎng)絡(luò)請求的步驟注釋已經(jīng)很詳細了∧钩拢可仔細了解其網(wǎng)絡(luò)請求步驟恶守,大致的套路是一樣的。

<font face="黑體" size="4" color="#ff0000">特別特別特別注意:網(wǎng)絡(luò)請求是需要權(quán)限的贡必,你需要在 AndroidManifet.xml 文件中聲明一句用戶權(quán)限兔港。至于權(quán)限的概念后面我們會細聊。現(xiàn)在只需要在AndroidManifet.xml文件申明即可仔拟。</font>

<uses-permission android:name="android.permission.INTERNET"/>

第三方網(wǎng)絡(luò)圖片加載庫與原始加載庫的對比

我們來思考幾個問題衫樊,如果在真實項目中,我們這樣加載圖片你覺得可以嗎利花?

........

答案是:不可以科侈。

  • 問題1:上面就只單一使用了內(nèi)存緩存來解決圖片加載問題,Android 系統(tǒng)為每個應(yīng)用分配的內(nèi)存是有限的炒事,假如說我們的圖片成千上萬兑徘,即使現(xiàn)在的 Android 手機硬件都配置很高,也頂不住這樣的操作羡洛,當內(nèi)存不足時應(yīng)用馬上會崩潰(Crash)挂脑。
  • 問題2:內(nèi)存緩存,易失去性欲侮。即當你重新啟動應(yīng)用程序后崭闲,原來已經(jīng)加載過的圖片就會丟失,重啟后又會重新下載威蕉!這就會導(dǎo)致頁面加載緩慢刁俭,再次耗費用戶流量。

所以我們需要一個比較完善的圖片加載系統(tǒng)韧涨,這個系統(tǒng)最基礎(chǔ)的要包括圖片的緩存策略:先從網(wǎng)絡(luò)請求圖片牍戚,在手機內(nèi)存中和SD卡中各自保存一份圖片資源侮繁。當重啟應(yīng)用時,如果圖片存在SD卡中如孝,就可以從SD卡中直接獲取圖片加載宪哩。并且SD卡所能存儲的圖片總數(shù)是一定的,會不斷的根據(jù)策略去舍去圖片的存留第晰。

還有非常重要的一點:從圖片加載庫的使用者角度講锁孟,使用者無需關(guān)心內(nèi)部到底是使用內(nèi)存緩存,還是SD卡緩存茁瘦,或是直接從網(wǎng)絡(luò)獲取的品抽。這對于使用者來講,內(nèi)部的一切用戶并不需要知道甜熔。使用者只需要知道加載圖片的接口圆恤。

對于圖片加載框架,內(nèi)部實現(xiàn)是極其復(fù)雜的腔稀,目前我們并不需要了解其內(nèi)部實現(xiàn)方式掠廓。

下面我們就使用最常用的圖片加載框架 Glide來完成我們圖片加載框架使用的演示积糯。

怎樣使用第三方網(wǎng)絡(luò)加載庫加載圖片(Glide)

我們要知道目溉,因為Android是開源的代嗤,所以會產(chǎn)生各種各樣的第三方框架,而我們不能盲目的去使用炕淮,要根據(jù)實際情況拆火,從這之中挑選出最優(yōu)的、最適合自己項目的框架涂圆,合理有效的去使用各種資源们镜。而我們推薦的Glide是經(jīng)過不斷的和其他框架對比所挑選出來性價比最高的!

目前國內(nèi)主流的第三方網(wǎng)絡(luò)圖片加載庫有Glide(主推)润歉、ImageLoader模狭、PicassoVolley踩衩、Fresco等嚼鹉,感興趣的小伙伴可以去搜索一下這些加載庫的全方面對比,百度一哈比比皆是驱富,我們就不再這里將網(wǎng)上的一些大神所對比的實際內(nèi)容再復(fù)述一遍啦锚赤。下面請跟我走4步,完成你人生中第一次加載網(wǎng)絡(luò)圖片吧:峙浮O呓拧!

  1. 首先我們要通過依賴 Glide 圖片加載庫。

    Glide github 官方地址

  2. 在官方文檔中我們找到需要依賴的 Glide庫地址浑侥。

 implementation 'com.github.bumptech.glide:glide:4.9.0'
  1. 將依賴地址放置到 app 模塊下的 build.gradle 中如圖:
image

添加完成后姊舵,我們點擊 右上角的 Sync Now ,從網(wǎng)絡(luò)下載依賴庫到本地寓落,并依賴到 app 模塊括丁。

  1. 我們在創(chuàng)建的空 Activity 當中,為 ImageView控件利用 Glide加載圖片零如。
image

okay,搞定3酢考蕾!使用第三圖片加載庫是不是很簡單。

其實里面的大致操作就是我們在第一個問題中書寫的代碼会宪,里面多的就是各種緩存策略和邏輯處理肖卧。

結(jié)語

關(guān)于網(wǎng)絡(luò)圖片的加載我們今天就講到這里,請原諒小編沒有對Glide的源碼做詳解掸鹅,因為內(nèi)容過于復(fù)雜塞帐,涉及到很多初學(xué)者無法理解的知識,咱們目前只需要會使用巍沙,慢慢的跟著我們一起學(xué)習(xí)葵姥,后續(xù)這些都會融會貫通的~ 如果有小伙伴對Glide的源碼感興趣可以加入我們的微信群一起探討~ 在公眾號中回復(fù)微信群,就可以加入其中句携,也可以在公眾號中回復(fù)視頻榔幸,里面有一些初學(xué)者視頻哦~

PS:如果還有未看懂的小伙伴,歡迎加入我們的QQ技術(shù)交流群:892271582矮嫉,里面有各種大神回答小伙伴們遇到的問題削咆,我們的微信群馬上也將要和大家見面啦,屆時希望大家踴躍加入其中~~

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蠢笋,一起剝皮案震驚了整個濱河市拨齐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昨寞,老刑警劉巖瞻惋,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異援岩,居然都是意外死亡熟史,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門窄俏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹂匹,“玉大人,你說我怎么就攤上這事凹蜈∠弈” “怎么了忍啸?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長履植。 經(jīng)常有香客問我计雌,道長,這世上最難降的妖魔是什么玫霎? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任凿滤,我火速辦了婚禮,結(jié)果婚禮上庶近,老公的妹妹穿的比我還像新娘翁脆。我一直安慰自己,他們只是感情好鼻种,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布反番。 她就那樣靜靜地躺著,像睡著了一般叉钥。 火紅的嫁衣襯著肌膚如雪罢缸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天投队,我揣著相機與錄音枫疆,去河邊找鬼。 笑死敷鸦,一個胖子當著我的面吹牛养铸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轧膘,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼钞螟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谎碍?” 一聲冷哼從身側(cè)響起鳞滨,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蟆淀,沒想到半個月后拯啦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡熔任,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年褒链,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疑苔。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡甫匹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兵迅,我是刑警寧澤抢韭,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站恍箭,受9級特大地震影響刻恭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扯夭,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一鳍贾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧交洗,春花似錦骑科、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梳码。三九已至隐圾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掰茶,已是汗流浹背暇藏。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留濒蒋,地道東北人盐碱。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像沪伙,于是被迫代替她去往敵國和親瓮顽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

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

  • 7.1 壓縮圖片 一围橡、基礎(chǔ)知識 1暖混、圖片的格式 jpg:最常見的圖片格式。色彩還原度比較好翁授,可以支持適當壓縮后保持...
    AndroidMaster閱讀 2,496評論 0 13
  • 一拣播、簡介 在泰國舉行的谷歌開發(fā)者論壇上,谷歌為我們介紹了一個名叫Glide的圖片加載庫收擦,作者是bumptech贮配。這...
    天天大保建閱讀 7,459評論 2 28
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,092評論 1 32
  • 近來,簡書最熱門的事情就是簡書鉆酣藻。 我是一書呆子曹洽,只知道寫文更文,對于政策的領(lǐng)會總是迷迷糊糊辽剧。 打開自己的簡書送淆,發(fā)...
    南歌吟閱讀 1,202評論 20 24
  • 我是一個大大咧咧的女孩,從小就不喜歡做家務(wù)怕轿,家里面也不整理偷崩,但內(nèi)心卻想成為一個很精致的女孩。 我一直想過這樣一種生...
    不是文藝的小女孩閱讀 207評論 0 0