安卓開發(fā)小技巧:Activity之間傳遞圖片

需求詳解

既然說了是傳遞圖片,自然就不是URL什么的。
假設(shè)有這樣一個情景:Activity A從網(wǎng)絡(luò)獲取了一張圖片,正好下一個Activity B也要用到,如果能從A把圖片傳過去的話,B就可以節(jié)約一次網(wǎng)絡(luò)圖片訪問,而這張圖片下次不一定會用到,因此緩存什么的也不合適。
那么,用什么方法可以做到呢?

解法分析

我們知道,在Activity之間傳遞數(shù)據(jù),一般用的是Intent。圖片雖然不能直接放進Intent里面,但可以處理一下,轉(zhuǎn)化為ByteArray然后再放進去:

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_target);     
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); 
byte[] b = baos.toByteArray();

Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("picture", b);
startActivity(intent);

//In Activity B you receive intent with byte array (decoded picture) and apply it as source to ImageView:

Bundle extras = getIntent().getExtras();
byte[] b = extras.getByteArray("picture");

Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);

image.setImageBitmap(bmp);

擴展探究

其實還是可以利用緩存的,就算不想緩存,也可以在B里面提取之后刪掉。

// In *Activity A* save the file (Internal Storage)
String fileName = "SomeName.png";
try {
    FileOutputStream fileOutStream = openFileOutput(fileName, MODE_PRIVATE);
    fileOutStream.write(b);  //b is byte array 
                             //(used if you have your picture downloaded
                             // from the *Web* or got it from the *devices camera*)
                             //otherwise this technique is useless
    fileOutStream.close();
} catch (IOException ioe) {
    ioe.printStackTrace();
}
//Pass location as String to Activity B
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("picname", fileName);

//In *Activity B* retrieve the file
Bundle extras = getIntent().getExtras();
String fileName = extras.getString("picname");
//Make *drawable* out of the picture
File filePath = getFileStreamPath(fileName);
Drawable d = Drawable.createFromPath(filePath.toString());
//Apply it to the ImageView resource
someImageView.setBackgroundDrawable(d);
//If want to delete
filePath.delete();

此方法不一定在性能上有優(yōu)勢,但也算是可行的一種
此外在這里發(fā)現(xiàn)一份整理得比較好的文件訪問圖:

   ($rootDir)
+- /data                -> Environment.getDataDirectory()
|   |
|   |   ($appDataDir)
|   +- data/com.srain.cube.sample
|       |
|       |   ($filesDir)
|       +- files            -> Context.getFilesDir() / Context.getFileStreamPath("")
|       |       |
|       |       +- file1    -> Context.getFileStreamPath("file1")
|       |   ($cacheDir)
|       +- cache            -> Context.getCacheDir()
|       |
|       +- app_$name        ->(Context.getDir(String name, int mode)
|
|   ($rootDir)
+- /storage/sdcard0     -> Environment.getExternalStorageDirectory()
    |                       / Environment.getExternalStoragePublicDirectory("")
    |
    +- dir1             -> Environment.getExternalStoragePublicDirectory("dir1")
    |
    |   ($appDataDir)
    +- Andorid/data/com.srain.cube.sample
        |
        |   ($filesDir)
        +- files        -> Context.getExternalFilesDir("")
        |   |
        |   +- file1    -> Context.getExternalFilesDir("file1")
        |   +- Music    -> Context.getExternalFilesDir(Environment.Music);
        |   +- Picture  -> ... Environment.Picture
        |   +- ...
        |
        |   ($cacheDir)
        +- cache        -> Context.getExternalCacheDir()
        |
        +- ???

從這個圖里面可以比較清楚地看出文件存儲系統(tǒng)的結(jié)構(gòu)和相應(yīng)的訪問方法。
當(dāng)然這里不是主要講這個的,以后有機會再詳細說一說。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容