mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 20:59:54 +01:00
Fix potential NPE when getting soft reference.
This commit is contained in:
@@ -8,12 +8,14 @@ import android.graphics.Paint;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.UiThread;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.BaseActivity;
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
@@ -38,6 +40,8 @@ import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
|
|||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
public class EmojiProvider {
|
public class EmojiProvider {
|
||||||
|
|
||||||
private static volatile EmojiProvider INSTANCE = null;
|
private static volatile EmojiProvider INSTANCE = null;
|
||||||
@@ -64,7 +68,7 @@ public class EmojiProvider {
|
|||||||
private static final int EMOJI_PER_ROW = 32;
|
private static final int EMOJI_PER_ROW = 32;
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final float decodeScale, verticalPad;
|
private final float decodeScale;
|
||||||
private final List<EmojiPageModel> staticPages;
|
private final List<EmojiPageModel> staticPages;
|
||||||
|
|
||||||
static EmojiProvider getInstance(Context context) {
|
static EmojiProvider getInstance(Context context) {
|
||||||
@@ -86,7 +90,6 @@ public class EmojiProvider {
|
|||||||
float drawerSize =
|
float drawerSize =
|
||||||
context.getResources().getDimension(R.dimen.emoji_drawer_size);
|
context.getResources().getDimension(R.dimen.emoji_drawer_size);
|
||||||
decodeScale = Math.min(1f, drawerSize / EMOJI_RAW_HEIGHT);
|
decodeScale = Math.min(1f, drawerSize / EMOJI_RAW_HEIGHT);
|
||||||
verticalPad = EMOJI_VERT_PAD * this.decodeScale;
|
|
||||||
staticPages = EmojiPages.getPages(context);
|
staticPages = EmojiPages.getPages(context);
|
||||||
for (EmojiPageModel page : staticPages) {
|
for (EmojiPageModel page : staticPages) {
|
||||||
if (page.hasSpriteMap()) {
|
if (page.hasSpriteMap()) {
|
||||||
@@ -100,8 +103,8 @@ public class EmojiProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
Spannable emojify(@Nullable CharSequence text,
|
@UiThread
|
||||||
@NonNull TextView tv) {
|
Spannable emojify(@Nullable CharSequence text, TextView tv) {
|
||||||
if (text == null) return null;
|
if (text == null) return null;
|
||||||
Matcher matches = EMOJI_RANGE.matcher(text);
|
Matcher matches = EMOJI_RANGE.matcher(text);
|
||||||
SpannableStringBuilder builder = new SpannableStringBuilder(text);
|
SpannableStringBuilder builder = new SpannableStringBuilder(text);
|
||||||
@@ -118,12 +121,13 @@ public class EmojiProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@UiThread
|
||||||
Drawable getEmojiDrawable(int emojiCode) {
|
Drawable getEmojiDrawable(int emojiCode) {
|
||||||
return getEmojiDrawable(offsets.get(emojiCode));
|
return getEmojiDrawable(offsets.get(emojiCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Drawable getEmojiDrawable(DrawInfo drawInfo) {
|
private Drawable getEmojiDrawable(@Nullable DrawInfo drawInfo) {
|
||||||
if (drawInfo == null) {
|
if (drawInfo == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -154,10 +158,10 @@ public class EmojiProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class EmojiDrawable extends Drawable {
|
static class EmojiDrawable extends Drawable {
|
||||||
|
|
||||||
private final DrawInfo info;
|
private final DrawInfo info;
|
||||||
private final float intrinsicWidth, intrinsicHeight;
|
private final float intrinsicWidth, intrinsicHeight, verticalPad;
|
||||||
|
|
||||||
private Bitmap bmp;
|
private Bitmap bmp;
|
||||||
|
|
||||||
@@ -165,6 +169,7 @@ public class EmojiProvider {
|
|||||||
this.info = info;
|
this.info = info;
|
||||||
intrinsicWidth = EMOJI_RAW_WIDTH * decodeScale;
|
intrinsicWidth = EMOJI_RAW_WIDTH * decodeScale;
|
||||||
intrinsicHeight = EMOJI_RAW_HEIGHT * decodeScale;
|
intrinsicHeight = EMOJI_RAW_HEIGHT * decodeScale;
|
||||||
|
verticalPad = EMOJI_VERT_PAD * decodeScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -178,7 +183,7 @@ public class EmojiProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(@NonNull Canvas canvas) {
|
public void draw(Canvas canvas) {
|
||||||
if (bmp == null) {
|
if (bmp == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -212,7 +217,7 @@ public class EmojiProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setColorFilter(ColorFilter cf) {
|
public void setColorFilter(@Nullable ColorFilter cf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,49 +250,46 @@ public class EmojiProvider {
|
|||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
private ListenableFutureTask<Bitmap> get() {
|
private ListenableFutureTask<Bitmap> get() {
|
||||||
if (bitmapReference != null && bitmapReference.get() != null) {
|
if (bitmapReference != null) {
|
||||||
return new ListenableFutureTask<>(bitmapReference.get());
|
Bitmap bitmap = bitmapReference.get();
|
||||||
} else if (task != null) {
|
if (bitmap != null) return new ListenableFutureTask<>(bitmap);
|
||||||
return task;
|
|
||||||
} else {
|
|
||||||
Callable<Bitmap> callable = new Callable<Bitmap>() {
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public Bitmap call() throws Exception {
|
|
||||||
try {
|
|
||||||
if (LOG.isLoggable(INFO))
|
|
||||||
LOG.info("Loading page " + model.getSprite());
|
|
||||||
return loadPage();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
LOG.log(WARNING, ioe.toString(), ioe);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
task = new ListenableFutureTask<>(callable);
|
|
||||||
new AsyncTask<Void, Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params) {
|
|
||||||
task.run();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void aVoid) {
|
|
||||||
task = null;
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
}
|
}
|
||||||
|
if (task != null) return task;
|
||||||
|
Callable<Bitmap> callable = new Callable<Bitmap>() {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public Bitmap call() throws Exception {
|
||||||
|
if (LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Loading page " + model.getSprite());
|
||||||
|
return loadPage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
task = new ListenableFutureTask<>(callable);
|
||||||
|
new AsyncTask<Void, Void, Void>() {
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... params) {
|
||||||
|
task.run();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void aVoid) {
|
||||||
|
task = null;
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap loadPage() throws IOException {
|
private Bitmap loadPage() throws IOException {
|
||||||
if (bitmapReference != null && bitmapReference.get() != null)
|
if (bitmapReference != null) {
|
||||||
return bitmapReference.get();
|
Bitmap bitmap = bitmapReference.get();
|
||||||
|
if (bitmap != null) return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Bitmap bitmap = BitmapUtil.createScaledBitmap(context,
|
Bitmap bitmap = BitmapUtil.createScaledBitmap(context,
|
||||||
"file:///android_asset/" + model.getSprite(),
|
"file:///android_asset/" + model.getSprite(),
|
||||||
decodeScale);
|
decodeScale);
|
||||||
bitmapReference = new SoftReference<>(bitmap);
|
bitmapReference = new SoftReference<>(bitmap);
|
||||||
|
|||||||
Reference in New Issue
Block a user