編輯:關於android開發
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,代碼如下:
package com.example.sharedemo; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.util.Log; public class ImageLoadTask extends AsyncTask{ private Handler handler; public ImageLoadTask(Handler handler) { this.handler = handler; } protected void onPostExecute(Bitmap bitmap) { Message msg = new Message(); msg.obj = bitmap; handler.sendMessage(msg); } @Override protected Bitmap doInBackground(String... urls) { Bitmap bitmap = null; // create HTTP client HttpClient httpclient = new DefaultHttpClient(); try { // GET request Log.i("image-url", urls[0]); HttpGet httpRequest = new HttpGet(urls[0]); HttpResponse httpResponse = httpclient.execute(httpRequest); if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // get entity from response HttpEntity httpEntity = httpResponse.getEntity(); // read stream InputStream is = httpEntity.getContent(); bitmap = BitmapFactory.decodeStream(is); is.close(); Log.i("image", "already get the image by url : " + urls[0]); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { httpclient.getConnectionManager().shutdown(); } return bitmap; } }
在當前的Activity中通過按鈕上的事件響應實現切換View到對應的Activity中去,同時實現Java串行化數據傳遞。MainActivity的代碼如下:
package com.example.sharedemo;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity implements OnClickListener{
public final static String SHARE_BITMAP_COMMAND = "share-image";
public final static String SHARE_TEXT_DATA_COMMAND = "share-text-data";
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupOnClickListener();
}
private void setupOnClickListener() {
Button bitmapBtn = (Button)this.findViewById(R.id.bitmapShareBtn);
bitmapBtn.setTag(SHARE_BITMAP_COMMAND);
bitmapBtn.setOnClickListener(this);
Button textDataBtn = (Button)this.findViewById(R.id.mapShareBtn);
textDataBtn.setTag(SHARE_TEXT_DATA_COMMAND);
textDataBtn.setOnClickListener(this);
final ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);
handler = new Handler()
{
public void handleMessage(Message msg) {
Bitmap bitmap = (Bitmap)msg.obj;
if(bitmap != null)
{
/*
// 為防止原始圖片過大導致內存溢出,這裡先縮小原圖顯示,然後釋放原始Bitmap占用的內存
Bitmap smallBitmap = zoomBitmap(bitmap, bitmap.getWidth()/ 5, bitmap.getHeight() / 5);
// 釋放資源
bitmap.recycle();
// 顯示圖片
imageView.setImageBitmap(smallBitmap);
imageView.invalidate();
*/
imageView.setImageBitmap(bitmap);
}
}
};
ImageLoadTask task = new ImageLoadTask(handler);
task.execute("http://img.blog.csdn.net/20150607143208238");
}
public static Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidth = ((float) width / w);
float scaleHeight = ((float) height / h);
matrix.postScale(scaleWidth, scaleHeight); // 不改變原來圖像大小
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);
return newbmp;
}
@Override
public void onClick(View v) {
Object tag = v.getTag();
Log.i("command", tag.toString());
if(SHARE_BITMAP_COMMAND.equals(tag))
{
Intent intent = new Intent(this.getApplicationContext(), ImageProcessActivity.class);
ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
intent.putExtra("selectedImage", bitmap);
intent.putExtra("name", "lena");
intent.putExtra("description", "超級大美女");
this.startActivity(intent);
}
else if(SHARE_TEXT_DATA_COMMAND.equals(tag))
{
Intent intent = new Intent(this.getApplicationContext(), ImageProcessActivity.class);
ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
// save it first then pass URI
ImageInfoBean dto = new ImageInfoBean();
String uri = createImageFromBitmap(bitmap);
dto.setDescription("超級大美女");
dto.setName("lena");
dto.setUri(uri);
intent.putExtra("tiger", dto);
this.startActivity(intent);
}
}
public String createImageFromBitmap(Bitmap bitmap) {
String fileName = "myImage";
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
FileOutputStream fo = openFileOutput(fileName, Context.MODE_PRIVATE);
fo.write(bytes.toByteArray());
fo.close();
} catch (Exception e) {
e.printStackTrace();
fileName = null;
}
Log.i("fileName", fileName);
return fileName;
}
}
對應另外一個Activity中實現讀取與組裝Bitmap對象顯示的代碼如下:
package com.example.sharedemo;
import java.io.FileNotFoundException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class ImageProcessActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.share_info);
backFillData();
}
private void backFillData() {
Object obj = this.getIntent().getExtras().get("tiger");
ImageView imageView = (ImageView)this.findViewById(R.id.imageView1);
TextView text1 = (TextView)this.findViewById(R.id.textView1);
TextView text2 = (TextView)this.findViewById(R.id.textView2);
try {
if(obj != null && obj instanceof ImageInfoBean)
{
ImageInfoBean dto = (ImageInfoBean)obj;
Bitmap bitmap = BitmapFactory.decodeStream(this.openFileInput(dto.getUri()));
imageView.setImageBitmap(bitmap);
imageView.invalidate(); // refresh
text1.setText("名稱: " + dto.getName());
text2.setText("描述: " + dto.getDescription());
return;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = (Bitmap) this.getIntent().getParcelableExtra("selectedImage");
String name = this.getIntent().getExtras().getString("name");
String description = this.getIntent().getExtras().getString("description");
if(bitmap != null)
{
imageView.setImageBitmap(bitmap);
imageView.invalidate(); // refresh
}
if(name != null)
{
text1.setText("名稱: " + name);
}
if(description != null)
{
text2.setText("描述: " + description);
}
}
}
對應的Java串行化對象類代碼如下:
package com.example.sharedemo;
import java.io.Serializable;
public class ImageInfoBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
private String name;
private String description;
private String uri;
}
最後聲明:
別忘記在Manifest文件添加網絡訪問的權限

將會演示正確的處理結果,顯示如下:

會話失效和PullToRefreshListView,pullrefreshlistview
會話失效和PullToRefreshListView,pullrefreshlistview今天碰到一個一個會話失效的問題,從網上找了個方法可以處理http://blog
自定義控件之創建可以復用的組合控件(三)
自定義控件之創建可以復用的組合控件(三) 前面已學習了兩種自定義控件的實現,分別是自定義控件之對現有控件拓展(一)和 自定義控件之直接繼承View創建全新視圖(二),
Android Ndk中C與JAVA之間的互相調用
Android Ndk中C與JAVA之間的互相調用 本例實現一個簡單的場景: 1、使用C編寫一個方法,接收1個參數,方法中調用Java的方法。 2、Java類中編寫一
手把手搭建自己的android環境,把手搭建android
手把手搭建自己的android環境,把手搭建android最近想學習安卓,不過國內實在被牆的厲害,真是萬裡安裝只被牆。安裝的過程中也出現了幾個問題。所以記錄下來,免得自己
android入門系列- TextView EditText Button ImageView 的簡單應用,textviewedittext
android入門系列- TextView EditText Butto