需求詳解
既然說了是傳遞圖片,自然就不是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)然這里不是主要講這個的,以后有機會再詳細說一說。