美文网首页Develop
安卓开发小技巧:Activity之间传递图片

安卓开发小技巧:Activity之间传递图片

作者: akak18183 | 来源:发表于2017-03-05 02:37 被阅读644次

    需求详解

    既然说了是传递图片,自然就不是URL什么的。
    假设有这样一个情景:Activity A从网络获取了一张图片,正好下一个Activity B也要用到,如果能从A把图片传过去的话,B就可以节约一次网络图片访问,而这张图片下次不一定会用到,因此缓存什么的也不合适。
    那么,用什么方法可以做到呢?

    解法分析

    我们知道,在Activity之间传递数据,一般用的是Intent。图片虽然不能直接放进Intent里面,但可以处理一下,转化为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();
    

    此方法不一定在性能上有优势,但也算是可行的一种
    此外在这里发现一份整理得比较好的文件访问图:

       ($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()
            |
            +- ???
    

    从这个图里面可以比较清楚地看出文件存储系统的结构和相应的访问方法。
    当然这里不是主要讲这个的,以后有机会再详细说一说。

    相关文章

      网友评论

        本文标题:安卓开发小技巧:Activity之间传递图片

        本文链接:https://www.haomeiwen.com/subject/xklsgttx.html