溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

【移動開發(fā)】Android圖片異步加載之Android-Universal-Image-Loader使用

發(fā)布時(shí)間:2020-07-11 04:34:12 來源:網(wǎng)絡(luò) 閱讀:20067 作者:zhf651555765 欄目:開發(fā)技術(shù)

   Android開發(fā)中我們會經(jīng)常遇到圖片過多或操作不當(dāng)造成OOM異常,有時(shí)雖然是解決了這個(gè)問題但卻會影響程序的運(yùn)行效率,例如:當(dāng)用戶在快速滑動滾動條的過程中,我們程序在仍在艱難的加載服務(wù)器端的圖片,這樣給用戶造成了極不好的體驗(yàn)。其實(shí)網(wǎng)絡(luò)上關(guān)于圖片的異步加載和緩存的講解很多,但是其實(shí),寫一個(gè)這方面的程序還是比較麻煩的,要考慮多線程,緩存,內(nèi)存溢出等很多方面,針對這一光大開發(fā)者都會遇到的問題,一些牛人們已經(jīng)幫我們解決了這一問題,今天我為大家介紹一款很流行的開源類庫,可以很很好的解決大家的煩惱!

   

一.介紹:

   Android-Universal-Image-Loader是一個(gè)開源的UI組件程序,該項(xiàng)目的目的是提供一個(gè)可重復(fù)使用的儀器為異步圖像加載,緩存和顯示。

   在GitHub上面的一個(gè)開源類庫(官方下載:https://github.com/nostra13/Android-Universal-Image-Loader


  特點(diǎn):

       1.多線程的圖像加載;

       2.圖片異步加載緩存機(jī)制,包括內(nèi)存緩存(軟引用)及本地緩存;

       3.動態(tài)對ImageLoader的配置(線程池的大小,HTTP選項(xiàng),內(nèi)存和光盤高速緩存方式,顯示圖像,以及其他選項(xiàng));

       4.對加載過程實(shí)現(xiàn)監(jiān)聽和事件處理;

       5.能夠配置加載圖片的顯示選項(xiàng),包括圖片圓角處理和加載完成顯示動畫等;

(官方截圖)

【移動開發(fā)】Android圖片異步加載之Android-Universal-Image-Loader使用


二.使用

  1.將下載下來的zip包,解壓開得到如下圖所示文件夾

【移動開發(fā)】Android圖片異步加載之Android-Universal-Image-Loader使用

  2.將universal-p_w_picpath-loader-1.8.6-with-sources.jar導(dǎo)入到新建的項(xiàng)目中,參考sample中的例子進(jìn)行使用即可。為了讓新手們快速掌握這里我簡單講解一下它的使用過程(使用該類庫中ImageLoader加載圖片,ListView、GridView、ViewPager)


Demo項(xiàng)目圖解:

【移動開發(fā)】Android圖片異步加載之Android-Universal-Image-Loader使用


   

    2.1.在程序啟動時(shí),用戶可以根據(jù)自己的情況初始化ImageLoaderConfiguration

public class MyApplication extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        initImageLoader(getApplicationContext());
    }
    /**初始化圖片加載類配置信息**/
    public static void initImageLoader(Context context) {
        // This configuration tuning is custom. You can tune every option, you may tune some of them,
        // or you can create default configuration by
        //  ImageLoaderConfiguration.createDefault(this);
        // method.
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
            .threadPriority(Thread.NORM_PRIORITY - 2)//加載圖片的線程數(shù)
            .denyCacheImageMultipleSizesInMemory() //解碼圖像的大尺寸將在內(nèi)存中緩存先前解碼圖像的小尺寸。
            .discCacheFileNameGenerator(new Md5FileNameGenerator())//設(shè)置磁盤緩存文件名稱
            .tasksProcessingOrder(QueueProcessingType.LIFO)//設(shè)置加載顯示圖片隊(duì)列進(jìn)程
            .writeDebugLogs() // Remove for release app
            .build();
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config);
    }
}

別忘了在AndroidManifest.xml中

android:name=".MyApplication"


  2.2.在MainActivity中我們做的僅僅是跳轉(zhuǎn)到對應(yīng)的界面,下面看一下ListView中的具體使用,剩下兩個(gè)自己看一下Demo,原理一樣。

ImageListActivity:

/**
 * listView中使用ImageLoader
 * @author ZHF
 *
 */
public class ImageListActivity extends AbsListViewBaseActivity {
    DisplayImageOptions options; //配置圖片加載及顯示選項(xiàng)
    String[] p_w_picpathUrls;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ac_p_w_picpath_list);
        //獲取url數(shù)組
        Bundle bundle = getIntent().getExtras();
        p_w_picpathUrls = bundle.getStringArray(Extra.IMAGES);
        //配置圖片加載及顯示選項(xiàng)(還有一些其他的配置,查閱doc文檔吧)
        options = new DisplayImageOptions.Builder()
            .showStubImage(R.drawable.ic_stub)    //在ImageView加載過程中顯示圖片
            .showImageForEmptyUri(R.drawable.ic_empty)  //p_w_picpath連接地址為空時(shí)
            .showImageOnFail(R.drawable.ic_error)  //p_w_picpath加載失敗
            .cacheInMemory(true)  //加載圖片時(shí)會在內(nèi)存中加載緩存
            .cacheOnDisc(true)   //加載圖片時(shí)會在磁盤中加載緩存
            .displayer(new RoundedBitmapDisplayer(20))  //設(shè)置用戶加載圖片task(這里是圓角圖片顯示)
            .build();
        listView = (ListView) findViewById(android.R.id.list);
        //綁定適配器
        listView.setAdapter(new ItemAdapter());
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                startImagePagerActivity(position);
            }
        });
    }
    @Override
    public void onBackPressed() {
        AnimateFirstDisplayListener.displayedImages.clear();
        super.onBackPressed();
    }
    private void startImagePagerActivity(int position) {
        Intent intent = new Intent(this, ImagePagerActivity.class);
        intent.putExtra(Extra.IMAGES, p_w_picpathUrls);
        intent.putExtra(Extra.IMAGE_POSITION, position);
        startActivity(intent);
    }
    /**自定義圖片適配器**/
    class ItemAdapter extends BaseAdapter {
        private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
        private class ViewHolder {
            public TextView text;
            public ImageView p_w_picpath;
        }
        @Override
        public int getCount() {
            return p_w_picpathUrls.length;
        }
        @Override
        public Object getItem(int position) {
            return position;
        }
        @Override
        public long getItemId(int position) {
            return position;
        }
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = convertView;
            final ViewHolder holder;
            if (convertView == null) {
                view = getLayoutInflater().inflate(R.layout.item_list_p_w_picpath, parent, false);
                holder = new ViewHolder();
                holder.text = (TextView) view.findViewById(R.id.text);
                holder.p_w_picpath = (ImageView) view.findViewById(R.id.p_w_picpath);
                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }
            holder.text.setText("Item " + (position + 1));
            //Adds display p_w_picpath task to execution pool. Image will be set to ImageView when it's turn.
            p_w_picpathLoader.displayImage(p_w_picpathUrls[position], holder.p_w_picpath, options, animateFirstListener);
            return view;
        }
    }
    /**圖片加載監(jiān)聽事件**/
    private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {
        static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());
        @Override
        public void onLoadingComplete(String p_w_picpathUri, View view, Bitmap loadedImage) {
            if (loadedImage != null) {
                ImageView p_w_picpathView = (ImageView) view;
                boolean firstDisplay = !displayedImages.contains(p_w_picpathUri);
                if (firstDisplay) {
                    FadeInBitmapDisplayer.animate(p_w_picpathView, 500); //設(shè)置p_w_picpath隱藏動畫500ms
                    displayedImages.add(p_w_picpathUri); //將圖片uri添加到集合中
                }
            }
        }
    }
}

說明:

   1.使用ImageLoader加載圖片,只要在Adapter的getView方法中調(diào)用displayImage方法完成了異步列表圖片加載,其中options是之前定義的圖片加載和顯示選項(xiàng)(我們這里使用的是RoundedBitmapDisplayer圓角圖片顯示),animateFirstListener是當(dāng)圖片第一次加載的監(jiān)聽事件,目的在于顯示一個(gè)淡入的顯示效果動畫,可以添加其他事件

   2.進(jìn)本人測試,官網(wǎng)例子中的Constant類中圖片的Uri在手機(jī)中鏈接很慢,完全達(dá)不到效果,之后我將其更改為其他一系列圖片的Uri,便于觀察效果!


效果圖:

【移動開發(fā)】Android圖片異步加載之Android-Universal-Image-Loader使用   【移動開發(fā)】Android圖片異步加載之Android-Universal-Image-Loader使用   【移動開發(fā)】Android圖片異步加載之Android-Universal-Image-Loader使用


  最后,大家在使用的時(shí)候記得關(guān)注一下在/sdcard/Android/data/[package_name]/cache目錄下的緩存的文件。記得定期清理緩存,否則時(shí)間一長,SD卡就會被占滿了,同時(shí)也可以在ImageLoaderConfiguration中配置SD的緩存策略,限制緩存文件數(shù)量(memoryCacheSizePercentage),限制緩存文件最大尺寸(memoryCacheSize)等選項(xiàng)。


Demo源碼已上傳!

 



附件:http://down.51cto.com/data/2363836
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI