couple of more optimazations on image loading
This commit is contained in:
		
							parent
							
								
									bf2d0d5596
								
							
						
					
					
						commit
						645139eb68
					
				| 
						 | 
					@ -52,6 +52,7 @@
 | 
				
			||||||
	        android:id="@+id/conversation_lastimage"
 | 
						        android:id="@+id/conversation_lastimage"
 | 
				
			||||||
	        android:layout_width="fill_parent"
 | 
						        android:layout_width="fill_parent"
 | 
				
			||||||
	        android:layout_height="36dp"
 | 
						        android:layout_height="36dp"
 | 
				
			||||||
 | 
						        android:background="#333333"
 | 
				
			||||||
	        android:scaleType="centerCrop" />
 | 
						        android:scaleType="centerCrop" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	</LinearLayout>
 | 
						</LinearLayout>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,9 +26,9 @@
 | 
				
			||||||
                android:layout_width="wrap_content"
 | 
					                android:layout_width="wrap_content"
 | 
				
			||||||
                android:layout_height="wrap_content"
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
                android:adjustViewBounds="true"
 | 
					                android:adjustViewBounds="true"
 | 
				
			||||||
                android:maxHeight="288dp"
 | 
					 | 
				
			||||||
                android:maxWidth="288dp"
 | 
					 | 
				
			||||||
                android:paddingBottom="2dp"
 | 
					                android:paddingBottom="2dp"
 | 
				
			||||||
 | 
					                android:scaleType="fitXY"
 | 
				
			||||||
 | 
					                android:background="#333333"
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            <TextView
 | 
					            <TextView
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,8 @@
 | 
				
			||||||
                android:layout_height="wrap_content"
 | 
					                android:layout_height="wrap_content"
 | 
				
			||||||
                android:adjustViewBounds="true"
 | 
					                android:adjustViewBounds="true"
 | 
				
			||||||
                android:paddingBottom="2dp"
 | 
					                android:paddingBottom="2dp"
 | 
				
			||||||
 | 
					                android:scaleType="fitXY"
 | 
				
			||||||
 | 
					                android:background="#333333"
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <TextView
 | 
					            <TextView
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,10 +118,10 @@ public class FileBackend {
 | 
				
			||||||
				.getAbsolutePath());
 | 
									.getAbsolutePath());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Bitmap getThumbnail(Message message, int size)
 | 
						public Bitmap getThumbnail(Message message, int size, boolean cacheOnly)
 | 
				
			||||||
			throws FileNotFoundException {
 | 
								throws FileNotFoundException {
 | 
				
			||||||
		Bitmap thumbnail = thumbnailCache.get(message.getUuid());
 | 
							Bitmap thumbnail = thumbnailCache.get(message.getUuid());
 | 
				
			||||||
		if (thumbnail == null) {
 | 
							if ((thumbnail == null)&&(!cacheOnly)) {
 | 
				
			||||||
			Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
 | 
								Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
 | 
				
			||||||
					.getAbsolutePath());
 | 
										.getAbsolutePath());
 | 
				
			||||||
			if (fullsize == null) {
 | 
								if (fullsize == null) {
 | 
				
			||||||
| 
						 | 
					@ -132,45 +132,6 @@ public class FileBackend {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return thumbnail;
 | 
							return thumbnail;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	public void getThumbnailAsync(final Message message, final int size, ImageView imageView, TextView textView) {
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		Bitmap thumbnail = thumbnailCache.get(message.getUuid());
 | 
					 | 
				
			||||||
		if (thumbnail == null) {
 | 
					 | 
				
			||||||
			final WeakReference<ImageView> image = new WeakReference<ImageView>(imageView);
 | 
					 | 
				
			||||||
			final WeakReference<TextView> text = new WeakReference<TextView>(textView);
 | 
					 | 
				
			||||||
			new Thread(new Runnable() {
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				@Override
 | 
					 | 
				
			||||||
				public void run() {
 | 
					 | 
				
			||||||
					if (image.get()!=null) {
 | 
					 | 
				
			||||||
						image.get().setVisibility(View.GONE);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if (text.get()!=null) {
 | 
					 | 
				
			||||||
						text.get().setVisibility(View.VISIBLE);
 | 
					 | 
				
			||||||
						text.get().setText("loading image");
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					Bitmap fullsize = BitmapFactory.decodeFile(getJingleFile(message)
 | 
					 | 
				
			||||||
							.getAbsolutePath());
 | 
					 | 
				
			||||||
					if (fullsize!=null) {
 | 
					 | 
				
			||||||
						Bitmap thumbnail = resize(fullsize, size);
 | 
					 | 
				
			||||||
						thumbnailCache.put(message.getUuid(), thumbnail);
 | 
					 | 
				
			||||||
						if (image.get()!=null) {
 | 
					 | 
				
			||||||
							image.get().setVisibility(View.VISIBLE);
 | 
					 | 
				
			||||||
							image.get().setImageBitmap(thumbnail);
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						if (text.get()!=null) {
 | 
					 | 
				
			||||||
							text.get().setVisibility(View.GONE);
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}).start();
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			textView.setVisibility(View.GONE);
 | 
					 | 
				
			||||||
			imageView.setVisibility(View.VISIBLE);
 | 
					 | 
				
			||||||
			imageView.setImageBitmap(thumbnail);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void removeFiles(Conversation conversation) {
 | 
						public void removeFiles(Conversation conversation) {
 | 
				
			||||||
		String prefix = context.getFilesDir().getAbsolutePath();
 | 
							String prefix = context.getFilesDir().getAbsolutePath();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -649,42 +649,51 @@ public class ConversationActivity extends XmppActivity {
 | 
				
			||||||
	    private Message message = null;
 | 
						    private Message message = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    public BitmapWorkerTask(ImageView imageView) {
 | 
						    public BitmapWorkerTask(ImageView imageView) {
 | 
				
			||||||
	        // Use a WeakReference to ensure the ImageView can be garbage collected
 | 
					 | 
				
			||||||
	        imageViewReference = new WeakReference<ImageView>(imageView);
 | 
						        imageViewReference = new WeakReference<ImageView>(imageView);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    // Decode image in background.
 | 
					 | 
				
			||||||
	    @Override
 | 
						    @Override
 | 
				
			||||||
	    protected Bitmap doInBackground(Message... params) {
 | 
						    protected Bitmap doInBackground(Message... params) {
 | 
				
			||||||
	        message = params[0];
 | 
						        message = params[0];
 | 
				
			||||||
	        try {
 | 
						        try {
 | 
				
			||||||
				return xmppConnectionService.getFileBackend().getThumbnail(message, (int) (metrics.density * 288));
 | 
									return xmppConnectionService.getFileBackend().getThumbnail(message, (int) (metrics.density * 288),false);
 | 
				
			||||||
			} catch (FileNotFoundException e) {
 | 
								} catch (FileNotFoundException e) {
 | 
				
			||||||
				Log.d("xmppService","file not found!");
 | 
									Log.d("xmppService","file not found!");
 | 
				
			||||||
				return null;
 | 
									return null;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    // Once complete, see if ImageView is still around and set bitmap.
 | 
					 | 
				
			||||||
	    @Override
 | 
						    @Override
 | 
				
			||||||
	    protected void onPostExecute(Bitmap bitmap) {
 | 
						    protected void onPostExecute(Bitmap bitmap) {
 | 
				
			||||||
	        if (imageViewReference != null && bitmap != null) {
 | 
						        if (imageViewReference != null && bitmap != null) {
 | 
				
			||||||
	            final ImageView imageView = imageViewReference.get();
 | 
						            final ImageView imageView = imageViewReference.get();
 | 
				
			||||||
	            if (imageView != null) {
 | 
						            if (imageView != null) {
 | 
				
			||||||
	                imageView.setImageBitmap(bitmap);
 | 
						                imageView.setImageBitmap(bitmap);
 | 
				
			||||||
 | 
						                imageView.setBackgroundColor(0x00000000);
 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	public void loadBitmap(Message message, ImageView imageView) {
 | 
						public void loadBitmap(Message message, ImageView imageView) {
 | 
				
			||||||
	    if (cancelPotentialWork(message, imageView)) {
 | 
							Bitmap bm;
 | 
				
			||||||
	        final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
 | 
							try {
 | 
				
			||||||
	        final AsyncDrawable asyncDrawable =
 | 
								bm = xmppConnectionService.getFileBackend().getThumbnail(message, (int) (metrics.density * 288), true);
 | 
				
			||||||
	                new AsyncDrawable(getResources(), null, task);
 | 
							} catch (FileNotFoundException e) {
 | 
				
			||||||
	        imageView.setImageDrawable(asyncDrawable);
 | 
								bm = null;
 | 
				
			||||||
	        task.execute(message);
 | 
							}
 | 
				
			||||||
	    }
 | 
							if (bm!=null) {
 | 
				
			||||||
 | 
								imageView.setImageBitmap(bm);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
							    if (cancelPotentialWork(message, imageView)) {
 | 
				
			||||||
 | 
							    	imageView.setBackgroundColor(0xff333333);
 | 
				
			||||||
 | 
							        final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
 | 
				
			||||||
 | 
							        final AsyncDrawable asyncDrawable =
 | 
				
			||||||
 | 
							                new AsyncDrawable(getResources(), null, task);
 | 
				
			||||||
 | 
							        imageView.setImageDrawable(asyncDrawable);
 | 
				
			||||||
 | 
							        task.execute(message);
 | 
				
			||||||
 | 
							    }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	public static boolean cancelPotentialWork(Message message, ImageView imageView) {
 | 
						public static boolean cancelPotentialWork(Message message, ImageView imageView) {
 | 
				
			||||||
| 
						 | 
					@ -692,16 +701,12 @@ public class ConversationActivity extends XmppActivity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    if (bitmapWorkerTask != null) {
 | 
						    if (bitmapWorkerTask != null) {
 | 
				
			||||||
	        final Message oldMessage = bitmapWorkerTask.message;
 | 
						        final Message oldMessage = bitmapWorkerTask.message;
 | 
				
			||||||
	        // If bitmapData is not yet set or it differs from the new data
 | 
					 | 
				
			||||||
	        if (oldMessage == null || message != oldMessage) {
 | 
						        if (oldMessage == null || message != oldMessage) {
 | 
				
			||||||
	            // Cancel previous task
 | 
					 | 
				
			||||||
	            bitmapWorkerTask.cancel(true);
 | 
						            bitmapWorkerTask.cancel(true);
 | 
				
			||||||
	        } else {
 | 
						        } else {
 | 
				
			||||||
	            // The same work is already in progress
 | 
					 | 
				
			||||||
	            return false;
 | 
						            return false;
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    // No task associated with the ImageView, or an existing task was cancelled
 | 
					 | 
				
			||||||
	    return true;
 | 
						    return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -301,16 +301,16 @@ public class ConversationFragment extends Fragment {
 | 
				
			||||||
						viewHolder.image.setVisibility(View.VISIBLE);
 | 
											viewHolder.image.setVisibility(View.VISIBLE);
 | 
				
			||||||
						String[] params = item.getBody().split(",");
 | 
											String[] params = item.getBody().split(",");
 | 
				
			||||||
			        	if (params.length==3) {
 | 
								        	if (params.length==3) {
 | 
				
			||||||
			        		int target = (int) (metrics.density * 288);
 | 
								        		double target = metrics.density * 288;
 | 
				
			||||||
			        		int w = Integer.parseInt(params[1]);
 | 
								        		int w = Integer.parseInt(params[1]);
 | 
				
			||||||
			        		int h = Integer.parseInt(params[2]);
 | 
								        		int h = Integer.parseInt(params[2]);
 | 
				
			||||||
			        		int scalledW;
 | 
								        		int scalledW;
 | 
				
			||||||
			    			int scalledH;
 | 
								    			int scalledH;
 | 
				
			||||||
			    			if (w <= h) {
 | 
								    			if (w <= h) {
 | 
				
			||||||
			    				scalledW = (int) (w / ((double) h / target));
 | 
								    				scalledW = (int) (w / ((double) h / target));
 | 
				
			||||||
			    				scalledH = target;
 | 
								    				scalledH = (int) target;
 | 
				
			||||||
			    			} else {
 | 
								    			} else {
 | 
				
			||||||
			    				scalledW = target;
 | 
								    				scalledW = (int)  target;
 | 
				
			||||||
			    				scalledH = (int) (h / ((double) w / target));
 | 
								    				scalledH = (int) (h / ((double) w / target));
 | 
				
			||||||
			    			}
 | 
								    			}
 | 
				
			||||||
			        		viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams(scalledW, scalledH));
 | 
								        		viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams(scalledW, scalledH));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ import java.util.Iterator;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Map.Entry;
 | 
					import java.util.Map.Entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.graphics.BitmapFactory;
 | 
				
			||||||
import android.util.Log;
 | 
					import android.util.Log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import eu.siacs.conversations.entities.Account;
 | 
					import eu.siacs.conversations.entities.Account;
 | 
				
			||||||
| 
						 | 
					@ -78,10 +79,16 @@ public class JingleConnection {
 | 
				
			||||||
				if (acceptedAutomatically) {
 | 
									if (acceptedAutomatically) {
 | 
				
			||||||
					message.markUnread();
 | 
										message.markUnread();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									BitmapFactory.Options options = new BitmapFactory.Options();
 | 
				
			||||||
 | 
									options.inJustDecodeBounds = true;
 | 
				
			||||||
 | 
									BitmapFactory.decodeFile(file.getAbsolutePath(),options);
 | 
				
			||||||
 | 
									int imageHeight = options.outHeight;
 | 
				
			||||||
 | 
									int imageWidth = options.outWidth;
 | 
				
			||||||
 | 
									message.setBody(""+file.getSize()+","+imageWidth+","+imageHeight);
 | 
				
			||||||
				mXmppConnectionService.databaseBackend.createMessage(message);
 | 
									mXmppConnectionService.databaseBackend.createMessage(message);
 | 
				
			||||||
				mXmppConnectionService.markMessage(message, Message.STATUS_RECIEVED);
 | 
									mXmppConnectionService.markMessage(message, Message.STATUS_RECIEVED);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum());
 | 
								Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum()+" "+message.getBody());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
| 
						 | 
					@ -197,7 +204,7 @@ public class JingleConnection {
 | 
				
			||||||
	public void init(Account account, JinglePacket packet) {
 | 
						public void init(Account account, JinglePacket packet) {
 | 
				
			||||||
		this.status = STATUS_INITIATED;
 | 
							this.status = STATUS_INITIATED;
 | 
				
			||||||
		Conversation conversation = this.mXmppConnectionService.findOrCreateConversation(account, packet.getFrom().split("/")[0], false);
 | 
							Conversation conversation = this.mXmppConnectionService.findOrCreateConversation(account, packet.getFrom().split("/")[0], false);
 | 
				
			||||||
		this.message = new Message(conversation, "receiving image file", Message.ENCRYPTION_NONE);
 | 
							this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
 | 
				
			||||||
		this.message.setType(Message.TYPE_IMAGE);
 | 
							this.message.setType(Message.TYPE_IMAGE);
 | 
				
			||||||
		this.message.setStatus(Message.STATUS_RECEIVED_OFFER);
 | 
							this.message.setStatus(Message.STATUS_RECEIVED_OFFER);
 | 
				
			||||||
		this.message.setJingleConnection(this);
 | 
							this.message.setJingleConnection(this);
 | 
				
			||||||
| 
						 | 
					@ -230,6 +237,7 @@ public class JingleConnection {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (supportedFile) {
 | 
									if (supportedFile) {
 | 
				
			||||||
					this.file.setExpectedSize(Long.parseLong(fileSize.getContent()));
 | 
										this.file.setExpectedSize(Long.parseLong(fileSize.getContent()));
 | 
				
			||||||
 | 
										message.setBody(""+this.file.getExpectedSize());
 | 
				
			||||||
					conversation.getMessages().add(message);
 | 
										conversation.getMessages().add(message);
 | 
				
			||||||
					if (this.file.getExpectedSize()<=this.mJingleConnectionManager.getAutoAcceptFileSize()) {
 | 
										if (this.file.getExpectedSize()<=this.mJingleConnectionManager.getAutoAcceptFileSize()) {
 | 
				
			||||||
						Log.d("xmppService","auto accepting file from "+packet.getFrom());
 | 
											Log.d("xmppService","auto accepting file from "+packet.getFrom());
 | 
				
			||||||
| 
						 | 
					@ -413,7 +421,7 @@ public class JingleConnection {
 | 
				
			||||||
			this.status = STATUS_TRANSMITTING;
 | 
								this.status = STATUS_TRANSMITTING;
 | 
				
			||||||
			if (connection.needsActivation()) {
 | 
								if (connection.needsActivation()) {
 | 
				
			||||||
				if (connection.getCandidate().isOurs()) {
 | 
									if (connection.getCandidate().isOurs()) {
 | 
				
			||||||
					Log.d("xmppService","candidate "+connection.getCandidate().getCid()+" was our proxy and needs activation");
 | 
										Log.d("xmppService","candidate "+connection.getCandidate().getCid()+" was our proxy. going to activate");
 | 
				
			||||||
					IqPacket activation = new IqPacket(IqPacket.TYPE_SET);
 | 
										IqPacket activation = new IqPacket(IqPacket.TYPE_SET);
 | 
				
			||||||
					activation.setTo(connection.getCandidate().getJid());
 | 
										activation.setTo(connection.getCandidate().getJid());
 | 
				
			||||||
					activation.query("http://jabber.org/protocol/bytestreams").setAttribute("sid", this.getSessionId());
 | 
										activation.query("http://jabber.org/protocol/bytestreams").setAttribute("sid", this.getSessionId());
 | 
				
			||||||
| 
						 | 
					@ -430,6 +438,8 @@ public class JingleConnection {
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										Log.d("xmppService","candidate "+connection.getCandidate().getCid()+" was a proxy. waiting for other party to activate");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if (initiator.equals(account.getFullJid())) {
 | 
									if (initiator.equals(account.getFullJid())) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue