移動開發面試常用題

fudanstar發表於2016-03-23

1 . 如何顯示一個很大的圖,高清載入巨圖方案

首先不壓縮,按照原圖尺寸載入,那麼螢幕肯定是不夠大的,並且考慮到記憶體的情況,不可能一次性整圖載入到記憶體中,所以肯定是區域性載入,那麼就需要用到一個類:
BitmapRegionDecoder
其次,既然螢幕顯示不完,那麼最起碼要新增一個上下左右拖動的手勢,讓使用者可以拖動檢視。
BitmapRegionDecoder主要用於顯示圖片的某一塊矩形區域,如果你需要顯示某個圖片的指定區域,那麼這個類非常合適。

對於該類的用法,非常簡單,既然是顯示圖片的某一塊區域,那麼至少只需要一個方法去設定圖片;一個方法傳入顯示的區域即可;詳見:
BitmapRegionDecoder提供了一系列的newInstance方法來構造物件,支援傳入檔案路徑,檔案描述符,檔案的inputstrem等。

例如:

BitmapRegionDecoder bitmapRegionDecoder =
  BitmapRegionDecoder.newInstance(inputStream, false);

上述解決了傳入我們需要處理的圖片,那麼接下來就是顯示指定的區域。

bitmapRegionDecoder.decodeRegion(rect, options);

引數一很明顯是一個rect,引數二是BitmapFactory.Options,你可以控制圖片的inSampleSize,inPreferredConfig等。
那麼下面看一個超級簡單的例子:

package com.zhy.blogcodes.largeImage;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;

import com.zhy.blogcodes.R;

import java.io.IOException;
import java.io.InputStream;

public class LargeImageViewActivity extends AppCompatActivity
{
    private ImageView mImageView;

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

        mImageView = (ImageView) findViewById(R.id.id_imageview);
        try
        {
            InputStream inputStream = getAssets().open(tangyan.jpg);
            //獲得圖片的寬、高
            BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
            tmpOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(inputStream, null, tmpOptions);
            int width = tmpOptions.outWidth;
            int height = tmpOptions.outHeight;
            //設定顯示圖片的中心區域
            BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            Bitmap bitmap = bitmapRegionDecoder.decodeRegion(new Rect(width / 2 - 100, height / 2 - 100, width / 2 + 100, height / 2 + 100), options);
            mImageView.setImageBitmap(bitmap);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

2 .安卓的資料快取方案

首先資料分為兩種:和應用相關的資料;和應用無關的資料。這裡分別介紹:

1、應用無關的資料是那些使用者比較關心的資料,不管您的應用在不在使用者裝置上,這些資料使用者都希望保留,這些資料包含:用相機拍攝的照片、用瀏覽器(下載工具)下載的檔案、使用者製作的個性鈴聲等。假設您開發了一個照相應用(例如: 360相機),使用者用您的應用拍攝並處理過的照片就屬於應用無關的資料,如果使用者把您的應用給解除安裝了,使用者還是會期望仍然保留他們拍攝並處理過的照片。這裡的照片按照Android官方的建議應該儲存到 DIRECTORY_PICTURES 目錄中,該目錄通過Environment.getExternalStoragePublicDirectory(String type)來獲取,您可以在該目錄下建立一個以您的程式命名的目錄來儲存資料。

2、應用相關的資料: 這種資料只和您的應用相關,如果您的應用被使用者刪除了這些資料也沒有理由還存在使用者裝置中。這種資料包含:資料庫檔案、屬性配置檔案、應用的快取檔案等。這裡我們只討論在API 8(Android 2.2)中新引入了一種儲存到外部儲存空間的偽私有資料API,通過函式getExternalFilesDir() 來獲取該路徑,同樣可以設定獲取各種型別資料的引數,例如 DIRECTORY_MUSIC 和 DIRECTORY_RINGTONES (如果引數為null則返回您應用資料的跟目錄)。比如一個應用的包名為 org.goodev.test 的應用,通過函式getExternalFilesDir(Environment.DIRECTORY_MOVIES)獲取到的檔案路徑為 /storage/sdcard0/Android/data/org.goodev.test/files/Movies。

關於app圖片儲存問題
方案:

暫時方案:
1、  與使用者有關的資料按照上面所說的,存在程式安裝資料夾下的一個目錄中。
2、  與使用者無關的資料,統一存在手機外儲存卡上,如果手機沒有裝外儲存卡,則提示沒插儲存卡,圖片不能快取。

LruCache介紹

核心的類是LruCache (此類在android-support-v4的包中提供) 。這個類非常適合用來快取圖片,它的主要演算法原理是把最近使用的物件用強引用儲存在 LinkedHashMap 中,並且把最近最少使用的物件在快取值達到預設定值之前從記憶體中移除。

LruCache使用 下面我們就來寫一個簡單的demo來學習LruCache,效果也是每次請求一次第二次直接從快取中提取出來不用再次請求網路 ## 標題 ##

private LruCache<integer, string=""> mJsonCache; /**     * 快取json資料     */    
private LruCache<integer, bitmap=""> mBitmapCache;  /**     * 快取圖片資訊     */    

public Util() {        
mJsonCache = new LruCache<integer, string="">(1 * 1024 * 1024);        
mBitmapCache = new LruCache<integer, bitmap="">(2 * 1024 * 1024);    
}     
/**     * 新增進入快取列表     *      * @param key     * @param value     */    
public void addJsonLruCache(Integer key, String value) 
{        
    mJsonCache.put(key, value);    
}     

public void addBitmapLruCache(Integer key, Bitmap value) 
{        
    mBitmapCache.put(key, value);    
}     
/**     * 從快取列表中拿出來     *      * @param key     * @return     */    
public String getJsonLruCache(Integer key) 
{        
     return mJsonCache.get(key);    
}     
public Bitmap getBitmapLruCache(Integer key) 
{        
    return mBitmapCache.get(key);    
}

相關文章