1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-02 17:56:56 +01:00

make media decoding faster

This commit is contained in:
Mariotaku Lee 2016-04-30 13:35:35 +08:00
parent a3c0138643
commit 004f26ad98
36 changed files with 65 additions and 567 deletions

View File

@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0'
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath('fr.avianey.androidsvgdrawable:gradle-plugin:3.0.0') {
// should be excluded to avoid conflict

View File

@ -44,5 +44,7 @@ dependencies {
compile 'com.github.mariotaku.RestFu:library:0.9.27'
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.2'
compile 'com.github.mariotaku.ObjectCursor:core:0.9.7'
compile 'com.github.mariotaku.CommonsLibrary:objectcursor:0.9.4'
compile 'com.github.mariotaku.CommonsLibrary:logansquare:0.9.4'
compile fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -1,36 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.bluelinelabs.logansquare;
import java.lang.reflect.Type;
/**
* Created by mariotaku on 15/12/13.
*/
public class Twidere_ParameterizedTypeAccessor {
private Twidere_ParameterizedTypeAccessor() {
}
public static <T> ParameterizedType<T> create(Type type) {
return new ParameterizedType.ConcreteParameterizedType<>(type);
}
}

View File

@ -27,11 +27,11 @@ import android.support.annotation.StringDef;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.draft.ActionExtra;
import org.mariotaku.twidere.model.util.DraftExtrasConverter;
import org.mariotaku.twidere.model.util.LoganSquareCursorFieldConverter;
import org.mariotaku.twidere.model.util.UserKeysCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;

View File

@ -30,10 +30,10 @@ import com.bluelinelabs.logansquare.annotation.OnJsonParseComplete;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
import org.mariotaku.library.objectcursor.annotation.AfterCursorObjectCreated;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.LoganSquareCursorFieldConverter;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;

View File

@ -29,9 +29,9 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.LoganSquareCursorFieldConverter;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.model.util.UserKeysConverter;

View File

@ -28,11 +28,11 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.model.util.LoganSquareCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import java.util.Arrays;

View File

@ -31,10 +31,10 @@ import com.bluelinelabs.logansquare.annotation.OnJsonParseComplete;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
import org.mariotaku.library.objectcursor.annotation.AfterCursorObjectCreated;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.LoganSquareCursorFieldConverter;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;

View File

@ -28,10 +28,10 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
import org.mariotaku.commons.objectcursor.LoganSquareCursorFieldConverter;
import org.mariotaku.library.objectcursor.annotation.AfterCursorObjectCreated;
import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.LoganSquareCursorFieldConverter;
import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;

View File

@ -1,89 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.util;
import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import org.mariotaku.library.objectcursor.converter.CursorFieldConverter;
import java.lang.reflect.ParameterizedType;
/**
* Created by mariotaku on 15/11/27.
*/
public abstract class AbsArrayCursorFieldConverter<T> implements CursorFieldConverter<T[]> {
@Override
public final T[] parseField(Cursor cursor, int columnIndex, ParameterizedType fieldType) {
final String string = cursor.getString(columnIndex);
if (TextUtils.isEmpty(string)) return null;
T[] temp = newArray(0);
int len = 0;
int offset = 0;
try {
while (true) {
int index = string.indexOf(',', offset);
if (index == -1) {
temp = putElement(temp, parseItem(string.substring(offset)), len++);
T[] out = newArray(len);
System.arraycopy(temp, 0, out, 0, len);
return out;
} else {
temp = putElement(temp, parseItem(string.substring(offset, index)), len++);
offset = (index + 1);
}
}
} catch (NumberFormatException e) {
return null;
}
}
@Override
public final void writeField(ContentValues values, T[] object, String columnName, ParameterizedType fieldType) {
if (object == null) return;
final StringBuilder sb = new StringBuilder();
for (int i = 0, j = object.length; i < j; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(object[i]);
}
values.put(columnName, sb.toString());
}
protected abstract T[] newArray(int size);
protected abstract T parseItem(String s);
private T[] putElement(T[] array, T element, int index) {
T[] out;
if (index < array.length) {
out = array;
} else {
out = newArray(Math.max(1, array.length) * 2);
System.arraycopy(array, 0, out, 0, array.length);
}
out[index] = element;
return out;
}
}

View File

@ -12,7 +12,7 @@ import org.mariotaku.twidere.model.draft.ActionExtra;
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtra;
import org.mariotaku.twidere.model.draft.UpdateStatusActionExtra;
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;

View File

@ -1,124 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.util;
import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import com.bluelinelabs.logansquare.JsonMapper;
import org.mariotaku.library.objectcursor.converter.CursorFieldConverter;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* Created by mariotaku on 15/11/27.
*/
public class LoganSquareCursorFieldConverter implements CursorFieldConverter<Object> {
@Override
public Object parseField(Cursor cursor, int columnIndex, ParameterizedType fieldType) {
try {
return getObject(cursor, columnIndex, fieldType);
} catch (IOException e) {
return null;
}
}
@Override
public void writeField(ContentValues values, Object object, String columnName, ParameterizedType fieldType) {
try {
writeObject(values, object, columnName, fieldType);
} catch (IOException ignored) {
}
}
private <T> void writeObject(ContentValues values, T object, String columnName, ParameterizedType fieldType) throws IOException {
if (object == null) return;
if (isArray(fieldType)) {
final Class<?> component = getArrayComponent(fieldType);
//noinspection unchecked
JsonMapper<Object> mapper = (JsonMapper<Object>) LoganSquareMapperFinder.mapperFor(component);
values.put(columnName, mapper.serialize(Arrays.asList((Object[]) object)));
} else if (fieldType.getRawType() == List.class) {
JsonMapper<Object> mapper = LoganSquareMapperFinder.mapperFor(fieldType.getActualTypeArguments()[0]);
//noinspection unchecked
values.put(columnName, mapper.serialize((List) object));
} else if (fieldType.getRawType() == Map.class) {
JsonMapper<Object> mapper = LoganSquareMapperFinder.mapperFor(fieldType.getActualTypeArguments()[1]);
//noinspection unchecked
values.put(columnName, mapper.serialize((Map) object));
} else {
JsonMapper<T> mapper = LoganSquareMapperFinder.mapperFor(fieldType);
values.put(columnName, mapper.serialize(object));
}
}
private <T> T getObject(Cursor cursor, int columnIndex, ParameterizedType fieldType) throws IOException {
final String string = cursor.getString(columnIndex);
if (TextUtils.isEmpty(string)) return null;
if (isArray(fieldType)) {
final Class<?> component = getArrayComponent(fieldType);
//noinspection unchecked
JsonMapper<Object> mapper = (JsonMapper<Object>) LoganSquareMapperFinder.mapperFor(component);
final List<Object> list = mapper.parseList(string);
//noinspection unchecked
return (T) list.toArray((Object[]) Array.newInstance(component, list.size()));
} else if (fieldType.getRawType() == List.class) {
JsonMapper<Object> mapper = LoganSquareMapperFinder.mapperFor(fieldType.getActualTypeArguments()[0]);
//noinspection unchecked
return (T) mapper.parseList(string);
} else if (fieldType.getRawType() == Map.class) {
JsonMapper<Object> mapper = LoganSquareMapperFinder.mapperFor(fieldType.getActualTypeArguments()[1]);
//noinspection unchecked
return (T) mapper.parseMap(string);
} else {
JsonMapper<T> mapper = LoganSquareMapperFinder.mapperFor(fieldType);
return mapper.parse(string);
}
}
private boolean isArray(Type type) {
if (type instanceof Class) {
return ((Class) type).isArray();
} else if (type instanceof ParameterizedType) {
return isArray(((ParameterizedType) type).getRawType());
}
return false;
}
private Class getArrayComponent(Type type) {
if (type instanceof Class) {
if (((Class) type).isArray()) {
return ((Class) type).getComponentType();
}
} else if (type instanceof ParameterizedType) {
return getArrayComponent(((ParameterizedType) type).getRawType());
}
throw new UnsupportedOperationException();
}
}

View File

@ -1,84 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.model.util;
import android.content.ContentValues;
import android.database.Cursor;
import android.text.TextUtils;
import org.mariotaku.library.objectcursor.converter.CursorFieldConverter;
import java.lang.reflect.ParameterizedType;
/**
* Created by mariotaku on 15/11/27.
*/
public class LongArrayCursorFieldConverter implements CursorFieldConverter<long[]> {
@Override
public long[] parseField(Cursor cursor, int columnIndex, ParameterizedType fieldType) {
final String string = cursor.getString(columnIndex);
if (TextUtils.isEmpty(string)) return null;
long[] temp = new long[0];
int len = 0;
int offset = 0;
try {
while (true) {
int index = string.indexOf(',', offset);
if (index == -1) {
temp = putElement(temp, Long.parseLong(string.substring(offset)), len++);
long[] out = new long[len];
System.arraycopy(temp, 0, out, 0, len);
return out;
} else {
temp = putElement(temp, Long.parseLong(string.substring(offset, index)), len++);
offset = (index + 1);
}
}
} catch (NumberFormatException e) {
return null;
}
}
@Override
public void writeField(ContentValues values, long[] object, String columnName, ParameterizedType fieldType) {
if (object == null) return;
final StringBuilder sb = new StringBuilder();
for (int i = 0, j = object.length; i < j; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(object[i]);
}
values.put(columnName, sb.toString());
}
private static long[] putElement(long[] array, long element, int index) {
long[] out;
if (index < array.length) {
out = array;
} else {
out = new long[Math.max(1, array.length) * 2];
System.arraycopy(array, 0, out, 0, array.length);
}
out[index] = element;
return out;
}
}

View File

@ -1,5 +1,6 @@
package org.mariotaku.twidere.model.util;
import org.mariotaku.commons.objectcursor.AbsArrayCursorFieldConverter;
import org.mariotaku.twidere.model.UserKey;
/**

View File

@ -1,79 +0,0 @@
package org.mariotaku.twidere.util;
import com.bluelinelabs.logansquare.JsonMapper;
import com.bluelinelabs.logansquare.LoganSquare;
import com.bluelinelabs.logansquare.ParameterizedType;
import com.bluelinelabs.logansquare.Twidere_ParameterizedTypeAccessor;
import org.mariotaku.twidere.common.BuildConfig;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* Created by mariotaku on 16/2/19.
*/
public class LoganSquareMapperFinder {
private static final ExecutorService pool = Executors.newSingleThreadExecutor();
private LoganSquareMapperFinder() {
}
public static <T> JsonMapper<T> mapperFor(Class<T> cls) throws ClassLoaderDeadLockException {
return mapperFor(Twidere_ParameterizedTypeAccessor.<T>create(cls));
}
public static <T> JsonMapper<T> mapperFor(Type type) throws ClassLoaderDeadLockException {
return mapperFor(Twidere_ParameterizedTypeAccessor.<T>create(type));
}
public static <T> JsonMapper<T> mapperFor(final ParameterizedType<T> type) throws ClassLoaderDeadLockException {
final Future<JsonMapper<T>> future = pool.submit(new Callable<JsonMapper<T>>() {
@Override
public JsonMapper<T> call() {
return LoganSquare.mapperFor(type);
}
});
final JsonMapper<T> mapper;
//noinspection TryWithIdenticalCatches
try {
mapper = future.get(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
if (BuildConfig.DEBUG) {
throw new RuntimeException(e);
}
BugReporter.logException(e);
throw new ClassLoaderDeadLockException(e);
}
return mapper;
}
public static class ClassLoaderDeadLockException extends IOException {
public ClassLoaderDeadLockException() {
super();
}
public ClassLoaderDeadLockException(String detailMessage) {
super(detailMessage);
}
public ClassLoaderDeadLockException(String message, Throwable cause) {
super(message, cause);
}
public ClassLoaderDeadLockException(Throwable cause) {
super(cause);
}
}
}

View File

@ -11,7 +11,7 @@ import org.mariotaku.twidere.model.MediaUploadResult;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
import org.mariotaku.twidere.model.UploaderMediaItem;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import java.io.IOException;
import java.lang.ref.WeakReference;
@ -26,6 +26,7 @@ public abstract class MediaUploaderService extends Service {
private final MediaUploaderStub mBinder = new MediaUploaderStub(this);
@Override
public final IBinder onBind(final Intent intent) {
return mBinder;
}

View File

@ -11,7 +11,7 @@ import org.mariotaku.twidere.model.UserKey;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableStatusUpdate;
import org.mariotaku.twidere.model.StatusShortenResult;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import java.io.IOException;
import java.lang.ref.WeakReference;
@ -24,6 +24,7 @@ import java.lang.ref.WeakReference;
public abstract class StatusShortenerService extends Service {
private final StatusShortenerStub mBinder = new StatusShortenerStub(this);
@Override
public final IBinder onBind(final Intent intent) {
return mBinder;
}

View File

@ -1,100 +0,0 @@
package org.mariotaku.twidere.model.util;
import android.content.ContentValues;
import android.database.MatrixCursor;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.junit.Test;
import org.mariotaku.twidere.util.JsonSerializer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/**
* Created by mariotaku on 16/2/19.
*/
public class LoganSquareCursorFieldConverterTest {
private final LoganSquareCursorFieldConverter converter = new LoganSquareCursorFieldConverter();
private final Model jsonObject = new Model("a");
private final Model[] jsonArray = {new Model("a"), new Model("b"), new Model("c")};
private final List<Model> jsonList = Arrays.asList(jsonArray);
private final Map<String, Model> jsonMap = Collections.singletonMap("key", new Model("value"));
@Test
public void testParseField() throws Exception {
final String[] columns = {"json_object", "json_array", "json_list", "json_map"};
MatrixCursor cursor = new MatrixCursor(columns);
cursor.addRow(new String[]{
JsonSerializer.serialize(jsonObject, Model.class),
JsonSerializer.serialize(jsonArray, Model.class),
JsonSerializer.serialize(jsonList, Model.class),
JsonSerializer.serialize(jsonMap, Model.class)
});
cursor.moveToFirst();
assertEquals(jsonObject, converter.parseField(cursor, 0, TypeUtils.parameterize(Model.class)));
assertArrayEquals(jsonArray, (Model[]) converter.parseField(cursor, 1, TypeUtils.parameterize(Model[].class)));
assertEquals((Object) jsonList, converter.parseField(cursor, 2, TypeUtils.parameterize(List.class, Model.class)));
assertEquals((Object) jsonMap, converter.parseField(cursor, 3, TypeUtils.parameterize(Map.class, String.class, Model.class)));
}
@Test
public void testWriteField() throws Exception {
final ContentValues contentValues = new ContentValues();
converter.writeField(contentValues, jsonObject, "json_object", TypeUtils.parameterize(Model.class));
converter.writeField(contentValues, jsonArray, "json_array", TypeUtils.parameterize(Model[].class));
converter.writeField(contentValues, jsonList, "json_list", TypeUtils.parameterize(List.class, Model.class));
converter.writeField(contentValues, jsonMap, "json_map", TypeUtils.parameterize(Map.class, String.class, Model.class));
assertEquals(JsonSerializer.serialize(jsonObject, Model.class), contentValues.getAsString("json_object"));
assertEquals(JsonSerializer.serialize(jsonArray, Model.class), contentValues.getAsString("json_array"));
assertEquals(JsonSerializer.serialize(jsonList, Model.class), contentValues.getAsString("json_list"));
assertEquals(JsonSerializer.serialize(jsonMap, Model.class), contentValues.getAsString("json_map"));
}
@JsonObject
public static class Model {
@JsonField(name = "field")
String field;
public Model() {
}
public Model(String field) {
this.field = field;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Model model = (Model) o;
return !(field != null ? !field.equals(model.field) : model.field != null);
}
@Override
public int hashCode() {
return field != null ? field.hashCode() : 0;
}
}
}

View File

@ -1,32 +0,0 @@
package org.mariotaku.twidere.model.util;
import android.database.MatrixCursor;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNull;
/**
* Created by mariotaku on 16/2/24.
*/
public class LongArrayConverterTest {
private final LongArrayCursorFieldConverter converter = new LongArrayCursorFieldConverter();
@Test
public void testParseField() throws Exception {
MatrixCursor cursor = new MatrixCursor(new String[]{"a", "b", "c", "d"});
cursor.addRow(new String[]{"1,2,3,4", "5,6,7", "8,", ""});
cursor.moveToFirst();
assertArrayEquals(new long[]{1, 2, 3, 4}, converter.parseField(cursor, 0, TypeUtils.parameterize(long[].class)));
assertArrayEquals(new long[]{5, 6, 7}, converter.parseField(cursor, 1, TypeUtils.parameterize(long[].class)));
assertNull(converter.parseField(cursor, 2, TypeUtils.parameterize(long[].class)));
assertNull(converter.parseField(cursor, 3, TypeUtils.parameterize(long[].class)));
}
@Test
public void testWriteField() throws Exception {
}
}

View File

@ -755,7 +755,7 @@ public final class MediaViewerActivity extends BaseActivity implements Constants
decodeBitmap(cr, uri, o);
final DisplayMetrics dm = context.getResources().getDisplayMetrics();
final int targetSize = Math.min(1024, Math.max(dm.widthPixels, dm.heightPixels));
final double sizeRatio = Math.ceil(Math.min(o.outHeight, o.outWidth) / (double) targetSize);
final double sizeRatio = Math.ceil(Math.max(o.outHeight, o.outWidth) / (double) targetSize);
o.inSampleSize = TwidereMathUtils.nextPowerOf2((int) Math.max(1, sizeRatio));
o.inJustDecodeBounds = false;
final Bitmap bitmap = decodeBitmap(cr, uri, o);

View File

@ -37,7 +37,7 @@ import org.mariotaku.twidere.api.twitter.model.User;
import org.mariotaku.twidere.api.twitter.model.UserList;
import org.mariotaku.twidere.api.twitter.model.Warning;
import org.mariotaku.twidere.api.twitter.util.CRLFLineReader;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import java.io.IOException;
import java.io.InputStreamReader;

View File

@ -35,7 +35,7 @@ import org.mariotaku.twidere.api.twitter.TwitterException;
import org.mariotaku.twidere.api.twitter.auth.OAuthToken;
import org.mariotaku.twidere.api.twitter.model.ResponseCode;
import org.mariotaku.twidere.api.twitter.model.TwitterResponse;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import java.io.IOException;
import java.lang.reflect.Type;

View File

@ -20,6 +20,7 @@ import org.mariotaku.twidere.adapter.DummyItemAdapter;
import org.mariotaku.twidere.adapter.VariousItemsAdapter;
import org.mariotaku.twidere.adapter.decorator.DividerItemDecoration;
import org.mariotaku.twidere.adapter.iface.IUsersAdapter;
import org.mariotaku.twidere.model.ParcelableMedia;
import org.mariotaku.twidere.model.ParcelableStatus;
import org.mariotaku.twidere.model.ParcelableUser;
import org.mariotaku.twidere.util.IntentUtils;
@ -33,6 +34,10 @@ import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
import java.util.List;
import edu.tsinghua.hotmobi.HotMobiLogger;
import edu.tsinghua.hotmobi.model.MediaEvent;
import edu.tsinghua.hotmobi.model.TimelineType;
/**
* Created by mariotaku on 16/3/20.
*/
@ -77,6 +82,19 @@ public class ItemsListFragment extends AbsContentListRecyclerViewFragment<Variou
if (view == null) return;
getRecyclerView().showContextMenuForChild(view);
}
@Override
public void onMediaClick(IStatusViewHolder holder, View view, ParcelableMedia media, int statusPosition) {
final ParcelableStatus status = dummyItemAdapter.getStatus(statusPosition);
if (status == null || media == null) return;
IntentUtils.openMedia(getActivity(), status, media, null,
mPreferences.getBoolean(KEY_NEW_DOCUMENT_API));
// BEGIN HotMobi
final MediaEvent event = MediaEvent.create(getActivity(), status, media,
TimelineType.OTHER, dummyItemAdapter.isMediaPreviewEnabled());
HotMobiLogger.getInstance(getActivity()).log(status.account_key, event);
// END HotMobi
}
});
dummyItemAdapter.setUserClickListener(new IUsersAdapter.SimpleUserClickListener() {
@Override

View File

@ -44,7 +44,7 @@ import org.mariotaku.twidere.model.util.ParcelableCredentialsUtils;
import org.mariotaku.twidere.model.util.ParcelableStatusUtils;
import org.mariotaku.twidere.util.InternalTwitterContentUtils;
import org.mariotaku.twidere.util.JsonSerializer;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
import org.mariotaku.twidere.util.TwidereArrayUtils;
import org.mariotaku.twidere.util.TwitterAPIFactory;

View File

@ -23,7 +23,7 @@ import org.mariotaku.restfu.RestFuUtils;
import org.mariotaku.twidere.TwidereConstants;
import org.mariotaku.twidere.model.CacheMetadata;
import org.mariotaku.twidere.task.SaveFileTask;
import org.mariotaku.twidere.util.LoganSquareMapperFinder;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.twidere.util.Utils;
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper;

View File

@ -788,7 +788,8 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
}
}
if (table == null) return null;
final Cursor c = mDatabaseWrapper.query(table, projection, selection, selectionArgs, null, null, sortOrder);
final Cursor c = mDatabaseWrapper.query(table, projection, selection, selectionArgs,
null, null, sortOrder);
setNotificationUri(c, Utils.getNotificationUri(tableId, uri));
return c;
} catch (final SQLException e) {

View File

@ -35,6 +35,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.library.objectcursor.ObjectCursor;
import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.annotation.Preference;

View File

@ -36,6 +36,7 @@ import android.text.TextUtils;
import com.bluelinelabs.logansquare.JsonMapper;
import org.apache.commons.lang3.ArrayUtils;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import org.mariotaku.sqliteqb.library.ArgsArray;
import org.mariotaku.sqliteqb.library.Columns;
import org.mariotaku.sqliteqb.library.Columns.Column;

View File

@ -23,6 +23,8 @@ import android.support.annotation.Nullable;
import com.bluelinelabs.logansquare.JsonMapper;
import org.mariotaku.commons.logansquare.LoganSquareMapperFinder;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

View File

@ -129,7 +129,7 @@ public class LinkCreator implements Constants {
return builder.build();
}
private static Uri getFanfouStatusLink(String id) {
static Uri getFanfouStatusLink(String id) {
Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_HTTP);
builder.authority(AUTHORITY_FANFOU);
@ -138,7 +138,7 @@ public class LinkCreator implements Constants {
return builder.build();
}
private static Uri getFanfouUserLink(String id) {
static Uri getFanfouUserLink(String id) {
Uri.Builder builder = new Uri.Builder();
builder.scheme(SCHEME_HTTP);
builder.authority(AUTHORITY_FANFOU);

View File

@ -1,5 +1,6 @@
package org.mariotaku.twidere.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@ -62,8 +63,6 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static android.text.TextUtils.isEmpty;
/**
* Created by mariotaku on 15/5/7.
*/
@ -254,7 +253,7 @@ public class TwitterAPIFactory implements TwidereConstants {
final String apiUrlFormat;
final boolean sameOAuthSigningUrl = credentials.same_oauth_signing_url;
final boolean noVersionSuffix = credentials.no_version_suffix;
if (!isEmpty(credentials.api_url_format)) {
if (!TextUtils.isEmpty(credentials.api_url_format)) {
apiUrlFormat = credentials.api_url_format;
} else {
apiUrlFormat = DEFAULT_TWITTER_API_URL_FORMAT;
@ -295,6 +294,7 @@ public class TwitterAPIFactory implements TwidereConstants {
return new Endpoint(endpointUrl);
}
@SuppressLint("SwitchIntDef")
@Nullable
public static Authorization getAuthorization(@Nullable ParcelableCredentials credentials) {
if (credentials == null) return null;
@ -316,7 +316,7 @@ public class TwitterAPIFactory implements TwidereConstants {
final String username = credentials.basic_auth_username;
final String loginName = username != null ? username : screenName;
final String password = credentials.basic_auth_password;
if (isEmpty(loginName) || isEmpty(password)) return null;
if (TextUtils.isEmpty(loginName) || TextUtils.isEmpty(password)) return null;
return new BasicAuthorization(loginName, password);
}
}
@ -471,7 +471,8 @@ public class TwitterAPIFactory implements TwidereConstants {
}
private static boolean isAsciiLetterOrDigit(int codePoint) {
return ('A' <= codePoint && codePoint <= 'Z') || ('a' <= codePoint && codePoint <= 'z') || '0' <= codePoint && codePoint <= '9';
return 'A' <= codePoint && codePoint <= 'Z' || 'a' <= codePoint && codePoint <= 'z'
|| '0' <= codePoint && codePoint <= '9';
}
@NonNull

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.7.2 (28276) - http://www.bohemiancoding.com/sketch -->
<title>Artboard</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard">
<polygon id="Shape" points="0 0 32 0 32 32 0 32"></polygon>
<path d="M16,12 C17.1,12 18,11.1 18,10 C18,8.9 17.1,8 16,8 C14.9,8 14,8.9 14,10 C14,11.1 14.9,12 16,12 L16,12 Z M16,14 C14.9,14 14,14.9 14,16 C14,17.1 14.9,18 16,18 C17.1,18 18,17.1 18,16 C18,14.9 17.1,14 16,14 L16,14 Z M16,20 C14.9,20 14,20.9 14,22 C14,23.1 14.9,24 16,24 C17.1,24 18,23.1 18,22 C18,20.9 17.1,20 16,20 L16,20 Z" id="Shape" fill="#FFFFFF"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 952 B