Android上在两个Activity之间传递Bitmap对象

转自:http://blog.csdn.net/jia20003/article/details/50212195

Android上在两个Activity之间传递Bitmap对象

因为我做Android应用的时间不长,所以当我第一次在android之间传递Bitmap对象的时候我直接用了Intent.putExtra的方法实现了,当时我选择的是一张图像的ROI区域,所以工作的很好,但是当我尝试将整个图片做为Bitmap对象传到另外一个Activity中的时候总是得到一个错误fatal bind error我当时很郁闷了好久,后来google才发现是这样传递Bitmap对象的方式不对,Activity之间传递Bitmap有大小限制,而且这个大小限制很小,512x512的图片肯定会得到我上述的这个错误,于是我想到了先保存到SD卡上然后传递路径的方法,但是SD卡属于外部存储,可能不是特别方便,后来看到有人通过内部存储方式实现了在两个Activity之间传递Bitmap对象以及其它支持串行化的Java对象,我觉得很好,所以就写了这篇博客。关键点有如下:

1.  HTTP客户端下载图片,通过ImageView对象显示

2.  把ImageView上的Bitmap对象从当前Activity传递到另外一个

Activity中并显示出来

3.  基于串行化传递Java对象数据

 

首先看我是怎么实现HTTP客户端下载图片,通过异步Task接口实现HTTP客户端下载图片并通过Handler来更新ImageView,代码如下:

[java]  view plain  copy
  1. package com.example.sharedemo;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5.   
  6. import org.apache.http.HttpEntity;  
  7. import org.apache.http.HttpResponse;  
  8. import org.apache.http.HttpStatus;  
  9. import org.apache.http.client.ClientProtocolException;  
  10. import org.apache.http.client.HttpClient;  
  11. import org.apache.http.client.methods.HttpGet;  
  12. import org.apache.http.impl.client.DefaultHttpClient;  
  13.   
  14. import android.graphics.Bitmap;  
  15. import android.graphics.BitmapFactory;  
  16. import android.os.AsyncTask;  
  17. import android.os.Handler;  
  18. import android.os.Message;  
  19. import android.util.Log;  
  20.   
  21. public class ImageLoadTask extends AsyncTask {  
  22.     private Handler handler;  
  23.   
  24.     public ImageLoadTask(Handler handler) {  
  25.         this.handler = handler;  
  26.     }  
  27.   
  28.     protected void onPostExecute(Bitmap bitmap) {  
  29.         Message msg = new Message();  
  30.         msg.obj = bitmap;  
  31.         handler.sendMessage(msg);  
  32.     }  
  33.   
  34.     @Override  
  35.     protected Bitmap doInBackground(String... urls) {  
  36.         Bitmap bitmap = null;  
  37.         // create HTTP client  
  38.         HttpClient httpclient = new DefaultHttpClient();  
  39.         try {  
  40.             // GET request  
  41.             Log.i("image-url", urls[0]);  
  42.             HttpGet httpRequest = new HttpGet(urls[0]);  
  43.             HttpResponse httpResponse = httpclient.execute(httpRequest);  
  44.             if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  45.                 // get entity from response  
  46.                 HttpEntity httpEntity = httpResponse.getEntity();  
  47.                 // read stream  
  48.                 InputStream is = httpEntity.getContent();  
  49.                 bitmap = BitmapFactory.decodeStream(is);  
  50.                 is.close();  
  51.                 Log.i("image""already get the image by url : " + urls[0]);  
  52.             }  
  53.   
  54.         } catch (ClientProtocolException e) {  
  55.             e.printStackTrace();  
  56.         } catch (IOException e) {  
  57.             e.printStackTrace();  
  58.         } finally {  
  59.             httpclient.getConnectionManager().shutdown();  
  60.         }  
  61.         return bitmap;  
  62.     }  
  63.   
  64. }  

在当前的Activity中通过按钮上的事件响应实现切换View到对应的Activity中去,同时实现Java串行化数据传递。MainActivity的代码如下:

[java]  view plain  copy
  1. package com.example.sharedemo;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.io.FileOutputStream;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.graphics.Bitmap;  
  10. import android.graphics.Matrix;  
  11. import android.graphics.drawable.BitmapDrawable;  
  12. import android.os.Bundle;  
  13. import android.os.Handler;  
  14. import android.os.Message;  
  15. import android.util.Log;  
  16. import android.view.View;  
  17. import android.view.View.OnClickListener;  
  18. import android.widget.Button;  
  19. import android.widget.ImageView;  
  20.   
  21. public class MainActivity extends Activity implements OnClickListener{  
  22.     public final static String SHARE_BITMAP_COMMAND = "share-image";  
  23.     public final static String SHARE_TEXT_DATA_COMMAND = "share-text-data";  
  24.     private Handler handler;  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_main);  
  30.         setupOnClickListener();  
  31.     }  
  32.   
  33.     private void setupOnClickListener() {  
  34.         Button bitmapBtn = (Button)this.findViewById(R.id.bitmapShareBtn);  
  35.         bitmapBtn.setTag(SHARE_BITMAP_COMMAND);  
  36.         bitmapBtn.setOnClickListener(this);  
  37.         Button textDataBtn = (Button)this.findViewById(R.id.mapShareBtn);  
  38.         textDataBtn.setTag(SHARE_TEXT_DATA_COMMAND);  
  39.         textDataBtn.setOnClickListener(this);  
  40.         final ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);  
  41.           
  42.         handler = new Handler()  
  43.         {  
  44.             public void handleMessage(Message msg) {  
  45.                 Bitmap bitmap = (Bitmap)msg.obj;  
  46.                 if(bitmap != null)  
  47.                 {  
  48.                     /* 
  49.                     // 为防止原始图片过大导致内存溢出,这里先缩小原图显示,然后释放原始Bitmap占用的内存 
  50.                     Bitmap smallBitmap = zoomBitmap(bitmap, bitmap.getWidth()/ 5, bitmap.getHeight() / 5); 
  51.                     // 释放资源 
  52.                     bitmap.recycle(); 
  53.                     // 显示图片 
  54.                     imageView.setImageBitmap(smallBitmap); 
  55.                     imageView.invalidate(); 
  56.                     */  
  57.                     imageView.setImageBitmap(bitmap);  
  58.                 }  
  59.             }  
  60.         };  
  61.         ImageLoadTask task = new ImageLoadTask(handler);  
  62.         task.execute("https://img-blog.csdn.net/20150607143208238");  
  63.     }  
  64.       
  65.     public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {  
  66.         int w = bitmap.getWidth();  
  67.         int h = bitmap.getHeight();  
  68.         Matrix matrix = new Matrix();  
  69.         float scaleWidth = ((float) width / w);  
  70.         float scaleHeight = ((float) height / h);  
  71.         matrix.postScale(scaleWidth, scaleHeight); // 不改变原来图像大小  
  72.         Bitmap newbmp = Bitmap.createBitmap(bitmap, 00, w, h, matrix, true);  
  73.         return newbmp;  
  74.     }  
  75.   
  76.     @Override  
  77.     public void onClick(View v) {  
  78.         Object tag = v.getTag();  
  79.         Log.i("command", tag.toString());  
  80.         if(SHARE_BITMAP_COMMAND.equals(tag))  
  81.         {  
  82.             Intent intent = new Intent(this.getApplicationContext(), ImageProcessActivity.class);  
  83.             ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);  
  84.             Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();  
  85.             intent.putExtra("selectedImage", bitmap);  
  86.             intent.putExtra("name""lena");  
  87.             intent.putExtra("description""超级大美女");  
  88.             this.startActivity(intent);           
  89.         }  
  90.         else if(SHARE_TEXT_DATA_COMMAND.equals(tag))  
  91.         {  
  92.             Intent intent = new Intent(this.getApplicationContext(), ImageProcessActivity.class);  
  93.             ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);  
  94.             Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();  
  95.             // save it first then pass URI  
  96.             ImageInfoBean dto = new ImageInfoBean();  
  97.             String uri = createImageFromBitmap(bitmap);  
  98.             dto.setDescription("超级大美女");  
  99.             dto.setName("lena");  
  100.             dto.setUri(uri);  
  101.               
  102.             intent.putExtra("tiger", dto);  
  103.             this.startActivity(intent);   
  104.         }  
  105.     }  
  106.       
  107.     public String createImageFromBitmap(Bitmap bitmap) {  
  108.         String fileName = "myImage";  
  109.         try {  
  110.             ByteArrayOutputStream bytes = new ByteArrayOutputStream();  
  111.             bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);  
  112.             FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);  
  113.             fo.write(bytes.toByteArray());  
  114.             fo.close();  
  115.         } catch (Exception e) {  
  116.             e.printStackTrace();  
  117.             fileName = null;  
  118.         }  
  119.         Log.i("fileName", fileName);  
  120.         return fileName;  
  121.     }  
  122. }  

对应另外一个Activity中实现读取与组装Bitmap对象显示的代码如下:

[java]  view plain  copy
  1. package com.example.sharedemo;  
  2.   
  3. import java.io.FileNotFoundException;  
  4.   
  5. import android.app.Activity;  
  6. import android.graphics.Bitmap;  
  7. import android.graphics.BitmapFactory;  
  8. import android.os.Bundle;  
  9. import android.widget.ImageView;  
  10. import android.widget.TextView;  
  11.   
  12. public class ImageProcessActivity extends Activity {  
  13.   
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.share_info);  
  18.         backFillData();  
  19.     }  
  20.   
  21.     private void backFillData() {  
  22.         Object obj = this.getIntent().getExtras().get("tiger");  
  23.         ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);  
  24.         TextView text1 = (TextView)this.findViewById(R.id.textView1);  
  25.         TextView text2 = (TextView)this.findViewById(R.id.textView2);  
  26.         try {  
  27.             if(obj != null && obj instanceof ImageInfoBean)  
  28.             {  
  29.                 ImageInfoBean dto = (ImageInfoBean)obj;  
  30.                 Bitmap bitmap = BitmapFactory.decodeStream(this.openFileInput(dto.getUri()));  
  31.                 imageView.setImageBitmap(bitmap);  
  32.                 imageView.invalidate(); // refresh  
  33.                   
  34.                 text1.setText("名称: " + dto.getName());  
  35.                 text2.setText("描述: " + dto.getDescription());  
  36.                 return;  
  37.             }  
  38.         } catch (FileNotFoundException e) {  
  39.             e.printStackTrace();  
  40.         }  
  41.           
  42.         Bitmap bitmap = (Bitmap) this.getIntent().getParcelableExtra("selectedImage");  
  43.         String name = this.getIntent().getExtras().getString("name");  
  44.         String description = this.getIntent().getExtras().getString("description");  
  45.         if(bitmap != null)  
  46.         {  
  47.             imageView.setImageBitmap(bitmap);  
  48.             imageView.invalidate(); // refresh  
  49.         }  
  50.         if(name != null)  
  51.         {  
  52.             text1.setText("名称: " + name);  
  53.         }  
  54.         if(description != null)  
  55.         {  
  56.             text2.setText("描述: " + description);  
  57.         }  
  58.     }  
  59.   
  60. }  
对应的Java串行化对象类代码如下:

[java]  view plain  copy
  1. package com.example.sharedemo;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. public class ImageInfoBean implements Serializable {  
  6.     /** 
  7.      *  
  8.      */  
  9.     private static final long serialVersionUID = 1L;  
  10.   
  11.     public String getName() {  
  12.         return name;  
  13.     }  
  14.   
  15.     public void setName(String name) {  
  16.         this.name = name;  
  17.     }  
  18.   
  19.     public String getDescription() {  
  20.         return description;  
  21.     }  
  22.   
  23.     public void setDescription(String description) {  
  24.         this.description = description;  
  25.     }  
  26.   
  27.     public String getUri() {  
  28.         return uri;  
  29.     }  
  30.   
  31.     public void setUri(String uri) {  
  32.         this.uri = uri;  
  33.     }  
  34.   
  35.     private String name;  
  36.     private String description;  
  37.     private String uri;  
  38.   
  39. }  
最后声明:

别忘记在Manifest文件添加网络访问的权限

[html]  view plain  copy
  1. <uses-permission android:name="android.permission.INTERNET"/>  
Android上在两个Activity之间传递Bitmap对象_第1张图片
第一个按钮【传递图片】将会演示我遇到错误,第二按钮【传递文本数据】

将会演示正确的处理结果,显示如下:

Android上在两个Activity之间传递Bitmap对象_第2张图片

Android学习交流群:523487222

(如果您觉得有用,欢迎加入,一起学习进步)
点击链接加入群【Android学习群】




你可能感兴趣的:(Android,知识)