メディアビューアのロード進捗表示の改善。クラッシュレポート対応
This commit is contained in:
parent
93f40e08a5
commit
2d559a84c0
|
@ -6,10 +6,7 @@
|
||||||
<inspection_tool class="EmptyStatementBody" enabled="false" level="WARNING" enabled_by_default="false">
|
<inspection_tool class="EmptyStatementBody" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
<option name="m_reportEmptyBlocks" value="true" />
|
<option name="m_reportEmptyBlocks" value="true" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
|
<inspection_tool class="FieldCanBeLocal" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
|
|
||||||
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
|
|
||||||
</inspection_tool>
|
|
||||||
<inspection_tool class="NumericOverflow" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="NumericOverflow" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="TryFinallyCanBeTryWithResources" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="TryFinallyCanBeTryWithResources" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
|
|
|
@ -4,12 +4,16 @@ import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
import jp.juggler.subwaytooter.table.SavedAccount;
|
import jp.juggler.subwaytooter.table.SavedAccount;
|
||||||
import jp.juggler.subwaytooter.util.Utils;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AsyncTask customized version:
|
AsyncTask customized version:
|
||||||
|
@ -18,47 +22,83 @@ import jp.juggler.subwaytooter.util.Utils;
|
||||||
- has TootApiClient.
|
- has TootApiClient.
|
||||||
- pass progress message from TootApiClient to ProgressDialog.
|
- pass progress message from TootApiClient to ProgressDialog.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
public abstract class TootApiTask extends AsyncTask< Void, Void, TootApiResult > implements TootApiClient.Callback {
|
public abstract class TootApiTask extends AsyncTask< Void, Void, TootApiResult > implements TootApiClient.Callback {
|
||||||
|
|
||||||
@NonNull protected final TootApiClient client;
|
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess") public static final int PROGRESS_NONE = - 1;
|
@SuppressWarnings("WeakerAccess") public static final int PROGRESS_NONE = - 1;
|
||||||
@SuppressWarnings("WeakerAccess") public static final int PROGRESS_SPINNER = ProgressDialog.STYLE_SPINNER;
|
@SuppressWarnings("WeakerAccess") public static final int PROGRESS_SPINNER = ProgressDialog.STYLE_SPINNER;
|
||||||
@SuppressWarnings("WeakerAccess") public static final int PROGRESS_HORIZONTAL = ProgressDialog.STYLE_HORIZONTAL;
|
@SuppressWarnings("WeakerAccess") public static final int PROGRESS_HORIZONTAL = ProgressDialog.STYLE_HORIZONTAL;
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
private static class ProgressInfo {
|
||||||
public TootApiTask( Activity _activity, SavedAccount access_info, boolean bShowProgress ){
|
|
||||||
this( _activity, access_info, bShowProgress ? PROGRESS_SPINNER : PROGRESS_NONE );
|
// HORIZONTALスタイルの場合、初期メッセージがないと後からメッセージを指定しても表示されない
|
||||||
|
@NonNull String message = " ";
|
||||||
|
|
||||||
|
boolean isIndeterminate = true;
|
||||||
|
int value = 0;
|
||||||
|
int max = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull private WeakReference< Activity > refActivity;
|
||||||
|
@NonNull protected Handler handler;
|
||||||
|
@NonNull protected final TootApiClient client;
|
||||||
|
@NonNull private final ProgressInfo info = new ProgressInfo();
|
||||||
|
@Nullable private ProgressDialog progress;
|
||||||
|
@Nullable private String progress_prefix;
|
||||||
|
|
||||||
|
private final int progress_style;
|
||||||
|
private boolean isAlive = true;
|
||||||
|
private long last_message_shown;
|
||||||
|
|
||||||
|
private static final NumberFormat percent_format;
|
||||||
|
|
||||||
|
static{
|
||||||
|
percent_format = NumberFormat.getPercentInstance();
|
||||||
|
percent_format.setMaximumFractionDigits( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public TootApiTask( Activity _activity, SavedAccount access_info, int progress_style ){
|
public TootApiTask( @NonNull Activity _activity, int progress_style ){
|
||||||
|
this.refActivity = new WeakReference<>( _activity );
|
||||||
|
this.handler = new Handler();
|
||||||
this.client = new TootApiClient( _activity, this );
|
this.client = new TootApiClient( _activity, this );
|
||||||
|
this.progress_style = progress_style;
|
||||||
|
if( progress_style != PROGRESS_NONE ){
|
||||||
|
// ダイアログの遅延表示を実装したけど、すぐにダイアログを出した方が下のUIのタッチ判定を隠せて良いので使わないんだ…
|
||||||
|
// handler.postDelayed( proc_progress_opener ,1000L );
|
||||||
|
proc_progress_opener.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public TootApiTask( @NonNull Activity _activity, SavedAccount access_info, int progress_style ){
|
||||||
|
this( _activity, progress_style );
|
||||||
client.setAccount( access_info );
|
client.setAccount( access_info );
|
||||||
showProgress( _activity, progress_style );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public TootApiTask( Activity _activity, String instance, boolean bShowProgress ){
|
public TootApiTask( @NonNull Activity _activity, String instance, int progress_style ){
|
||||||
this( _activity, instance, bShowProgress ? PROGRESS_SPINNER : PROGRESS_NONE );
|
this( _activity, progress_style );
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
public TootApiTask( Activity _activity, String instance, int progress_style ){
|
|
||||||
this.client = new TootApiClient( _activity, this );
|
|
||||||
client.setInstance( instance );
|
client.setInstance( instance );
|
||||||
showProgress( _activity, progress_style );
|
}
|
||||||
|
|
||||||
|
private static int getDefaultProgressStyle( boolean bShowProgress ){
|
||||||
|
return bShowProgress ? PROGRESS_SPINNER : PROGRESS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public TootApiTask( Activity _activity, boolean bShowProgress ){
|
public TootApiTask( @NonNull Activity _activity, boolean bShowProgress ){
|
||||||
this( _activity, bShowProgress ? PROGRESS_SPINNER : PROGRESS_NONE );
|
this( _activity, getDefaultProgressStyle( bShowProgress ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public TootApiTask( Activity _activity, int progress_style ){
|
public TootApiTask( @NonNull Activity _activity, SavedAccount access_info, boolean bShowProgress ){
|
||||||
this.client = new TootApiClient( _activity, this );
|
this( _activity, access_info, getDefaultProgressStyle( bShowProgress ) );
|
||||||
showProgress( _activity, progress_style );
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public TootApiTask( @NonNull Activity _activity, String instance, boolean bShowProgress ){
|
||||||
|
this( _activity, instance, getDefaultProgressStyle( bShowProgress ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public TootApiTask setProgressPrefix( String s ){
|
public TootApiTask setProgressPrefix( String s ){
|
||||||
|
@ -67,39 +107,7 @@ public abstract class TootApiTask extends AsyncTask< Void, Void, TootApiResult >
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
// implements AsyncTask
|
||||||
@Override public boolean isApiCancelled(){
|
|
||||||
return isCancelled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void publishApiProgress( final String s ){
|
|
||||||
if( progress != null ){
|
|
||||||
Utils.runOnMainThread( new Runnable() {
|
|
||||||
@Override public void run(){
|
|
||||||
progress.setIndeterminate( true );
|
|
||||||
if( ! TextUtils.isEmpty( progress_prefix ) ){
|
|
||||||
progress.setMessage( progress_prefix + "\n" + s );
|
|
||||||
}else{
|
|
||||||
progress.setMessage( s );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publishApiProgressRatio( final int value, final int max ){
|
|
||||||
if( progress != null ){
|
|
||||||
Utils.runOnMainThread( new Runnable() {
|
|
||||||
@Override public void run(){
|
|
||||||
progress.setIndeterminate( false );
|
|
||||||
progress.setProgress( value );
|
|
||||||
progress.setMax( max );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
@Override protected abstract TootApiResult doInBackground( Void... voids );
|
@Override protected abstract TootApiResult doInBackground( Void... voids );
|
||||||
|
|
||||||
|
@ -115,36 +123,39 @@ public abstract class TootApiTask extends AsyncTask< Void, Void, TootApiResult >
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
|
// implements TootApiClient.Callback
|
||||||
|
|
||||||
private ProgressDialog progress;
|
@Override public boolean isApiCancelled(){
|
||||||
private String progress_prefix;
|
return isCancelled();
|
||||||
|
|
||||||
private void showProgress( Activity activity, int progressStyle ){
|
|
||||||
|
|
||||||
if( progressStyle == PROGRESS_NONE ) return;
|
|
||||||
|
|
||||||
//noinspection deprecation
|
|
||||||
this.progress = new ProgressDialog( activity );
|
|
||||||
progress.setCancelable( true );
|
|
||||||
progress.setProgressStyle( progressStyle );
|
|
||||||
progress.setIndeterminate( true );
|
|
||||||
progress.setMax( 1 );
|
|
||||||
if( ! TextUtils.isEmpty( progress_prefix ) ){
|
|
||||||
progress.setMessage( progress_prefix );
|
|
||||||
}else{
|
|
||||||
// HORIZONTALスタイルの場合、初期メッセージがないと後からメッセージを指定しても表示されない
|
|
||||||
progress.setMessage( " " );
|
|
||||||
}
|
|
||||||
progress.setOnCancelListener( new DialogInterface.OnCancelListener() {
|
|
||||||
@Override
|
|
||||||
public void onCancel( DialogInterface dialog ){
|
|
||||||
TootApiTask.this.cancel( true );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
progress.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void publishApiProgress( final String s ){
|
||||||
|
synchronized( this ){
|
||||||
|
info.message = s;
|
||||||
|
info.isIndeterminate = true;
|
||||||
|
}
|
||||||
|
requestShowMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// 内蔵メディアビューアのローディング進捗の表示に使う
|
||||||
|
|
||||||
|
public void publishApiProgressRatio( final int value, final int max ){
|
||||||
|
synchronized( this ){
|
||||||
|
info.isIndeterminate = false;
|
||||||
|
info.value = value;
|
||||||
|
info.max = max;
|
||||||
|
}
|
||||||
|
requestShowMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ダイアログを閉じる
|
||||||
private void dismissProgress(){
|
private void dismissProgress(){
|
||||||
|
synchronized( this ){
|
||||||
|
isAlive = false;
|
||||||
|
}
|
||||||
if( progress != null ){
|
if( progress != null ){
|
||||||
try{
|
try{
|
||||||
progress.dismiss();
|
progress.dismiss();
|
||||||
|
@ -163,4 +174,73 @@ public abstract class TootApiTask extends AsyncTask< Void, Void, TootApiResult >
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ダイアログを開く
|
||||||
|
private final Runnable proc_progress_opener = new Runnable() {
|
||||||
|
@Override public void run(){
|
||||||
|
synchronized( this ){
|
||||||
|
Activity activity = refActivity.get();
|
||||||
|
if( isAlive
|
||||||
|
&& activity != null
|
||||||
|
&& progress == null
|
||||||
|
&& progress_style != PROGRESS_NONE
|
||||||
|
){
|
||||||
|
//noinspection deprecation
|
||||||
|
progress = new ProgressDialog( activity );
|
||||||
|
progress.setCancelable( true );
|
||||||
|
progress.setOnCancelListener( new DialogInterface.OnCancelListener() {
|
||||||
|
@Override public void onCancel( DialogInterface dialog ){
|
||||||
|
TootApiTask.this.cancel( true );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
progress.setProgressStyle( progress_style );
|
||||||
|
showProgressMessage();
|
||||||
|
progress.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ダイアログのメッセージを更新する
|
||||||
|
private void showProgressMessage(){
|
||||||
|
if( progress == null ) return;
|
||||||
|
|
||||||
|
if( ! TextUtils.isEmpty( progress_prefix ) ){
|
||||||
|
progress.setMessage( progress_prefix + ( TextUtils.isEmpty( info.message.trim() ) ? "" : "\n" + info.message ) );
|
||||||
|
}else{
|
||||||
|
progress.setMessage( info.message );
|
||||||
|
}
|
||||||
|
|
||||||
|
progress.setIndeterminate( info.isIndeterminate );
|
||||||
|
if( info.isIndeterminate ){
|
||||||
|
progress.setProgressNumberFormat( null );
|
||||||
|
progress.setProgressPercentFormat( null );
|
||||||
|
}else{
|
||||||
|
progress.setProgress( info.value );
|
||||||
|
progress.setMax( info.max );
|
||||||
|
progress.setProgressNumberFormat( "%1$,d / %2$,d" );
|
||||||
|
progress.setProgressPercentFormat( percent_format );
|
||||||
|
}
|
||||||
|
|
||||||
|
last_message_shown = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 少し後にダイアログのメッセージを更新する
|
||||||
|
// あまり頻繁に更新せず、しかし繰り返し呼ばれ続けても時々は更新したい
|
||||||
|
private void requestShowMessage(){
|
||||||
|
long wait = 100L + last_message_shown - SystemClock.elapsedRealtime();
|
||||||
|
wait = wait < 0L ? 0L : wait > 100L ? 100L : wait;
|
||||||
|
handler.removeCallbacks( proc_progress_message );
|
||||||
|
handler.postDelayed( proc_progress_message, wait );
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Runnable proc_progress_message = new Runnable() {
|
||||||
|
@Override public void run(){
|
||||||
|
synchronized( this ){
|
||||||
|
if( progress != null && progress.isShowing() ){
|
||||||
|
showProgressMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class CustomEmojiCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull final ConcurrentHashMap< String, CacheItem > cache = new ConcurrentHashMap<>();
|
@NonNull final ConcurrentHashMap< String, CacheItem > cache;
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// リクエスト
|
// リクエスト
|
||||||
|
@ -106,6 +106,14 @@ public class CustomEmojiCache {
|
||||||
|
|
||||||
cancelRequest( target_tag );
|
cancelRequest( target_tag );
|
||||||
|
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
if( cache == null ){
|
||||||
|
// java.lang.NullPointerException:
|
||||||
|
// at java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:915)
|
||||||
|
// at jp.juggler.subwaytooter.util.CustomEmojiCache.get (CustomEmojiCache.java:113)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized( cache ){
|
synchronized( cache ){
|
||||||
long now = getNow();
|
long now = getNow();
|
||||||
|
|
||||||
|
@ -122,10 +130,10 @@ public class CustomEmojiCache {
|
||||||
if( time_error != null && now < time_error + ERROR_EXPIRE ){
|
if( time_error != null && now < time_error + ERROR_EXPIRE ){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}catch(Throwable ex){
|
}catch( Throwable ex ){
|
||||||
// NullPointerException at java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:915)
|
// NullPointerException at java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:915)
|
||||||
|
|
||||||
log.trace(ex);
|
log.trace( ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
synchronized( queue ){
|
synchronized( queue ){
|
||||||
|
@ -143,6 +151,7 @@ public class CustomEmojiCache {
|
||||||
public CustomEmojiCache( Context context ){
|
public CustomEmojiCache( Context context ){
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.handler = new Handler( context.getMainLooper() );
|
this.handler = new Handler( context.getMainLooper() );
|
||||||
|
this.cache = new ConcurrentHashMap<>();
|
||||||
this.worker = new Worker();
|
this.worker = new Worker();
|
||||||
worker.start();
|
worker.start();
|
||||||
}
|
}
|
||||||
|
@ -166,7 +175,7 @@ public class CustomEmojiCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
if( request == null ){
|
if( request == null ){
|
||||||
if(DEBUG) log.d( "wait. req_size=%d", req_size );
|
if( DEBUG ) log.d( "wait. req_size=%d", req_size );
|
||||||
waitEx( 86400000L );
|
waitEx( 86400000L );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -175,8 +184,19 @@ public class CustomEmojiCache {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
if( cache == null ){
|
||||||
|
// Fujitsu F-01H(F01H), 2048MB RAM, Android 6.0
|
||||||
|
// java.lang.NullPointerException:
|
||||||
|
// at java.util.concurrent.ConcurrentHashMap.get (ConcurrentHashMap.java:772)
|
||||||
|
// at jp.juggler.subwaytooter.util.CustomEmojiCache$Worker.run (CustomEmojiCache.java:183)
|
||||||
|
waitEx( 1000L );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
long now = getNow();
|
long now = getNow();
|
||||||
int cache_size;
|
int cache_size;
|
||||||
|
|
||||||
synchronized( cache ){
|
synchronized( cache ){
|
||||||
|
|
||||||
// 成功キャッシュ
|
// 成功キャッシュ
|
||||||
|
@ -197,13 +217,14 @@ public class CustomEmojiCache {
|
||||||
//noinspection UnusedAssignment
|
//noinspection UnusedAssignment
|
||||||
cache_size = cache.size();
|
cache_size = cache.size();
|
||||||
}
|
}
|
||||||
if(DEBUG) log.d( "start get image. req_size=%d, cache_size=%d url=%s", req_size, cache_size, request.url );
|
if( DEBUG )
|
||||||
|
log.d( "start get image. req_size=%d, cache_size=%d url=%s", req_size, cache_size, request.url );
|
||||||
|
|
||||||
APNGFrames frames = null;
|
APNGFrames frames = null;
|
||||||
try{
|
try{
|
||||||
byte[] data = App1.getHttpCached( request.url );
|
byte[] data = App1.getHttpCached( request.url );
|
||||||
if( data == null ){
|
if( data == null ){
|
||||||
log.e("get failed. url=%s",request.url );
|
log.e( "get failed. url=%s", request.url );
|
||||||
}else{
|
}else{
|
||||||
frames = decodeAPNG( data, request.url );
|
frames = decodeAPNG( data, request.url );
|
||||||
}
|
}
|
||||||
|
@ -269,10 +290,10 @@ public class CustomEmojiCache {
|
||||||
try{
|
try{
|
||||||
APNGFrames frames = APNGFrames.parseAPNG( new ByteArrayInputStream( data ), 64 );
|
APNGFrames frames = APNGFrames.parseAPNG( new ByteArrayInputStream( data ), 64 );
|
||||||
if( frames == null ){
|
if( frames == null ){
|
||||||
if(DEBUG) log.d("parseAPNG returns null.");
|
if( DEBUG ) log.d( "parseAPNG returns null." );
|
||||||
// fall thru
|
// fall thru
|
||||||
}else if( frames.isSingleFrame() ){
|
}else if( frames.isSingleFrame() ){
|
||||||
if(DEBUG) log.d( "parseAPNG returns single frame." );
|
if( DEBUG ) log.d( "parseAPNG returns single frame." );
|
||||||
// mastodonのstatic_urlが返すPNG画像はAPNGだと透明になってる場合がある。BitmapFactoryでデコードしなおすべき
|
// mastodonのstatic_urlが返すPNG画像はAPNGだと透明になってる場合がある。BitmapFactoryでデコードしなおすべき
|
||||||
frames.dispose();
|
frames.dispose();
|
||||||
// fall thru
|
// fall thru
|
||||||
|
@ -288,7 +309,7 @@ public class CustomEmojiCache {
|
||||||
try{
|
try{
|
||||||
Bitmap b = decodeBitmap( data, 128 );
|
Bitmap b = decodeBitmap( data, 128 );
|
||||||
if( b != null ){
|
if( b != null ){
|
||||||
if(DEBUG) log.d("bitmap decoded.");
|
if( DEBUG ) log.d( "bitmap decoded." );
|
||||||
return new APNGFrames( b );
|
return new APNGFrames( b );
|
||||||
}else{
|
}else{
|
||||||
log.e( "Bitmap decode returns null. %s", url );
|
log.e( "Bitmap decode returns null. %s", url );
|
||||||
|
|
Loading…
Reference in New Issue