在我的Android应用程序中,我正在调用一个Java Web服务,它返回一个Image Blob。我想在ImageView中将其显示为位图。此图像blob是HTML5 Canvas元素的已保存toDataUrl()表示形式。主线程使用execute命令启动AsyncTask内部类作为onclick。这是主线程:
public class MainActivity extends Activity
{
private ImageView outputIv;
public View vue;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setOutputIv((ImageView)findViewById(R.id.imageView1));
}
public void onClickBtn(View v){
vue = v;
new RequestTask(v).execute("http://10.0.2.2:8080/CasosDeUso5/webresources/casosdeusowsport/getimagenes?usuarioId=1");
}
/**
* @return the outputIv
*/
public ImageView getOutputIv() {
return outputIv;
}
/**
* @param outputIv the outputIv to set
*/
public void setOutputIv(ImageView outputIv) {
this.outputIv = outputIv;
}
class RequestTask extends AsyncTask<String, String, String>{
private View rootView;
public RequestTask(View rootView){
this.rootView=rootView;
}
@Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = "STRAWBERRIES";
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
Log.d("info", statusLine.toString());
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.d("OH CRIKEY", e.toString());
} catch (IOException e) {
Log.d("OH CRIKEY", e.toString());
}
Log.d("info", responseString);
return responseString;
}
@Override
protected void onPostExecute(String result) {
//super.onPostExecute(result);
try{
List<Imagen> imgs = Parser.parseByDOM(result);
//Below prints 3280
Log.d("UUYU", String.valueOf(imgs.get(0).getImagen().getRowBytes()));
//Below prints 550
Log.d("UUYU2", String.valueOf(imgs.get(0).getImagen().getHeight()));
//Below prints 820
Log.d("UUYU3", String.valueOf(imgs.get(0).getImagen().getWidth()));
outputIv.setImageBitmap(imgs.get(0).getImagen());
//vue.invalidate();
}catch(Exception e){ e.printStackTrace();
Log.d("ERROR!!", ""+e.getMessage());}
//outputTv.setText(result);
}
/**
* @return the rootView
*/
public View getRootView() {
return rootView;
}
/**
* @param rootView the rootView to set
*/
public void setRootView(View rootView) {
this.rootView = rootView;
}
}
位图具有正确的宽度和高度,似乎有数据。这是我解析Web服务响应String并设置Bitmap的地方,只是为了完整性。所有调试看起来都很好。
public static List<Imagen> parseByDOM(String response) throws ParserConfigurationException, SAXException, IOException{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(response)));
// normalize the document
doc.getDocumentElement().normalize();
// get the root node
NodeList nodeList = doc.getElementsByTagName("return");
Log.d("miaouw", nodeList.toString());
List<Imagen> imgData = new ArrayList<Imagen>();
for(int k = 0; k < nodeList.getLength(); k++){
Node node=nodeList.item(0);
Log.d("miaouw", node.getNodeName());
Imagen img = new Imagen();
try{
for(int i = 0; i < node.getChildNodes().getLength(); i++){
Node temp = node.getChildNodes().item(i);
Log.d("miaouw", temp.getNodeName());
if(temp.getNodeName().equalsIgnoreCase("fechaCreada")){
img.setFechaCreada(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(temp.getTextContent()));
}
else if(temp.getNodeName().equalsIgnoreCase("imagen")){
String encodedImg = temp.getTextContent();
Log.d("vroom", encodedImg); //prints long, correct base64 binary String. If I try to convert it to an image in http://www.freeformatter.com/base64-encoder.html, I get the correct image.
Log.d("toom ", String.valueOf(encodedImg.length())); //prints 19383
byte[] decodedString = Base64.decode(encodedImg, Base64.DEFAULT);
Log.d("woom", decodedString.toString()); //prints B@417b72f0
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
img.setImagen(decodedByte);
}
else if(temp.getNodeName().equalsIgnoreCase("titulo")){
img.setTitulo(temp.getTextContent());
}
}
imgData.add(img);
Log.d("MIAUOW", img.toString()); //prints com.example.android.Imagen@4175ec58
Log.d("noddy", node.toString());
return imgData;
}catch(ParseException e){
Log.d("MEWL", e.getMessage());
}
}
return null;
}
最后,这是我的布局。我将ImageView设置为默认的Android drawable,以确保View正在更新(因为它是Async)。当我单击Test时,src图像消失但它不会被我的位图替换。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Test"
android:onClick="onClickBtn" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:contentDescription="yep"
android:src="@drawable/ic_launcher"/>
</LinearLayout>
这是一个简单的概念证明,但它不起作用。我不明白Bitmap是如何存在的,View更新,但Bitmap不可见。
答案 0 :(得分:0)
在下面的代码中
else if(temp.getNodeName().equalsIgnoreCase("imagen")){
String encodedImg = temp.getTextContent();
Log.d("vroom", encodedImg); //prints long, correct base64 binary String. If I try to convert it to an image in http://www.freeformatter.com/base64-encoder.html, I get the correct image.
Log.d("toom ", String.valueOf(encodedImg.length())); //prints 19383
byte[] decodedString = Base64.decode(encodedImg, Base64.DEFAULT);
Log.d("woom", decodedString.toString()); //prints B@417b72f0
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
img.setImagen(decodedByte);
}
使用
img.setImageBitmap(decodedByte);
我不知道这是不是一个错字,或者你实际上已经把它放了,但如果那也在你的代码中,那就换掉它。
答案 1 :(得分:0)
/**
* @param outputIv the outputIv to set
*/
public void setOutputIv(ImageView outputIv) {
this.outputIv = outputIv;
}
你打电话给:
setOutputIv((ImageView)findViewById(R.id.imageView1));
然后你将this.outputIv的引用放到R.id.imageView1中的那个。您是否尝试将类引用设置为OnCreate()中Layout.xml中指定的类引用?
ImageView outputIv = (ImageView) findViewById(R.id.imageView1);
我想其他你只是让class.outputIv有来自R.id.imageView1的内容,但是这个会显示它的android:src =“@ drawable / ic_launcher”独立于你添加到class.outputIv的内容甚至没有添加到Activity的视图中。
答案 2 :(得分:0)
自我注意:透明与白色不同。
我对ImageView执行了以下操作:
outputIv.setBackgroundColor(Color.WHITE);
一切都很好。